【融云分析】苹果 iOS 通知推送机制全面解析

【融云分析】苹果 iOS 通知推送机制全面解析

在当下的 App 开发中,通知功能已成为不可或缺的一部分,目前主要分为两种模式:本地通知和远程推送。本文将围绕这两种模式,为开发者们详细介绍下 iOS 通知推送机制。

本地通知

一、本地通知介绍

指定推送时间,该时间在手机上弹出推送通知,不需要网络连接,例如日历、待办、闹钟等应用。

更多详情请点击 ☞ Scheduling and Handling Local Notifications 

二、本地通知使用

1. 在代码中注册本地通知

如果是 iOS 7 及之前的设备,不需要开发者添加代码即可使用(用户需要打开 App 通知)。 

如果是 iOS 8 – iOS 10 之间的设备,直接用下方代码(通过注册本地通知)注册即可。 

如果是 iOS 10 以上的设备,需要在 Appdelegate 中导入 #import <UserNotifications/UserNotifications.h>,并遵循 UNUserNotificationCenterDelegate(在 iOS 10 中,苹果针对远程推送和本地通知推出了全新的 UserNotifications 框架),如下:

2. 发送本地通知

3. 取消本地通知

4. 处理收到的本地通知

4.1 应用处于前台运行状态

4.2 应用处于后台活跃状态

4.3 应用处于后台暂停或者被杀死状态

远程推送

一、远程推送介绍

更多详情请点击 ☞ APNs Overview

Provider:App Server

APNs:Apple Push Notification Service

远程推送工作流程

二、远程推送类型

1. 普通推送

服务端通过 APNs 推送到手机的一种消息通知,包括:声音、横幅、角标和自定义字段。

通知内容格式如下:

2. VoIP 推送

更多详情请点击 ☞ Voice Over IP (VoIP) Best Practices 

iOS 8 之后推出,依赖 PushKit.framework,主要用于音视频通话时响铃,VoIP 推送可以在应用被杀死的情况下唤醒 App。

使用时需要在 Signing & Capabilities 的 Background Modes 中打开 VoIP、Background fetch 和 Remote notification,并添加 PushKit.framework。

从 iOS 13 开始苹果为防止 VoIP 推送被非来电功能滥用,禁止在非来电功能中使用 VoIP 推送,如果使用 VoIP 推送只能使用 iOS 系统的 CallKit.framework 库,如果不使用 iOS 系统的 CallKit.framework 库,App 在收到 VoIP 推送后会被杀掉,表现上就类似于没有收到 VoIP 推送;由于苹果限制中国区域使用 iOS 系统的 CallKit.framework 库,导致 VoIP 推送功能也无法在苹果商店审核通过,可以将 VoIP 推送转成 APNs 解决,融云 iOS 13 以上 VoIP 功能适配

3. 静默推送

iOS 7 版本之后推出的一种特殊远程推送,又称为后台远程推送。这一推送的特征是收到通知时没有弹窗、横幅和声音,这时不用点开通知,不用打开 App 就会执行下面的方法:

注:1. 需要开启 Remote notifications 和 开启远程推送功能 

2. 静默推送的字段中不允许携带 alert、badge 和 sound 等字段,必须包含 content-available。

三、iOS 远程推送配置

1. 申请证书及配置文件

1.1 创建 App ID

1.1.1 登录 Apple Developer,进入 Identifiers,点击“+”按钮。

1.1.2 创建 App ID(如果 App ID 已经存在可以直接跳过此步骤)

注: App 的 BundleID 不能使用通配符,否则将无法使用远程推送服务。

1.1.3 开启远程推送服务

1.2 创建推送证书

1.2.1 创建 Push 证书

1.2.2 选择新建的证书类型(开发或者生产)

注:从 iOS 9.2 开始,Apple Developer 上生成的生产环境推送证书,名称为 Apple Push Services: XXX, 之前生成的生产环境推送证书名称为 Apple Production IOS Push Services: XXX。

1.2.3 选择要开启远程推送的 App ID,点击 Continue 后会提示需要一个 CSR 文件,CSR 文件需要参考 1.2.4 生成

1.2.4 生成 CSR 文件,用于上传

•打开 Mac 系统自带的钥匙串访问;

•从证书颁发机构请求证书;

•将请求的 CSR 保存到磁盘。

1.2.5 上传 Certificate Signing Request(CSR) 文件

将 1.2.4 中生成的 .certSigningRequest 文件上传,点击 Continue 即可生成推送证书。

