概述
即时通信 IM 的终端用户需要随时都能够得知最新的消息,而由于移动端设备的性能与电量有限,当 App 处于后台时,为了避免维持长连接而导致的过多资源消耗,即时通信 IM 推荐您使用 Apple 提供的系统级推送通道(APNs)来进行消息通知,APNs 相比第三方推送拥有更稳定的系统级长连接,可以做到随时接受推送消息,且资源消耗大幅降低。
注意:
在没有主动退出登录的情况下,应用退后台、手机锁屏、或者应用进程被用户主动杀掉三种场景下,如果想继续接收到 IM 消息提醒,可以接入即时通信 IM 离线推送。
如果应用主动调用 logout 退出登录,或者多端登录被踢下线,即使接入了 IM 离线推送,也收不到离线推送消息。
集成 TUIOfflinePush 跑通离线推送功能
说明:
如果您想尽可能简单地接入 TUIOfflinePush 组件,您需要使用 TUICore 组件中的 TUILogin 提供的 login/logout 接口登录/登出,此时 TUIOfflinePush 组件会自动感知登录/登出事件。如果您不想使用 TUILogin 提供的接口,可参见 TUIOfflinePush 的 高级用法-自定义登录/登出。 步骤1:集成 TUIOfflinePush 组件
1. TUIOfflinePush 组件支持 cocoapods 集成,您需要在 Podfile 中添加组件依赖。
install! 'cocoapods', :disable_input_output_paths => true
pod 'TUIOfflinePush'
2. 执行以下命令,安装 TUIOfflinePush 组件。
如果无法安装 TUIKit 最新版本,执行以下命令更新本地的 CocoaPods 仓库列表。
步骤2:配置推送参数
2. 您需要在 AppDelegate 中,调用宏 TUIOfflinePushCertificateIDForAPNS
设置下证书 ID 即可。
@implementation AppDelegate
// 配置开发环境证书
TUIOfflinePushCertificateIDForAPNS(31287)
// 配置生产环境证书
TUIOfflinePushCertificateIDForAPNS(31288)
@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
{
// 自定义解析收到的 userInfo
NSLog(@">>> 您可以在此处自定义解析, %@", userInfo);
// 如果您不想执行 TUIOfflinePush 默认的解析逻辑,直接返回 YES
// 如果您只是想查看推送的内容,依然依赖 TUIOfflinePush 的默认解析及统一跳转逻辑,直接返回 NO
return NO;
}
常见问题
普通消息为什么收不到离线推送?
首先,请检查下 App 的运行环境和证书的环境是否一致,如果不一致,收不到离线推送。
其次,检查下 App 和证书的环境是否为生产环境。如果是开发环境,向苹果申请 deviceToken
可能会失败,生产环境暂时没有发现这个问题,请切换到生产环境测试。
自定义消息为什么收不到离线推送?
如何关闭离线推送消息的接收?
如果您想关闭离线推送消息的接收,可以通过设置 setAPNS 接口的 config
参数为 nil
来实现。该功能从5.6.1200 版本开始支持。 收不到推送,且后台报错 bad devicetoken。
如果使用的是 Release 环境编译,则 - application:didRegisterForRemoteNotificationsWithDeviceToken:
回调返回的是发布环境的 token,此时 businessID 需要设置生产环境的 证书 ID。 如果使用的是 Debug 环境编译,则- application:didRegisterForRemoteNotificationsWithDeviceToken:
回调返回的是开发环境的 token,此时 businessID 需要设置开发环境的 证书 ID。 V2TIMAPNSConfig *confg = [[V2TIMAPNSConfig alloc] init];
/* 用户自己到苹果注册开发者证书,在开发者帐号中下载并生成证书(p12 文件),将生成的 p12 文件传到腾讯证书管理控制台,控制台会自动生成一个证书 ID,将证书 ID 传入以下 busiId 参数中。*/
//推送证书 ID
confg.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 系统的手机测试。
本页内容是否解决了您的问题?