差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
im:ios:apns:deploy [2019/11/22 04:34]
huanxinfudh [客户端如何申请DeviceToken]
im:ios:apns:deploy [2022/03/01 08:10] (当前版本)
jennifer.zeng [APNs推送]
行 1: 行 1:
 ====== APNs推送 ======= ====== APNs推送 =======
  
 +更新时间:2022-01-15
 +
 +新版文档见:[[ccim:​ios:​push|iOS 推送设置]]。
 ===== SDK的运行状态 ===== ===== SDK的运行状态 =====
   * 当 App 在前台可见的时候,SDK 处于前台活跃状态,此时是使用 SDK 长连接接收消息。   * 当 App 在前台可见的时候,SDK 处于前台活跃状态,此时是使用 SDK 长连接接收消息。
   ​   ​
-  * 当 App 进入后台且在2分钟之内的时候,SDK 处于后台活跃状态,此时是使用 SDK 长连接接收消息(用户根据需要实现本地通知,否则将不会有本地通知提示弹出)。+  * 当 App 进入后台,短时间内 ​SDK 处于后台活跃状态,此时是使用 SDK 长连接接收消息(用户根据需要实现本地通知,否则将不会有本地通知提示弹出)。
   ​   ​
-  * 当 App 进入后台超过2分,被系统挂起,此时 SDK 处于不活跃状态,或者是主动把App进程杀死,此时如果有新消息,是通过苹果的 APNs 服务进行提醒的。当 App 再次启动,SDK 会去服务器拉取不活跃期间的消息。+  * 当 App 进入后台被系统挂起,此时 SDK 处于不活跃状态,或者是主动把App进程杀死,此时如果有新消息,是通过苹果的 APNs 服务进行提醒的。当 App 再次启动,SDK 会去服务器拉取不活跃期间的消息。
  
 **注意:**''​由于本地通知和 APNs 不好区分,调试时建议您将 App 进程杀死,确保所有的提醒都是来自于 APNs 推送。''​ **注意:**''​由于本地通知和 APNs 不好区分,调试时建议您将 App 进程杀死,确保所有的提醒都是来自于 APNs 推送。''​
行 27: 行 30:
 首先,登录苹果的开发者中心。 首先,登录苹果的开发者中心。
 创建App 创建App
- +{{:​im:​ios:​apns:​apns_setting_1.jpg?​800|}} 
-{{:im:300iosclientintegration:apns_create1.jpg?800|}}+{{:im:ios:​apns:​apns_setting_2.jpg?​800|}} 
 +{{:​im:​ios:​apns:apns_setting_3.jpg?800|}}
  
 为App命名,此处bundle id不能用通配符,否则无法收到推送。 为App命名,此处bundle id不能用通配符,否则无法收到推送。
  
-{{:im:300iosclientintegration:apns_create2.jpg?800|}}+{{:im:ios:apns:​apns_setting_4.jpg|}}
  
 打开推送功能 打开推送功能
  
-{{:im:300iosclientintegration:apns_create3.jpg?800|}}+{{:im:ios:apns:​apns_setting_5.jpg|}}
  
-{{:im:300iosclientintegration:apns_create4.jpg?800|}}+{{:im:ios:apns:​apns_setting_6.jpg|}}
  
 创建推送证书 创建推送证书
  
-{{:im:300iosclientintegration:apns_create5.jpg?800|}}+{{:im:ios:apns:​apns_setting_7.jpg|}}
  
-如果您是测试开发环境,选择development下的Apple Push Notification service SSL(如果是生产,则需要选择Production下的)+如果您是测试开发环境,选择Services下的Apple Push Notification service SSL(Sandbox),如果是生产环境,则需要选择Services下的Apple Push Notification service SSL(Sandbox & Production)
  
-{{:im:300iosclientintegration:apns_create6.jpg?800|}}+{{:im:ios:apns:​apns_setting_8.jpg|}}
  
 选择证书所属的App 选择证书所属的App
  
-{{:im:300iosclientintegration:apns_create7.jpg?800|}}+{{:im:ios:apns:​apns_setting_9.jpg|}}
  
 上传CSR文件 上传CSR文件
  
-{{:im:300iosclientintegration:apns_create8.jpg?800|}}+{{:im:ios:apns:​apns_setting_10.jpg|}}
  
 下面,我们来创建一个CSR文件,首先,选择"​钥匙串访问"​ 下面,我们来创建一个CSR文件,首先,选择"​钥匙串访问"​
行 74: 行 78:
 点击继续,会得到一个下载页面。 点击继续,会得到一个下载页面。
  
-{{:im:300iosclientintegration:apns_create13.jpg?800|}}+{{:im:ios:apns:​apns_setting_11.jpg|}}
  
-{{:im:300iosclientintegration:apns_create14.jpg?800|}}+{{:im:ios:apns:​apns_setting_12.jpg|}}
  
 点击下载,就会下载一个aps_development.cer。(production的是aps.cer) 点击下载,就会下载一个aps_development.cer。(production的是aps.cer)
行 95: 行 99:
  
 此处需要记住密码,后面需要用到。 此处需要记住密码,后面需要用到。
 +''​注意:导出p12证书时,设置证书的密码长度不要超过20个字符,建议使用纯英文或者数字组合,不建议带特殊字符''​
  
 {{:​im:​300iosclientintegration:​apns_create19.jpg?​800|}} {{:​im:​300iosclientintegration:​apns_create19.jpg?​800|}}
