天天看点

苹果远程推送通知 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。

准备步骤