push功能是什么意思啊?手电钻PUSH是什么功能

1、引言

开发iOS系统中的Push推送,通常有以下3种情况:

1)在线Push:比如QQ、微信等IM界面处于前台时,聊天消息和指令都会通过IM自建的网络长连接通道推送过来,这种Push在本文中暂且称为“在线Push”;

2)本地Push:这种就是最常见的iOS系统通知(作用相当于传统PC端的提示窗口,在iOS10以后全部整合到UserNotifications.framework框架了),不涉及任何网络数据,仅仅是让APP拥有一个统一系统通知方式而已,比如:闹钟的定时提醒等;

3)离线/远程Push:这就是iOS程序员最熟悉的APNs这一套东西了,它使得APP处于后台或者被kill的情况下仍能收到网络通知,最常见的应场景就是IM聊天工具了。

本文将对iOS Push的在线push、本地push及离线(远程)push进行了详细梳理,介绍相关逻辑、测试时要注意的要点以及相关工具的使用。小小的Push背后蕴藏着大大的逻辑,我们一起来学习吧!

2、相关文章

《移动端实时消息推送技术浅析》

《iOS的推送服务APNs详解:设计思路、技术原理及缺陷等》

《信鸽团队原创:一起走过 iOS10 上消息推送(APNS)的坑》

《扫盲贴:浅谈iOS和Android后台实时消息推送的原理和区别》

3、iOS的Push种类

3.1 在线push

在线push:当用户在线(APP在前台)时,收到的状态栏的消息提醒,称为在线push。这个功能与苹果系统无关,是我们自己的APP开发的一种功能,该push与设置中是否打开“通知”无关。

这里以iOS Qzone为例,当APP在前台时,自己发的说说被点赞了,收到的在线push如下:

push功能是什么意思啊?手电钻PUSH是什么功能

push功能是什么意思啊?手电钻PUSH是什么功能

2)延迟展示( iOS10以前)

另一种是用scheduleLocalNotification方法按计划来弹本地推送:

push功能是什么意思啊?手电钻PUSH是什么功能

其中alertBody是消息内容锁屏与不锁屏时效果如下:

push功能是什么意思啊?手电钻PUSH是什么功能

2)App运行在后台及前台

上面的2种情况的处理基本一致, 不同点只有当运行再后台的时候,会有弹窗提示用户另外一个App有通知,对于本地通知单的处理都是通过AppDelegate的方法:- (void)application

UIApplication )application didReceiveLocalNotification:UILocalNotification *)notification来处理的。

push功能是什么意思啊?手电钻PUSH是什么功能

5、在线、离线(远程)push流程

5.1 在线push流程

在线push相对简单,因为是内部实现,具体流程如上面所示。

1)判断app是否在线:

此处可以根据APP自身的后台策略如上一次与后台交互的时间等方法来判断APP是否在线或者离线。认为在线,会发送在线push,否则,发送离线push。

2)在线push有以下几个特点:

不需要经过苹果APNs;

需要自己实现长链接;

代码在app内部实现。

5.2 离线(远程)push流程

push功能是什么意思啊?手电钻PUSH是什么功能

(3)名词解释之device token

什么是device token?我们看一下官方的简介:

device token: APNs uses device tokens to identify each unique app and device combination. It also uses them to authenticate the routing of remote notifications sent to a device.(device token是APNs用于区分识别每个iOS设备和设备上不同app的一个标识符,还可以用于APNs通过它将推送消息路由到指定设备上)

即:device token里包含了device id和bundle id的信息,但是device id和bundle id不会确定唯一的device token。

但是,这里有个坑,查资料得知,iOS8及之前的iOS系统,对于同一部手机,如果卸载后重装APP的话,device token是不会变的,在token变了以后,老的token,就被认为是无效了,苹果不会对这部分无效的token推送。但是,对iOS9及以后的iOS系统,对于同一部手机,卸载后重装APP的device token是会发生变化的,而且老的token不会无效,还可以正常推送,这应该是苹果的一个bug,但是苹果也没有修复这个问题,所以这个需要开发者自己来解决,否则容易出现一个app收到多个push的问题。

官方的说法是:

To protect user privacy, do not use device tokens to identify user devices. Device tokens change when the user updates the operating system and when a device’s data and settings are erased. As a result, apps should always request the current device token at launch time.(即此举为了保护用户隐私,device token会在更新系统、擦除设置重置后变化,在一定时间后会过期)

【离线push详细流程】

知道了以上概念后我们重新来看一下离线(远程)push的详细流程:

push功能是什么意思啊?手电钻PUSH是什么功能

那么这两个函数有什么区别呢?其实这两个方法都是用来处理离线push的。

差别就是,如果app在前台是收到离线(远程)push,那么就会调用:

push功能是什么意思啊?手电钻PUSH是什么功能

则会调用:

push功能是什么意思啊?手电钻PUSH是什么功能

6、iOS 10关于push的一些新特性

iOS10新增的UserNotifications框架,主要有了这样几方面的更新:

1)用UserNotifications框架替换了原先与通知相关的接口,通知文字可分为title、subtitle和body三部分,通知可携带附件;

2)系统在展示通知之前,可以唤起app附带的service extension,并且允许它改动通知的内容;

3)用户在对通知右滑查看、下拉或者3d touch的时候,通知会展开,展开后页面的布局可以由app附带的content extension来决定。

6.1 push的多样性

iOS10以前的push只有文字,甚至没有标题。iOS10以后的push更加多样化,可以有主标题,副标题,甚至还有附件。

