说在前面
iOS中的推送分为:Local Notification(本地消息通知)和Remote Notification(远程消息推送)。本文重点介绍一下Remote Notification,主要讲理论知识,没有具体的代码实现,望各位见谅。
Apple Push Notification Service
苹果官方的Programming Guide中是这么描述的:
Apple Push Notification service (APNs) is the centerpiece of the remote notifications feature. It is a robust and highly efficient service for propagating information to iOS (and, indirectly, watchOS), tvOS, and OS X devices. Each device establishes an accredited and encrypted IP connection with APNs and receives notifications over this persistent connection. If a notification for an app arrives when that app is not running, the device alerts the user that the app has data waiting for it.
You provide your own server to generate the remote notifications for your users. This server, known as the provider, gathers data for your users and decides when a notification needs to be sent. For each notification, the provider generates the notification payload and attaches that payload to an HTTP/2 request, which it then sends to APNs using a persistent and secure channel using the HTTP/2 multiplex protocol. Upon receipt of your request, APNs handles the delivery of your notification payload to your app on the user’s device.
For information about the format of the requests that you send to APNs, and the responses and errors you can receive, see APNs Provider API. For information about how to implement notification support in your app, see Registering, Scheduling, and Handling User Notifications.
大概的意思就是:
Apple Push Notification service
(以下简称:APNs
)即苹果推送通知服务是苹果远程通知功能的核心,支持苹果的所有的设备(包括WatchOS、TVOS、OS X)。每台设备和APNs
之间会建立一个网络长连接接收通知。无论应用程序是否正在运行,Apple设备都可以接收到通知并且对用户进行提示。
我们需要创建自己的服务器(以下称为:Provider
)在需要的时候生成远程通知。再由Provider
通过HTTP 2.0协议向APNs发送请求,APNs在接收到请求后,会对远程消息进行处理并推送到你的应用程序所在的设备。
上面这么一大段话,我们可以简单的用下图来概括:
通过上面这些内容,我们大概可以知道以下几点:
- Provider,发送远程推送的时候,首先要有一个自己的服务器,用来生成远程通知的内容并按照苹果官方的API发送远程通知请求。这个请求是通过HTTP2.0协议完成的,也就是https
- APNs,苹果的远程推送服务器,Provider发出的请求并不是直接发送到设备,而是发给APNs(强制的),然后再由 APNs 发送给应用程序所在的设备
- APNs 是通过和设备之间的一个可信任、加密、长久的网络连接将远程通知发送到设备上的
** APNs 的储存机制**
当苹果设备处于无网络连接时,远程推送消息是没有办法发送到设备的,这时APNs会把这条消息存起来,当然,只是一段时间内,并且只可以存一条,也就是说一旦你的设备无网络连接的时间过长,或者有一条新的推送消息的话,都会导致之前存的消息消失。个人认为这勉强可以算是苹果对于推送消息在网络方面小小的解决方案吧,毕竟想做到大数据量的存储不是容易的事,而且你也不想在IPhone重新连接网络的时候会有N条推送出现吧,小心脏压力不会小……
The device token
The device token 是苹果设备的唯一认证码。当你设备中的APP需要发送推送消息的时候,APNs 只能通过 device token 才能定位到你的设备。APP 在使用远程推送功能之前需要注册 device token ,通过Device 向 APNs 发送注册请求,并将从 APNs 获得的 device token 发给 Provider 进行保存,以便将来发送推送消息时, Provider 向 APNs 发送请求时使用。
注意:
- device token 是Device (也就是设备)向 APNs 注册然后分享给 APP 使用的,虽然注册的代码是写在 APP 当中,但是主角还是 Device
- device token 并不是永远不变的,当升级操作系统后会生成新的 device token ,所以我们需要在APP 启动的时就将新的 device token 发送到Provider 并进行保存,这样才能确保推送消息能够准确的发送到设备上
- device token 虽然是可修改的,但是千万不要试图修改他们,否则小心无法以正确的姿势发送推送消息啊
下面两图,分别展示了 device token 注册和远程推送过时的过程
Provider 和 APNs 之间的连接
Provider 和APNs 之间会创建一个TLS连接,Provider首先会接收到APNs发过来的服务器证书,然后把自己的证书发给APNs(也就是p12文件),APNs验证通过后,完成TLS连接创建。如果你的证书配置的不正确,也就是没有开通推送权限的话,APNs 会拒绝Provider的https请求。
Provider 除了需要向 APNs 发送证书以外,还需要发送 PayLoad (消息载体),包括了JSON字典格式的消息内容、消息展示的形式(比如:Alert)、badge 显示的消息数目以及sound提示声。
APNs 和 Device 之间的连接
每个 Device 都有自己的设备证书和私钥,在设备激活的时候存储在了 Keychain 中。Device 会启动一个 TLS 连接APNs,APNs 会把服务器证书发给 Device 进行验证,通过后 Device 会把设备证书发送给 APNs 进行验证,一旦双方都验证通过,这个连接就会创建成功,并且长时间的保持,当然,这个过程中我们是什么都不需要做的,苹果会自动帮我们完成。
注意:APNs 和 Device 的长连接优先使用的移动网络,只有已经连接wifi时才会走wifi,这也就是为什么好多人wifi上不了网,但是却能收到推送消息的原因。
总结
iOS 远程推送的相关知识大概就是这些了,总结一下有以下几点:
- 具有远程推送权限的证书,如果没有,也就不能通过APNs的验证,当然也就没有办法进行消息推送了
- 向 APNs 进行注册获得 device token,并进行存储,要保证 device token 的正确性和实时性,否则也是无法消息推送的
- Provider 向 APNs 请求时,使用的HTTP 2.0 也就是https协议,普通的 http 是会被拒绝访问的
- APNs 和 Device 之间的长连接也是 HTTP 2.0 协议,优先走的移动网络,若连 wifi 才会走 wifi 网络,所以只要保证有其中一样的网络连接是可用的,那么就可以正确的姿势收到推送消息了