APNs
APNs(Apple Push Notification service) 官方文档 Overview
推送原理
当 Provider 远程服务器需要向 App 推送一条消息时,并不是直接往 App 推送消息,而是推送苹果 APNs 服务器上,而苹果的 APNs 服务器再通过与设备建立长连接进而把消息推送到我们的设备上。
由此:APNs 推送就划分成两部分:
- Provider-to-APNs connection (服务端交互)
- APNs-to-device connection (客户端交互)
deviceToken
1、当一个 App 注册接收远程通知时,系统会发送请求到 APNs 服务器,APNs 服务器收到此请求会生成一个独一无二的 deviceToken,发送到对应请求的 App 上。然后 App 把此 deviceToken 发送给我们自己的服务器 Provider。
❗️一个 deviceToken 可以唯一标识某个设备上的某个 App,可以理解成:deviceToken = device UUID + App Bundle ID
2、Provider 给我们的设备推送通知的时候,必须包含此 deviceToken。
推送消息 Payload
1、Payload 消息大小
- For regular remote notifications, the maximum size is 4KB (4096 bytes)
- For Voice over Internet Protocol (VoIP) notifications, the maximum size is 5KB (5120 bytes)
- If you are using the legacy APNs binary interface to send notifications instead of an HTTP/2 request, the maximum payload size is 2KB (2048 bytes)
当 Payload 负载大小超过规定的负载大小时,APNs 会拒绝发送此消息。
2、Payload 消息格式
- aps:推送消息必须有的 key
- alert:推送消息包含此 key 值,系统就会根据用户的设置展示标准的推送信息
- title:简短描述此调推送消息的目的
- body:推送的内容
- badge:在 app 图标上显示消息数量,缺少此 key ,消息数量就不会改变,消除标记时把此 key 对应的 value 设置为0
- sound:设置推送声音的key值,系统默认提示声音对应的 value 值为 default
- alert:推送消息包含此 key 值,系统就会根据用户的设置展示标准的推送信息
- acme: 以
acme
作为前缀,表示自定义数据
例如:
3、当设备处于离线 offline 状态时,APNs 会为保留 Provider 所推送的最后一条通知,当设备转换为连网状态时,APNs则把其保留的最后一条通知推送给我们的设备;如果设备长时间离线,那么最后一条通知也有可能被丢弃。
总结
- ① App 向系统发起请求
- ② 系统向 APNs 发送注册远程推送请求
- ③ APNs 生成 deviceToken 并返回
- ④ App 将 deviceToken 发送给服务器 Provider
- ⑤ 从推送管理平台向 Provider 发出推送消息指令
- ⑥ Provider 推送消息给 APNs
- ⑦ APNs 推送消息给 App
安装插件
Cordova 项目要集成远程推送功能,需要用到 phonegap-plugin-push 这个插件,该插件提供了对多个平台的推送支持,当然包括 iOS 和 Android,下面以 iOS 项目为例,详细介绍整个安装过程。
iOS 安装过程:参考文档
❗️注意:
- 以下安装过程需要翻墙
- 该插件要求 cordova 版本至少 6.1.0,否则要么更新 cordova 或者下载时指定该插件版本号:1cordova plugin add phonegap-plugin-push@1.8.1
执行安装命令:
提示我们要安装 CocoaPods,执行如下命令进行安装:
根据错误提示我们知道,从淘宝 Ruby 的软件源中找不到 cocoapods,我们需要增加 gem 源
安装完 CocoaPods 之后,重新安装插件:
安装文档中也可以找到 解决这个问题 的介绍:
- 进入
platforms/ios
iOS 项目根目录,执行pod repo update
- 重新安装该插件
但是执行 pod repo update
实在是太慢了💩,不能忍。我们可以通过如下方法进行解决:
执行 pod setup
会 Specs 整个仓库 clone 到本地,这个仓库是是所有 Pods 的索引,就是一个容器,所有公开的 Pods 都在这里面。整个下载大小约 400M 所以需要点时间 🤣
下载完毕后,我们再进入 iOS 项目中执行 pod repo update
就很快了。以上操作都顺利完成后,重新安装该插件:
不出意外就安装成功了 ✌️。
总结一下其实就是两点:
sudo gem install cocoapods
pod setup
使用插件
插件在全局添加了一个 PushNotification 类。
PushNotification.init(options)
推送初始化,通过传入配置信息,包含各个平台相应的设置,返回 PushNotification
实例
❗️注意:
- 必须在
deviceready
事件回调中调用PushNotification.init()
- 每一次 App 启动,都需要调用
PushNotification.init()
,因为 App 对应的推送服务 registration ID 可能发生变化(对于 iOS 即是 deviceToken)
|
|
事件监听 push.on(event, callback)
|
|
PushNotification.hasPermission
检查 App 是否授权允许推送通知
get/setApplicationIconBadgeNumber
获取/设置应用图标标记数字
badge 自增问题 🤖
通常来说,应用在接收到一条推送消息通知的时候,图标标记 badge 就应该加一;当打开应用的时候,badge 清零。
我们知道通过设置 Payload 消息中的 badge
字段,可以设置应用接收到推送消息时,图标标记设置的数值(badge
字段为零即为清空图标标记数字);而在 PushNotification 插件初始化时通过配置传入 clearBadge
可以设置打开应用时,图标标记清零。
但是能否做到接收到推送消息时,badge 显示数值自增一呢?就目前 PushNotification 插件来说,并不能做到。而对于微信或者 QQ 这类应用的图标 badge 数值提示的是未读消息数,其设置逻辑应该是通过服务端维护的。
对于图标标记的设置,参考了一些 App 的做法:
- 设置
badge
字段为 1 - 不展示图标标记(设置
badge
字段为 0 或者 PushNotification 插件初始化是badge
设置为false
)
推送证书
具备接收远程推送的应用打包时需要使用推送证书,同样也区分开发证书和发布证书。
导出推送证书
登录 苹果开发者中心 在 Certificates, Identifiers & Profiles -> Identifiers -> App IDs
,找到应用对应的 App ID,点击 Edit
对 Push Notifications 进行配置导出 certificate 证书。
双击安装证书如下:
同时我们也需要更新下载 Provisioning Profile 文件。
Xcode 真机调试推送配置
1、target -> Capabilities
2、target -> Build Settings -> Signings