目录
一、简介
二、APNs推送流程
三、什么是deviceToken
四、消息体
五、APNs推送中的问题
APNs 简介
Apple Push Notification service (APNs),即苹果推送通知服务。
为什么会有 APNs ?
由于移动设备内存、CPU、电量的局限性,iOS 不允许 APP 的进程常驻后台(事实上可以申请后台运行一段时间,最长约10分钟)。
当用户主动杀掉APP或者APP进入后台超过限定时长时,就意味着该APP进程的结束。这很大程度保障了前台APP的流畅性,也延长了手机的使用时长。这也是苹果用户体验好的原因之一。但是这也意味着,服务器无法主动和用户交互(如推送实时消息等)。为了解决这个限制,苹果推出了APNs,允许设备和服务器分别与苹果的推送通知服务器保持长连接状态。
iOS的通知
iOS分本地通知和远程通知,(APNs)是远程通知功能的核心.
- 本地通知是由本地应用触发的。一般是基于时间的一种通知形式,如闹钟、待办事件等的提醒。
- 远程通知是通过我们自己的服务器推送消息的一种通知形式。
APNs推送流程
假如我们的苹果设备(AC电脑、笔记本、iPad、iPhone等)安装了一个名叫XXX的应用。那么我们具体是怎样接收到推送通知的那??接下来我们就说说具体这个过程。下面是苹果APNs官方简介 中提供的APNs推送流程的图
Provier 代表我们自己的应用服务器
APNs 代表苹果的APNs推送服务器
接着是代表的就是苹果的设备
Client App 代表我们开发的应用
说明:
-
- 安装了XXX应用的苹果设备需要向APNs服务器注册,注册成功后APNs服务器会返回一个deviceToken,并且二者之间会维持一个长连接(这个长连接是基于SSL协议的TCP流通讯)
-
- 拿到这个deviceToken后我们将这个deviceToken发给我们自己的服务器
-
- 当有消息需要被推送时,我们自己的服务器会将消息按指定的格式结合设备的deviceToken一并打包 然后发给APNs服务器
-
- APNs将新消息推送给我们的设备上,然后就在设备的屏幕上显示出来了 (因为我们的设备和APNs服务器二者之间维持了一个长连接)
注意说明:
真正完成推送的是APNS服务器。消息一定是由APNs服务器推送给我们的设备的,我们自己的应用服务器只是将需要推送的消息告诉APNs服务器。至于如何维护消息队列或如何保证消息能被推送到指定的设备上,这些都由苹果APNs做好的。
什么是deviceToken ?
deviceToken是一个APP装在一个设备上的唯一标识符。一个APP在不同的设备上deviceToken不一样;一个APP删除之后再次安装deviceToken也不一样。
在项目代码AppDelegate里面有一个回调方法,当APNs注册成功通过该回调方法可以获取到返回的deviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
上面说过当有消息需要被推送时,我们自己的服务器会将消息按指定的格式结合设备的deviceToken一并打包 ,APNs拿到这个包之后验证这个包结构是否正确并提取其中的信息后,再将消息推送到指定的设备。
接下来就来看看这个包的结构:
这个包分五个部分
- 第一个部分是命令标示符
- 第二个部分是我们的deviceToken的长度
- 第三个部分是我们的deviceToken字符串
- 第四个部分是推送的消息体(Payload)的长度
- 最后一个部分也就是真正的消息内容了,里面包含了推送消息的基本信息。(比如消息内容,应用icon右上角显示的数字角标以及推送消息到达时所播放的声音等)
接下来详细看一下Payload(消息体)的结构
Payload(消息体)其实就是个JSON结构体。上面的图只是简单的一种消息体更多详细类型的消息体类型,请看消息体苹果官方相关介绍
- alert里的就是会显示在用户手机上的推送标题内容
- badge显示的数量(注意是整型)是会在应用icon右上角显示的数量,提示有多少条未读消息等
- sound就是当推送信息送达是手机播放的声音,传defalut就标明使用系统默认声音,如果传比如“xxx.wav”就会播放在我们应用工程目录下名称为xxx.wav的音频文件,比如当手机锁屏时QQ在后台收到新消息时的滴滴声。
安全架构
为了保证安全性,APNs用连接信任(connection trust)和token信任(token trust)来控制通信入口,你要用APNs则必须用通过这两种验证。
连接信任
连接信任第一个作用是保证APNs连接的provider是苹果已经同意可通信的,然后第二个是保证与APNs连接的设备的合法性,第二步是APNs处理的,你所要处理的是provider与APNs之间的连接安全性。
服务器与APNs之间的连接信任
每个服务器都必须要有唯一的provider证书和私钥,都是用来验证连接的。provider证书就是在开发者官网申请的。
服务器通过TLS验证和APNs连接,HTTPS中用的也是TLS协议,即四步握手,首先初始化TLS连接,即provider(服务器)发送请求给APNs,APNs服务器返回APNs证书(即公钥)给provider,然后服务端收到后生成provider证书后再返回给APNs,APNs收到后验证后即可以建立TLS连接,不过APNs用的不是HTTPS,而是HTTP/2,具体过程如下图
APNs推送中的问题
问题一: 当应用从设备卸载后,推送的消息改如何处理??
我们知道当应用从设备卸载后,是收不到推送消息的。但是,如何让APNs和Provider知道不再向这台卸载了应用的设备推送消息呢?
针对这个问题苹果也已经帮我们解决了(那就是Feedback Service)。它是APNS的一部分,APNs会持续的更新Feedback service的列表,当我们的Provider将信息发给APNs服务器,APNs推送信息到我们的设备时,如果这时设备无法将消息推送到指定的应用(应用已经删除),就会向APNs服务器发送一个反馈信息,而这个信息就记录在Feedback service中。按照这种方式,Provider应该定时的去检测Feedback service的列表,然后删除在自己数据库中记录的存在于反馈列表中的deviceToken,从而不再向这些设备发送推送信息。连接Feedback service的过程同样使用长连接的方式,连接上后,直接接收由APNs传输给我们的反馈列表,传输完成后断开连接,然后我们根据这个最新的反馈列表在更新我们自己的数据库,删除那些不再需要推送信息的设备的deviceToken。
从Feedback service读取的数据结构如下:
结构中包含三个部分
- 第一部分是一个时间戳,记录的是设备失效后的时间信息
- 第二个部分是deviceToken的长度
- 第三部分就是失效的deviceToken,我们所要获取的就是第三部分,跟我们的数据库进行对比后,删除对应的deviceToken,下次不再向这些设备发送推送信息
问题二:iOS 重复推送之谜 文章地址
问题三:收不到 APNs 推送怎么办?
- 首先要知道服务器推送成功,并不代表设备就能收到推送。服务器推送成功只是将消息交给了苹果服务器而已,苹果服务器还需要设备在线才能推送的。
- 其次 deviceToken 可能会在 APP 卸载重装后发生变化,客户端对此需要制定相应的汇报策略,以便服务器及时更新存储的 deviceToken 。
客户端只要能上报正确的 deviceToken 就可以说明客户端实现没问题了。否则检查客户端是否开启了远程推送通知服务,Bundle Identifier 是否与申请的推送证书匹配。 - 检查服务器内存缓存的 deviceToken 或者数据库存储的 deviceToken 是否与客户端汇报的一致。
排查服务器配置的证书是否过期,是否与客户端的 Bundle Identifier 匹配,或者是否勿用了其他类型的推送证书。
采用抓包工具(如 Wireshark )抓包分析,看看服务器是否将消息交给苹果服务器,客户端是否收到了相应的推送通知。
参考文档:
国内 90%以上的 iOS 开发者,对 APNs 的认识都是错的
iOS 必知必会 - APNs篇
苹果推送机制APNs(一)