行 125: 行 130:
  
 为证书起名,并记住名称,后续有用。选择上传证书,将上一步中生成的P12文件上传,并设置导出时设置的密码。选择证书类型,此处是【开发环境】(如果之前用的是production,则此处应该选择生产)。填写应用包名,应为**bundle id**,​点击上传,完成上传证书操作。 为证书起名,并记住名称,后续有用。选择上传证书,将上一步中生成的P12文件上传,并设置导出时设置的密码。选择证书类型,此处是【开发环境】(如果之前用的是production,则此处应该选择生产)。填写应用包名,应为**bundle id**,​点击上传,完成上传证书操作。
 +
 +''​注意:证书的名称和密码的长度不要超过20个字符,建议使用纯英文或者数字组合,不建议带特殊字符''​
  
 {{:​im:​ios:​apns:​ios证书.png?​nolink|}} {{:​im:​ios:​apns:​ios证书.png?​nolink|}}
行 149: 行 156:
 2、 将得到的deviceToken传到SDK 2、 将得到的deviceToken传到SDK
  
-''​如果是iOS13及以上的系统,请将SDK更新到v3.6.2及以上版本''​+''​如果是iOS13及以上的系统,请将SDK更新到v3.6.4或以上版本''​
 <​code>​ <​code>​
 // 将得到的deviceToken传给SDK // 将得到的deviceToken传给SDK
行 173: 行 180:
 </​code>​ </​code>​
  
 +
 +===== 使用在线推送通道 =====
 +
 +与APNs离线推送使用苹果厂商推送通道不同,在线推送通道使用环信长连接接收推送,之后以本地通知的形式展示推送消息,可以有效提升推送到达率。
 +集成在线推送过程如下:
 +  - 申请本地通知权限
 +  - 启用SDK在线推送
 +  - 处理Delegate
 +
 +==== 申请本地通知权限 ====
 +由于要使用本地通知展示推送消息,你需要在App中需要申请权限,过程如下:
 +<​code>​
 +    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];​
 +    [center requestAuthorizationWithOptions:​(UNAuthorizationOptionAlert + UNAuthorizationOptionSound) completionHandler:​^(BOOL granted, NSError * _Nullable error) {
 +        ​
 +    }];
 +</​code>​
 +
 +==== 启用SDK在线推送 ====
 +在启用APNs在线推送前,你需要完成IM SDK的初始化工作
 +
 +SDK初始化完成后,启用APNs在线推送过程如下:
 +<​code>​
 +    [[EMLocalNotificationManager sharedManager] launchWithDelegate:​self];​
 +</​code>​
 +
 +
 +
 +==== 处理Delegate ====
 +在启用在线通道过程中,SDK会重写**[UNUserNotificationCenter currentNotificationCenter]**的delegate,如果要处理其他本地通知,需要实现**EMLocalNotificationDelegate**,过程如下
 +<​code>​
 +#pragma mark - EMLocalNotificationDelegate
 +- (void)emuserNotificationCenter:​(UNUserNotificationCenter *)center willPresentNotification:​(UNNotification *)notification withCompletionHandler:​(void (^)(UNNotificationPresentationOptions options))completionHandler
 +{
 +    // // 这里处理其他本地通知
 +    completionHandler(UNNotificationPresentationOptionAlert);​
 +}
 +- (void)emuserNotificationCenter:​(UNUserNotificationCenter *)center didReceiveNotificationResponse:​(UNNotificationResponse *)response withCompletionHandler:​(void(^)(void))completionHandler
 +{
 +    NSDictionary* userInfo = response.notification.request.content.userInfo;​
 +    // 这里处理其他本地通知
 +    completionHandler();​
 +}
 +</​code>​
 +
 +
 +==== 进阶 ====
 +iOS的本地通知管理模块**UNUserNotificationCenter**是单例,一个App
 +中只能有一个实例,如果在启用SDK在线推送之后,App又重写了**[UNUserNotificationCenter currentNotificationCenter].delegate**,会把SDK中的delegate覆盖掉,此时需要在App实现的**UNUserNotificationCenterDelegate**中,调用SDK的相关处理,过程如下
 +<​code>​
 +#pragma mark - UNUserNotificationCenterDelegate
 +
 +- (void)userNotificationCenter:​(UNUserNotificationCenter *)center willPresentNotification:​(UNNotification *)notification withCompletionHandler:​(void (^)(UNNotificationPresentationOptions options))completionHandler
 +{
 +    // 处理其他通知
 +    ...
 +    // 调用SDK推送在线通道处理
 +    [[EMLocalNotificationManager sharedManager] userNotificationCenter:​center willPresentNotification:​notification withCompletionHandler:​completionHandler];​
 +}
 +
 +- (void)userNotificationCenter:​(UNUserNotificationCenter *)center didReceiveNotificationResponse:​(UNNotificationResponse *)response withCompletionHandler:​(void(^)(void))completionHandler
 +{
 +    ​
 +    // 处理其他通知
 +    ...
 +    // 调用SDK推送在线通道处理
 +    [[EMLocalNotificationManager sharedManager] userNotificationCenter:​center didReceiveNotificationResponse:​response withCompletionHandler:​completionHandler];​
 +}
 +</​code>​
 ===== 常见问题 ===== ===== 常见问题 =====
 ==== 如何实现本地通知 ==== ==== 如何实现本地通知 ====