这里以我司的腾讯新闻为例(有标题,内容,和附件):

push功能是什么意思啊?手电钻PUSH是什么功能

3D touch点入详情以后:

push功能是什么意思啊?手电钻PUSH是什么功能

这里我们惊奇的发现,除了可以携带图片这样的附件、push还能展开详情以外,进入详情以后,下面还多了“打开”、“收藏”、“不感兴趣”这些选项,这里就涉及到以下iOS10的新特性。

6.2 push携带附件

因为payload有大小限制,所以如果remote notification想要携带附件,那么payload上只能带上如附件下载地址之类的信息,等通知到达客户端后由service extension下载附件到本地,然后在初始化UNNotificationAttachment对象时传入附件在本地的URL。

push功能是什么意思啊?手电钻PUSH是什么功能

怎么得知用户选了哪个action并做出相应操作呢?这需要给UNUserNotificationCenter指定一个delegate:

push功能是什么意思啊?手电钻PUSH是什么功能

此外,还有删除所有推送等,都在UNUserNotificationCenter.h中实现。

2)改变离线(远程)push内容:

目前远程push只支持更新push内容,更新需要通过新的字段apps-collapse-id来作为唯一标示。方法是在HTTP/2 请求头中使用相同的apns-collapse-id,这样收到同样的apns-collapse-id的push时,push内容便会更新。

使用场景:比较容易理解的一个场景就是球赛比分,比如现在是1:0,如果变成1:1的话,只需要刷新原来的新闻,这样用户就不会因为同一场比赛收到多条push。

6.5 两个extension

有两个与push相关的extension,可能我们会好奇这两个extension有什么不同,为什么需要两个?它们分别实现什么功能呢?

push功能是什么意思啊?手电钻PUSH是什么功能

【1)notification service extension】

给app添加notification service extension后,系统会在收到通知后唤醒它,并允许它修改通知的内容,之后再展示这个通知。

service extension只对remote notification起作用,local notification是无法唤起它的。

如果想要让系统唤起service extension的话,payload必须符合这样几个条件:

1)必须增加mutable-content字段并为1,这表示允许客户端修改这个通知:

payload(举例)如下:

push功能是什么意思啊?手电钻PUSH是什么功能

2)这个通知必须展示一个alert,如果只是一个修改badge的通知的话,是不会唤起service extension的;

3)静默推送是不能唤起service extension的,所以payload中不能有”content-available” : 1字段。

所以,通过这个notification service extension,你可以在接收到推送之后、展示推送之前处理一些事情,比如说更新一下推送内容,或者在后台做一些其他事情。

【2)notification content extension】

另一项notification content extension用于完全自定义推送展开后的视图。上面腾讯新闻的展开后的视图就是通过这个notification content extension实现的。

依然以腾讯新闻为例子:

push功能是什么意思啊?手电钻PUSH是什么功能

这里Notification Content Extension大展拳脚的地方,在这里可以自定义绘制不同的内容,将希望展现给用户的额外信息可以加载这里。

下半部分的notification action的实现就是在上面提到的“携带action的通知”。

7、iOS Push的测试要点罗列push功能是什么意思啊?手电钻PUSH是什么功能

另外注意一点:测试Push的时候,区分好Appstore证书和开发证书。两者不能相互发Push。

8、有关iOS Push的常见疑问汇总

Q:离线push,支持角标(badge)在本地角标数值上 1这样的操作吗?

A:不支持。如果是自己实现push服务的话,需要自己的后台将角标值badge发送个APNs服务器,有些APP使用第三方push SDK除外。

Q:如果重复收到离线push,可能是什么情况?

A:

1)iOS9之后卸载重装后生成新的deviceToken,后台对多个deviceToken都发送了push

2)后台对注销了的账号也发送了push。

总而言之一般是后台的逻辑出现了问题,而不是APNs服务器出现问题。

Q:直接卸载APP,还能收到离线push吗?

A:不会收到。直接卸载APP,虽然后台不知道APP被卸载了,仍然会对之前的账号发送push,但是由于手机上没有对应APP,所以并不会收到push。

Q:为什么有时候全新安装APP就立马有红点角标?

A:这是因为卸载该APP时有红点角标。每个 APP 的角标都是存在 iOS 手机系统里的,开发无法修改,所以此时卸载前有角标,重新安装也会有角标。但是,APP 卸载之后超过一天的时间再重装,那么角标就会被系统清空,届时也不会有新安装的 APP 就有角标的情况存在。

Q:自己Server通过APNs发的每一条Push,客户端都会收到么?

答案是否定的,Push是不可靠的,push通知是fire-and-forget,比如手机关机,那么自然就收不到,虽然Apple会尝试几次。

Q:Push消息的大小是多少?

iOS8发的时间点起,无论那个iOS系统,push消息的body大小调整为2k,注意这里是iOS8的时间点,也就是2014年秋,就目前来说push的限制应该是2k不再是256了。

9、相关工具推荐

Knuff离线push工具下载链接:https://github.com/KnuffApp/Knuff/releases

使用方法也比较简单:

push功能是什么意思啊?手电钻PUSH是什么功能

比如我的payload输入如下:

push功能是什么意思啊?手电钻PUSH是什么功能

得到的应该是有“Knuff测试”文字,和角标数变为999,我们可以看下结果,与预料是一致的:

push功能是什么意思啊?手电钻PUSH是什么功能

有了这个工具也更加方便了我们的iOS push的调试。