前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >APNs推送

APNs推送

原创
作者头像
腾讯视频云-Zachary
修改2019-09-09 12:15:51
2.1K0
修改2019-09-09 12:15:51
举报

场景

即时通讯中需要对离线消息进行接收,此时就需要离线推送即当应用没有退出登录的情况下,被系统或者用户杀掉进程仍然能收到IMSDK消息提醒。云通讯iOS客户端采用的是APNs推送服务,以下提供整个处理流程及参考代码。

处理流程

1.申请APNs证书可参考文档:Apple 推送证书申请

2.上传证书到腾讯云控制台

注意:上传证书名最好使用全英文(尤其不能使用括号等特殊字符)。 上传证书生效时间为 10 分钟左右。 上传证书需要设置密码,无密码收不到推送。 注意生产环境的选择,发布 AppStore 的证书需要设置为生产环境,否则无法收到推送。 上传的 p12 证书必须是自己申请的真实有效的证书。

3.客户端实现APNs推送

客户端实现步骤

1. 向苹果后台请求DeviceToken
代码语言:txt
复制
//在IM登录之后注册通知
- (void)registNotification
{
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
    {
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    else
    {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
    }
}
2. 上传Token到腾讯云
代码语言:txt
复制
//在通知的回调中上传的token
-(void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    
    DebugLog(@"didRegisterForRemoteNotificationsWithDeviceToken:%ld", (unsigned long)deviceToken.length);
    NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
    [[TIMManager sharedInstance] log:TIM_LOG_INFO tag:@"SetToken" msg:[NSString svtringWithFormat:@"My Token is :%@", token]];
    TIMTokenParam *param = [[TIMTokenParam alloc] init];
    //注意区分证书环境
#if kAppStoreVersion
    // AppStore版本
#if DEBUG
    param.busiId = 2383;
#else
    param.busiId = 2382;
#endif
#else
    //企业证书id
    param.busiId = 4496;
#endif
    [param setToken:deviceToken];
    //调用IM API 上传Token到腾讯云
    [[TIMManager sharedInstance] setToken:param succ:^{
        NSLog(@"-----> 上传token成功 ");
    } fail:^(int code, NSString *msg) {
        NSLog(@"-----> 上传token失败 ");
    }];
}
3. App进入后台时上报切后台事件
代码语言:txt
复制
//App进入后台 上报事件
- (void)applicationDidEnterBackground:(UIApplication *)application {
 __block UIBackgroundTaskIdentifier bgTaskID;
 bgTaskID = [application beginBackgroundTaskWithExpirationHandler:^ {
 //不管有没有完成,结束 background_task 任务
 [application endBackgroundTask: bgTaskID];
 bgTaskID = UIBackgroundTaskInvalid;
 }];
 //获取未读计数
 int unReadCount = 0;
 NSArray *convs = [[TIMManager sharedInstance] getConversationList];
 for (TIMConversation *conv in convs) {
 if([conv getType] == TIM_SYSTEM){
 continue;
 }
 unReadCount += [conv getUnReadMessageNum];
 }
 [UIApplication sharedApplication].applicationIconBadgeNumber = unReadCount;
 //doBackground
 TIMBackgroundParam *param = [[TIMBackgroundParam alloc] init];
 [param setC2cUnread:unReadCount];
 [[TIMManager sharedInstance] doBackground:param succ:^() {
 NSLog(@"doBackgroud Succ");
 } fail:^(int code, NSString * err) {
 NSLog(@"Fail: %d->%@", code, err);
 }];
}
4. App进入前台时上报切前台事件
代码语言:txt
复制
//App进入前台
- (void)applicationDidBecomeActive:(UIApplication *)application {
 [[TIMManager sharedInstance] doForeground:^() {
 NSLog(@"doForegroud Succ");
 } fail:^(int code, NSString * err) {
 NSLog(@"Fail: %d->%@", code, err);
 }];
}
5. 离线消息处理
代码语言:txt
复制
// 处理推送消息
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
    DebugLog(@"userinfo:%@",userInfo);
    DebugLog(@"收到推送消息:%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]);
    //当APP在前台运行时,不做处理
    if( [UIApplication sharedApplication].applicationState == UIApplicationStateActive){
    
    }else if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive) {
        //当APP在后台运行时,当有通知栏消息时,点击它,就会执行下面的方法跳转到相应的页面
        if ([[TIMManager sharedInstance] getLoginStatus])
        {
            for (NSString *tfStr in userInfo)
            {
                if ([tfStr isEqualToString:@"careline"])
                {
                    //跳转到对应的页面
                    
                }
            }
        }
    }

}

推送机制

APNS推送机制
APNS推送机制

上图可以分为三个阶段:

  1. 应用程序的服务器端把要发送的消息、目的iPhone的标识打包,发给APNS。
  2. APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发送到iPhone。
  3. iPhone把发来的消息传递给相应的应用程序,并且按照设定弹出Push通知。

问题排查

  1. 确认是否正确上传证书到腾讯云控制台。
  2. 确认在登录成功后,是否成功上报token到腾讯云了,注意开发环境与发布环境的token不一样,删除app重新装也会导致token的变化。建议每次登录后都获取token。
  3. 确认是否正确上报了切前后台事件,应用进入后台上报applicationDidEnterBackground事件,进入前台上报applicationDidBecomeActive事件。
  4. 确认TIMCustomElem消息中的desc属性是否是空的,如果desc为空消息将发送不出。
  5. MsgRandom 等去重标记设为一样,导致被去重无法推送。
  6. 对于群消息,确认群消息接收选项是否为接收群消息提醒。
代码语言:txt
复制
//设置群接收选项
[[TIMGroupManager sharedInstance] ModifyReciveMessageOpt:@"TGID1JYSZEAEQ" opt:TIM_GROUP_RECEIVE_MESSAGE succ:^() {
    NSLog(@"modify receive group message option succ");
}fail:^(int code, NSString* err) {
    NSLog(@"failed code: %d %@", code, err);
}];

7.对于更换证书的情况下新证书得在上传一个小时后生效

8.以上排查不出问题可提供sdkappid、证书id、发送接收双方的账号给技术人员排查

参考文档:

  1. https://segmentfault.com/a/1190000012019282
  2. https://blog.csdn.net/csdn100861/article/details/51508885

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 场景
  • 处理流程
  • 客户端实现步骤
    • 1. 向苹果后台请求DeviceToken
      • 2. 上传Token到腾讯云
        • 3. App进入后台时上报切后台事件
          • 4. App进入前台时上报切前台事件
            • 5. 离线消息处理
            • 推送机制
            • 问题排查
            相关产品与服务
            即时通信 IM
            即时通信 IM(Instant Messaging)基于腾讯二十余年的 IM 技术积累,支持Android、iOS、Mac、Windows、Web、H5、小程序平台且跨终端互通,低代码 UI 组件助您30分钟集成单聊、群聊、关系链、消息漫游、群组管理、资料管理、直播弹幕和内容审核等能力。适用于直播互动、电商带货、客服咨询、社交沟通、在线课程、企业办公、互动游戏、医疗健康等场景。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档