1.2.6 下载生成的推送证书,并导出 .p12 文件

双击下载的推送证书,系统会将其导入钥匙串中。打开钥匙串访问,选中对应的证书,右键选择导出。保存 .p12 文件时,可以为其设置密码,也可以不设置密码。

注意右键选择导出的时候不要打开证书,直接在证书上点击右键即可。

1.3 创建配置文件

1.3.1 创建 Profiles

1.3.2 选择对应环境

1.3.3 为配置文件关联 App ID

1.3.4 选择开发者证书

1.3.5 选择要安装的设备

1.3.5 填写 Profile Name

1.3.6 下载后双击,即添加到 Xcode 中

2. 代码处理

2.1 在代码中注册远程推送

如果是 iOS 10 以上的设备,需要在 Appdelegate 中导入 #import <UserNotifications/UserNotifications.h>,并遵循 UNUserNotificationCenterDelegate(在 iOS 10 中,苹果针对远程推送和本地通知推出了全新的 UserNotifications 框架),如下:

#if __IPHONE_10_0

#import <UserNotifications/UserNotifications.h>

#endif

注册远程推送相关代码:

2.2. 处理 deviceToken

如果处理 deviceToken 的方法是通过去掉 [deviceToken description] 的 “<“、”>” 和 “空格” 的话,iOS 13 之前的设备可以获取到正确的 deviceToken,但是在 iOS 13 之后就无法获取正确的 deviceToken;因为 iOS 13 之后通过 [deviceToken description] 获取到的字符串变成了下面这样的格式:

现在应该采用的获取 deviceToken 的方法:

3. 处理收到的远程推送

3.1 应用处于前台运行状态

App 前台可见时,处于前台状态。

3.1.1 收到远程推送会回调下面的方法

3.1.2 点击远程推送会回调下面的方法

3.2 应用处于后台活跃状态

当 App 进入后台未被系统回收时,处于后台活跃状态。

3.2.1 点击弹窗会启动应用并回调下面的方法

3.3 应用处于后台暂停或者被杀死状态

当 App 进入后台被系统回收或者被杀进程,处于后台暂停状态。

四、iOS 远程推送扩展

1. 修改通知内容

利用 iOS 10 新增的 Notification Service Extension 可以修改收到的远程推送内容。

注意:

1.1 只在 iOS 10 以上有效;

1.2 后台推送过来的数据要协商好格式;

1.3 Targets 中的 Service Extension 的系统版本需要修改为 10.0,如果版本高于测试设备的系统版本,则不会走对应的方法。

具体步骤如下:

•给工程添加一个 target :Notification Service Extension。

•主工程开启 Push Notifications 和 Background Modes 功能。

•Service Extension target 开启 Push Notifications 功能。

•NotificationService.m 中实现 – (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler :

场景一:修改收到的远程推送

场景二:撤回已经展示过的通知

撤回消息的推送内容示例:

其中通过 aps 中的 category 判断是不是撤回消息,如果是撤回消息,appData 中的 rc-dlt-identifier 表示要撤回消息的 ID 。

2. 自定义展示通知

利用 iOS 10 新增的 Notification Content Extension 可以自定义展示通知,

Notification Content Extension 是 iOS 10 新增的通知扩展。

具体步骤如下:

•给工程添加一个 target :Notification Content Extension;

•修改新建的 target 的 plist 文件:将 UNNotificationExtensionCategory 的 value 修改成需要修改样式的标识符(默认的标识符是 myNotificationCategory),这里也可以是数组;

•收到远程推送后下拉时才会走 – (void)didReceiveNotification:(UNNotification *)notification 方法;

•Targets 中对应 Notification Content Extension 的系统版本修改为 10.0。

示例代码:

3. 通知分组

iOS 12 之后同类型的通知会被合并成一个组,目前的分组方式有自动分组(Automatic grouping)和线程标识(Thread identifier)。

•自动分组(按应用分组):不设置 thread-id 系统会根据 App Bundle ID 进行分组;

•线程标识(自定义分组):如果想实现 App 的通知再次分组,则需要推送时设置 thread-id,系统会根据 thread-id 进一步分组。

总结

以上就是 iOS 本地通知和远程推送的使用介绍,总而言之,iOS 10 之后的通知使用了全新的 UserNotifications 框架,通知内容更加多样化,接口更加统一、易用,并且可以针对收到的推送进行内容扩展和 UI 扩展,进一步提升开发者效率和用户体验。

最新活动推荐:

       

标签: , ,