苹果远程推送通知 APNs 详解,官方,iOS | Swift | UNNotification

本文是翻译的 APNs 的官方说明

自己英文不是太好,花了不少时间来翻译,其实之前我是看不进去的。后来发现,只要你一点一点的看,总是能看进去的。

APNs 概述

APNs (Apple Push Ontification service) 服务是远程通知的核心。该服务健全、安全、高效,开发者可以方便的向 iOS tvOS macOS 终端设备推送通知。

当应用在用户设备上运行的时候会在用户设备和 APNs 之间建立一个安全的数据交互连接。应用通过该连接接收通知。在下面的一节中说明

另一半的连接是发送通知的连接,是在你的服务器与 APNs 之间的固定连接,需要在你的开发者帐户中用苹果提供的加密证书配置。本质上讲,信息提供者是一个服务器,是由你配置及部署的,需要你来写服务端的功能。下图显示远程通知的传递过程:

苹果远程推送通知 APNs 详解,官方,iOS | Swift | UNNotification

当服务器和手机应用中都配置好了之后,此时服务器可以向 APNs 发送推送请求。APNs 接收并向每个目标设置发送对应的通知信息。在终端设备(iOS macOS tvOS)接收到通知之后,系统把信息传递能你的应用,并管理用户与通知的交互。

如果设备接收到通知的时候,你的应用没有处于运行状态,系统还是能正常的显示通知。
如果 APNs 发送通知的时候,终端设备关机了,APNs 会保留通知信息,并在一段时间之后重试。

服务器的职责

你的服务器在跟 APNs 沟通连接的时候具有以下责任:

  • 通过 APNs 接收关于你的app的全球唯一的设备验证码,及其它一些数据

  • 根据app功能的需要,决定通知推送的时间

  • 建立通知请求,并发送通知请求到 APNs, APNs 再将通知递送到相应的设备

