iOS 17+非上架iMessage扩展后台发送定时SMS问题求助
iOS后台发送定时SMS方案分析(非App Store提交场景)
核心结论
对于非App Store的越狱/企业签名场景,iOS支持后台线程发送SMS,但需依赖私有API,且不同iOS版本兼容性差异极大;官方公开API(如MFMessageComposeViewController)仅支持前台交互发送,无法实现后台静默执行。
你的CTMessageCenter调用问题排查
你通过NSInvocation调用私有API失败,大概率是以下原因导致:
- 方法签名/参数不匹配
不同iOS版本中CTMessageCenter的方法签名可能变更:部分版本的发送方法是简化版sendSMSWithText:toAddress:,而非你使用的sendSMSWithText:serviceCenter:toAddress:;且serviceCenter参数直接传nil可能不合法,部分版本需要传入有效的服务中心号码(可通过CTMessageCenter的defaultServiceCenter方法获取)。 - 权限缺失
调用私有SMS发送API需要应用拥有com.apple.coretelephony.sms.send权限,需在Entitlements.plist中添加该权限并重新签名。 - 线程限制
部分私有API要求必须在主线程执行,后台线程调用会直接失败,需切换到主线程执行发送逻辑。
修正后的调用示例
void sendSMS(NSObject* receiver, NSString* message, NSString* phoneNumber) { // 先尝试简化版方法,适配不同iOS版本 SEL selector = @selector(sendSMSWithText:toAddress:); NSMethodSignature* signature = [receiver methodSignatureForSelector:selector]; // 简化版不存在则 fallback 到带serviceCenter的版本 if (!signature) { selector = @selector(sendSMSWithText:serviceCenter:toAddress:); signature = [receiver methodSignatureForSelector:selector]; } NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature]; [invocation setTarget:receiver]; [invocation setSelector:selector]; [invocation setArgument:&message atIndex:2]; if (signature.numberOfArguments == 4) { // 处理带serviceCenter参数的版本 NSString* serviceCenter = [receiver performSelector:@selector(defaultServiceCenter)]; [invocation setArgument:&serviceCenter atIndex:3]; [invocation setArgument:&phoneNumber atIndex:4]; } else { // 处理简化版方法 [invocation setArgument:&phoneNumber atIndex:3]; } // 切换到主线程执行发送逻辑 dispatch_async(dispatch_get_main_queue(), ^{ printf("Before.\n"); [invocation invoke]; printf("After.\n"); }); }
ChatKit框架方案说明
ChatKit的部分发送API确实仅能在MobileSMS进程内调用,如果你开发的是iMessage扩展,可尝试注入到MobileSMS进程中使用:
- 获取目标联系人对应的
CKConversation实例 - 调用
sendMessage:方法发送文本消息
但此方案仅适用于越狱环境下的进程注入,且iOS 10+后ChatKit的API变更频繁,兼容性极差。
其他可行方案
- 使用封装好的私有库:越狱社区维护的
libSMS.dylib封装了CTMessageCenter和ChatKit的API,兼容性比直接调用原生私有API更好,可直接调用sms_send函数发送SMS。 - 后台定时触发:结合
UNNotificationRequest(非越狱环境)或launchd定时任务(越狱环境)触发发送逻辑,注意非越狱环境下后台任务最多存活几分钟,越狱环境可突破该限制。
开源项目参考
- SMSLib:越狱社区维护的开源SMS发送库,封装了多版本iOS的私有发送API,适配性强。
- iMessageBot:针对iMessage扩展的开源项目,包含后台消息发送逻辑,可参考其私有API调用方式。
内容的提问来源于stack exchange,提问作者Prowtons McBishop
相关产品推荐
相关产品推荐

