iOS
概述
即时通信 IM 的终端用户需要随时都能够得知最新的消息,而由于移动端设备的性能与电量有限,当 App 处于后台时,为了避免维持长连接而导致的过多资源消耗,即时通信 IM 推荐您使用 Apple 提供的系统级推送通道(APNs)来进行消息通知,APNs 相比第三方推送拥有更稳定的系统级长连接,可以做到随时接受推送消息,且资源消耗大幅降低。
注意:
在没有主动退出登录的情况下,应用退后台、手机锁屏、或者应用进程被用户主动杀掉三种场景下,如果想继续接收到 IM 消息提醒,可以接入即时通信 IM 离线推送。
如果应用主动调用 logout 退出登录,或者多端登录被踢下线,即使接入了 IM 离线推送,也收不到离线推送消息。
集成 TUIOfflinePush 跑通离线推送功能
2. 配置推送参数
3. 点击离线推送后自定义跳转
说明:
如果您想尽可能简单地接入 TUIOfflinePush 组件,您需要使用 TUICore 组件中的 TUILogin 提供的 login/logout 接口登录/登出,此时 TUIOfflinePush 组件会自动感知登录/登出事件。如果您不想使用 TUILogin 提供的接口,可参见 TUIOfflinePush 的 高级用法-自定义登录/登出。
步骤1:集成 TUIOfflinePush 组件
1. TUIOfflinePush 组件支持 cocoapods 集成,您需要在 Podfile 中添加组件依赖。
# 防止 TUI 组件里的 *.xcassets 与您项目里面冲突。install! 'cocoapods', :disable_input_output_paths => true# TUI 组件依赖了静态库,需要屏蔽如下设置,如果报错,请参见常见问题说明。# use_frameworks!# 集成离线推送组件pod 'TUIOfflinePush'
2. 执行以下命令,安装 TUIOfflinePush 组件。
pod install
如果无法安装 TUIKit 最新版本,执行以下命令更新本地的 CocoaPods 仓库列表。
pod repo update
步骤2:配置推送参数
1. 当您 上传证书到 IM 控制台 后,IM 控制台会为您分配一个证书 ID 。
2. 您需要在 AppDelegate 中,调用宏
TUIOfflinePushCertificateIDForAPNS
设置下证书 ID 即可。@implementation AppDelegate#ifdef DEBUG// 配置开发环境证书TUIOfflinePushCertificateIDForAPNS(31287)#else// 配置生产环境证书TUIOfflinePushCertificateIDForAPNS(31288)#endif@end
说明:
TUIOfflinePushCertificateIDForAPNS
是组件内置的宏定义,您只需要在 AppDelegate
的 @implementation
中的任意位置中调用即可。步骤3:点击离线推送后自定义跳转
1. 点击通知栏的离线推送后,TUIOfflinePush 组件已支持推送内容的解析。
2. 如果要实现跳转到聊天列表,您只需要在 AppDelegate 中实现
-navigateToTUIChatViewController:groupID:
跳转方法即可。说明:
TUIOfflinePush 组件默认已经从离线推送中解析出当前推送的 userID 和 groupID。
如果 groupID 不为空,说明当前点击的是群聊离线消息。
如果 groupID 为空且 userID 不为空,说明当前点击的是单聊离线消息。
您需要在 AppDelegate 的 @implementation 中实现
- navigateToTUIChatViewController:groupID:
方法。以下是示例代码,当点击离线推送后先获取当前的会话页面,然后通过会话页面 push 到聊天页面。您可以按需实现自己的跳转逻辑。
// 统一点击跳转// 您可以直接拷贝当前的方法名到您的 AppDelegate 中- (void)navigateToTUIChatViewController:(NSString *)userID groupID:(NSString *)groupID{// 示例: 点击推送通知后,首先跳转到会话列表页面,然后再会话列表页跳转到聊天页面// 1. 获取当前 app 的 tabBarController// 2. 获取 tabBarController 的 firstObject,也即 ConversationController// 3. 执行 pushToViewController: 跳转到 ChatViewController// 跳转到聊天页面后,支持点击左上角的返回按钮回退到主页面UITabBarController *tab = [self getMainController];if (![tab isKindOfClass: UITabBarController.class]) {// 正在登录中return;}if (tab.selectedIndex != 0) {[tab setSelectedIndex:0];}self.window.rootViewController = tab;UINavigationController *nav = (UINavigationController *)tab.selectedViewController;if (![nav isKindOfClass:UINavigationController.class]) {return;}UIViewController *vc = nav.viewControllers.firstObject;if (![vc isKindOfClass:NSClassFromString(@"ConversationController")]) {return;}if ([vc respondsToSelector:NSSelectorFromString(@"pushToChatViewController:userID:")]) {[vc performSelector:NSSelectorFromString(@"pushToChatViewController:userID:") withObject:groupID withObject:userID];}}
高级用法
1. 自定义登录/登出
TUIOfflinePush 默认使用了 TUICore 组件中的 TUILogin 提供的 login/logout 接口。如果您想自己实现 App/IM 的登录,不依赖 TUILogin,您需要在完成登录/登出操作后,手动调用
registerService
和 unregisterService
接口。 说明:
如果您使用了 TUILogin 的登录/登出,无需再调用上述两个接口。
// 您登录完成后的回调- (void)onLoginSuccess{// 调用 TUIOfflinePush 组件的登录[TUIOfflinePushManager.shareManager registerService];}// 您登出成功后的回调- (void)onLogoutSuccess{// 调用 TUIOfflinePush 的登出[TUIOfflinePushManager.shareManager unregisterService];}
2. 自定义离线内容解析
TUIOfflinePush 默认参与解析了离线推送的内容,并通过
- navigateToTUIChatViewController:groupID:
接口回调给业务层自定义跳转。如果您想自定义解析离线推送的内容,或者查看收到的离线推送,可以在您的 AppDelegate 中实现
- processTUIOfflinePushNotification:
方法。说明:
关于方法的返回值
如果返回 YES,那么组件将不再执行默认解析逻辑,完全交由业务层自行处理。
如果返回 NO,组件会继续执行默认解析逻辑,继续回调 - navigateToTUIChatViewController:groupID: 方法。
// 统一收到离线推送- (BOOL)processTUIOfflinePushNotification:(NSDictionary *)userInfo{// 自定义解析收到的 userInfoNSLog(@">>> 您可以在此处自定义解析, %@", userInfo);// 如果您不想执行 TUIOfflinePush 默认的解析逻辑,直接返回 YES// 如果您只是想查看推送的内容,依然依赖 TUIOfflinePush 的默认解析及统一跳转逻辑,直接返回 NOreturn NO;}
常见问题
普通消息为什么收不到离线推送?
首先,请检查下 App 的运行环境和证书的环境是否一致,如果不一致,收不到离线推送。
其次,检查下 App 和证书的环境是否为生产环境。如果是开发环境,向苹果申请
deviceToken
可能会失败,生产环境暂时没有发现这个问题,请切换到生产环境测试。自定义消息为什么收不到离线推送?
自定义消息的离线推送和普通消息不太一样,自定义消息的内容我们无法解析,不能确定推送的内容,所以默认不推送,如果您有推送需求,需要您在 sendMessage 的时候设置 offlinePushInfo 的
desc
字段,推送的时候会默认展示 desc
信息。如何关闭离线推送消息的接收?
收不到推送,且后台报错 bad devicetoken。
如果使用的是 Release 环境编译,则
- application:didRegisterForRemoteNotificationsWithDeviceToken:
回调返回的是发布环境的 token,此时 businessID 需要设置生产环境的 证书 ID。如果使用的是 Debug 环境编译,则
- application:didRegisterForRemoteNotificationsWithDeviceToken:
回调返回的是开发环境的 token,此时 businessID 需要设置开发环境的 证书 ID。V2TIMAPNSConfig *confg = [[V2TIMAPNSConfig alloc] init];/* 用户自己到苹果注册开发者证书,在开发者帐号中下载并生成证书(p12 文件),将生成的 p12 文件传到腾讯证书管理控制台,控制台会自动生成一个证书 ID,将证书 ID 传入以下 busiId 参数中。*///推送证书 IDconfg.businessID = sdkBusiId;confg.token = self.deviceToken;[[V2TIMManager sharedInstance] setAPNS:confg succ:^{NSLog(@"%s, succ, %@", __func__, supportTPNS ? @"TPNS": @"APNS");} fail:^(int code, NSString *msg) {NSLog(@"%s, fail, %d, %@", __func__, code, msg);}];
iOS 开发环境下,注册偶现不返回 deviceToken 或提示 APNs 请求 token 失败?
此问题现象是由于 APNs 服务不稳定导致的,可尝试通过以下方式解决:
1. 给手机插入 SIM 卡后使用4G网络测试。
2. 卸载重装、重启 App、关机重启后测试。
3. 打生产环境的包测试。
4. 更换其它 iOS 系统的手机测试。