对于每一个通知请求,服务器需要做的:

  1. 组建一个 JSON 数据,其中包含通知的信息 具体看下一章节

  2. 添加 device token和通知信息到一个 HTTP/2 请求中。关于 device token 关于 HTTP/2 参数及回执信息

  3. 通过一个永久安全的线路 (Security Architecture,发送包含证书的 HTTP/2 请求到 APNs

对于使用多个服务器的

工作图示如下图
多个服务器的时候,每个服务器都需要通过证书或token 连接到 APNs,然后任意一个取得 device token 的服务器就可以发送通知了。

苹果远程推送通知 APNs 详解,官方,iOS | Swift | UNNotification

服务质量,存储并发送,联合通知

APNs 的服务质量组件可以实现存储然后发送的功能。当 APNs 发送通知到一个离线设备时,APNs 会把通知存储起来(一定的时间内),当设备上线时再递送给设备。这个存储功能只存储一个设备的一个app的最近的通知。如果设备离线中,发送一个到该设备的通知会消除前面存储的通知。如果设备处于离线太久,所有存储的发往该设备的通知都将被消除。

当发送通知的时候在头部添加合并id,可以使发送的通知合并起来。当 apns-collapse-id 添加到你发送的 HTTP/2 通知请求中时,APNs 合并apns-collapse-id值相同的通知。关于更多apns-collapse-id的知识,点此查看

安全结构

APNs 采用双层信任机制:连接信任device token 信任

连接信任工作在服务器与 APNs 之间 | APNs 与设备之间

服务器与APNs之间的信任确保服务器与 APNs 之间的连接是安全的,你需要根据本节中提到的信息,按步骤确保服务器与 APNs 之间的安全连接
APNs与设备之间的信任确保只有验证的设备才能连接 APNs 收到通知,APNs 自动确保与设备之间的连接是安全正确的。

服务器与 APNs 通信的时候,必须实现 验证证书(基于token的验证)或者 SSL 证书(基于证书的验证)。你在[开发者帐户][]中需要实现这两种验证方式的任意一种,帮助在这。可以查看这里服务器与apns连接信任来确定你需要选择哪种验证方式。

device token 信任

device token 可以确保通知只在确定的服务器与终端设备之间传送。

device token 是一个不透明的 NSData,包含一个设备上的一个应用的唯一标识。只有 APNs 能解密并查看 device token 中的内容。每个应用在向 APNs 发送远程推送注册请求的时候都会收到自己的 唯一的 device token,然后必须把 device token 转发给你app的服务器(详见 配置推送支持)。服务器在发送通知到相应的设备时,必须包含对应的 device token。APNs 通过 device token 来确保通知发送到对应设备的对应app中。

APNs 发行新 device token 的原因有:

  • 用户安装你的app到新设备上

  • 用户通过备份恢复设备

  • 用户重装系统后

  • 其它系统层面的事件

所以,app在启动的时候必须请求 device token,参阅 APNs 到设备之间的连接信任 和 device token,看代码实例详见 推送注册请求

注意:为了保护用户隐私,不要用 device token 来标识用户

服务器与 APNs 之间的信任

服务器与APNs之间有两种方式实现连接信任

基于 Token 的服务器与 APNs 之间的信任 服务器可以根据 基于HTTP/2 的API 用JSON web tokens (JWT) 来实现与 APNs 之间的连接信任。这这个模式下,你需要提供一个公共密钥给 Apple。服务器需要用该密钥来生成并添加到 JWT 服务器验证 token。 服务器发出的每个推送请求必须包含该 token。

你就能用简单的基于token的连接,来实现在你开发者帐户中的所有应用的推送请求。

服务器向 APNs 发出的每个推送请求,都会收到 APNs 的 HTTP/2 反馈。

基于证书的服务器与 APNs 之间的信任 服务器也可以通过唯一的证书来实现连接信任。服务器证书可以从开发者帐户中获取到,基于你 app 的唯一的证书。然后就可以使用证书来实现推送请求了。

重要
为实现与 APNs 之间基于 HTTP/2的 SSL 连接,你的服务器中必须包含 GeoTrust Gloabl CA 作为根证书。如果你的服务器运行的是 macOS,这个根证书在 keychain 中。其它系统的服务器则就个人情况来安装。你可以从 GeoTrust Root Certificates 网站下载,也可以点这里直接下载证书。

基于 Token 的服务器与 APNs 之间的信任

Apple Push Notification Authentication Key (Sandbox & Production)
你需要在你的[开发者帐户][]中进行配置,具体操作看 生成唯一的服务器Token
这个证书有以下特性:

  • 一个证书可以用于向所有包含在帐户下的 app 发送推送。同样可用于 voiceover-Internet Protocol(VoIP)。即使在你的app处于后台运行时,APNs 也会向app发送这个证书。详情参见APNs 服务器证书,在开发中的能耗指导查看关于Voice Over IP(VoIP)最好的应用的说明

  • 发送推送请求时,必须在基于 JWT 连接中包含该证书

  • 认证证书永不失效,但你可以随时通过[开发者帐户][]重新获取,重新获取后旧的证书将不能再使用

下图为: 用 HTTP/2 在服务器与 APNs 之间建立信任连接,用 JWT 向 APNs 发送推送请求

苹果远程推送通知 APNs 详解,官方,iOS | Swift | UNNotification

如图所示,工作流程是这样的:

  1. 服务器向 APNs 请求基于 TLS(transport layer security)的安全连接请求

  2. APNs 向服务器发送认证证书,到这里,服务器与 APNs 之间的连接已经建立,此时可以发送推送请求

  3. 服务器需要发送的每个推送请求必须包含 JWT 认证 token

  4. APNs 向服务器发送 HTTP/2 回执 参见HTTP/2

基于证书的服务器与 APNs 之间的信任

基于证书的服务器连接只支持特定的某一个应用。证书需要在你的服务器上根据你的应用 bundle 提前生成,具体参见 生成一个唯一的通往APNs 的 SSL 连接证书。根据你生成的证书的不同,信任的连接也可以推送一些与你app相关的一些东西,如 apple watch 的并发和 VoIP (voice-over-Internet Protocol)。APNs 会传送推送这些,即使设备仅在后台运行。查阅与 APNs 沟通来获取更多知识,在开发中的能耗指导查看关于Voice Over IP(VoIP)最好的应用的说明。

在基于证书的信任连接中,APNs 会持有一个废止的证书列表,如果服务器的证书在这个列表中,APNs 会废止与服务器的信任连接(也就是说 APNs 会拒绝服务器的请求)

苹果远程推送通知 APNs 详解,官方,iOS | Swift | UNNotification

该连接方式的过程是这样的:

  1. 服务器向 APNs 发出 TLS 连接请求

  2. APNs 把证书发给服务器

  3. 服务器需要把你之前从[开发者帐户][]中生成的证书发给 APNs,具体参见生成一个唯一的通往APNs 的 SSL 连接证书

  4. APNs 验证服务器提供的证书是否正确,如果正确,则确定服务器与 APNs 的信任连接。此时服务器可以向 APNs 发送推送请求了。

APNs 与设备之间的连接与 Device Tokens

APNs 与每个设备之间的连接是自动建立的,这个过程中,不需要你的 app 做什么。

每个设备都有一个加密的证书和私有密钥,在设备激活的时候生成,并保存在设备的 keychain 中,在设备激活的时候,APNs 根据设备的证书和密钥验证并授权与设备之间的连接。

苹果远程推送通知 APNs 详解,官方,iOS | Swift | UNNotification
过程是这样的:

  1. 设备向 APNs 发送 TLS 连接请求,信任连接设置开始

  2. APNs 回执 APNs 证书到设备上

  3. 设备操作系统验证接收到的 APNs 证书,并向 APNs 发送自己的设备证书

  4. APNs 验证设备发来证书,如果正确,信任连接建立

当设备与 APNs 之间的信任连接建立之后,此时设备可以向 APNs 申请特定 app 的 device-token,具体参阅 配置远程推送支持注册接收远程推送章节。

在收到 device token 之后,app 必须向其服务器发送接收到的 device token。因为服务器之后向 APNs 发送推送请求时需要用到 device token,代码请参阅 配置远程推送支持

设备激活申请 device token,和 APNs 新生成一个 device token 的过程是一样的,如图:

苹果远程推送通知 APNs 详解,官方,iOS | Swift | UNNotification

过程:

  1. app 向 APNs 申请远程推送请求,如果设备已经注册了远程推送请求,并且特定 app 的 device token 并没有变化,则 APNs 会返回已经存在的 device token 到设备上,跳转到步骤4

  2. 当一个新的设备需要注册推送请求时,APNs 根据接收到的设备证书来生成一个 device token,并回执给设备

  3. 设备系统把接收到的 device token 传给 app 并调用 AppDelegate 方法 application:didRegisterForRemoteNotificationWithDeviceToken:

  4. 设备接收到 device token 之后,需要把它按二进制或十六进制的格式发给你的服务器,服务器才能用该 device token 来发送推送请求

重要
APNs 提供的 device token 的长度不定,不要强行解码其大小

当服务器向 APNs 发送推送请求时,请求中包含中标识唯一设备唯一 app 的 device token,这个过程就是下图中 Token, Payload 过程。APNs 解密 device token 确保推送请求的目标。如果请求的发送者和接收者都合法,APNs 向设备发送请求的推送信息。

苹果远程推送通知 APNs 详解,官方,iOS | Swift | UNNotification

在设备接收到 APNs 发来的推送之后,操作系统会把通知递送给相应的 app。

准备步骤

APNs 可用于发布在 iOS 应用商店,tvOS 应用商店, macOS 应用商店中的应用,和企业应用。
你的 app 需要编写支持推送的功能。如果你是以团队合作的形式开发,那么大多数配置的过程都由管理来实现。因为需要用到开发者帐户。

想查看更多关于如何配置推送的知识,参阅 配置远程推送通知

相关推荐