iOS的推送功能,相信大家都了解常规的推送APNS,此外苹果还有两种推送SlientPush和PushKit,这两种均可唤醒App,并执行一段本地代码,最近做了些测试,这里给大家总结一下。
一、APNs:
收到通知(在不点击通知的情况下)不会走本地任何代码,此方式不做介绍。
二、SlientPush:
一种静默推送,App无论在前台/后台active/后台kill都会收到通知,并可以执行一段本地代码,此方式激活的App最多保活30秒;每小时有推送次数限制,级别低于APNs。
2、实际测试:
①在前台:可以收到推送
②后台未被kill:可以收到推送,包括锁屏也能收到(如果切到别的app,这时很大概率以后就再也收不到push了)
③程序被kill:可以收到推送(如果切到别的app,基本收不到push了;或者如果手机重启,在不打开app的情况下,也收不到push)
3、总结:
在测试过程中,推送了大概40条以内,之后就再也收不到了,隔了有数十分钟,又可以接收。可见SlientPush是有每小时的次数限制,但是App处于前台是一直可以收到的,这个限制是针对App处于后台的情况。APNs把SlientPush视为低优先级,并且如果消息总数过多,可能会限制其传送。实际的限制是动态且根据具体情况变化的,但是不要在一小时内传送过多的数据。
三、PushKit:
无论app在任何状态下都可以收到通知,并可以执行一段本地代码,级别高于APNs。
1、官方文档:
https://developer.apple.com/documentation/pushkit?language=objc
2、适用场景:
VoIP类,例如A给B发送微信/QQ视频通话时,A给B发的这个推送可以用PushKit实现,B收到通知之后,发出一个本地通知,说是有A的通话。
3、实际测试:
①在前台:可以正常收到推送
②切到后台:在受到通知时,Xcode11.3下运行出来的App会崩溃、Xcode10.3下可以收到。崩溃原因是没有使用CallKit,如下:
Apps receving VoIP pushes must post an incoming call (via CallKit or IncomingCallNotifications) in the same run loop as pushRegistry:didReceiveIncomingPushWithPayload:forType:[withCompletionHandler:] without delay.
4、总结:PushKit的使用要伴随着CallKit,而CallKit在大陆已经禁止使用了。在Xcode11之前,我们可以直对接VoIP推送,唯一面临的是苹果的审核。但是前段时间苹果发布了一则通知:
On iOS 13.0 and later, if you fail to report a call to CallKit, the system will terminate your app. Repeatedly failing to report calls may cause the system to stop delivering any more VoIP push notifications to your app. If you want to initiate a VoIP call without using CallKit, register for push notifications using the UserNotifications framework instead of PushKit. For more information, see UserNotifications.
上述说iOS13.0之后用PushKit必须用CallKit,而用了CallKit则不允许大陆上架。这是一个互斥。
我们下载国外版本微信,是带CallKit功能的,即收到微信通话则交给系统级别进行通话处理;而国内版本微信和钉钉等只是一个本地通知,即PushKit。
Xcode11之前的版本不允许iOS13后的系统进行在线调试,可以打ipa包进行测试。这也意味着随着Xcode升级,PushKit方式也将被大陆淘汰。据开发者网友说PushKit最多能撑几个月,看到时候的规定吧,如果真不能用,微信/钉钉肯定也就只能选择APNs了。目前融云新版本语音和视频通话都改成了APNs。
下图是苹果给我一个开发者朋友的邮件回复:

这是说VoIP应用+PushKit+CallKit,三者搭配才可以
。至此,大陆用PushKit最大的问题,是能否通过苹果上架问题。PushKit还能用多久,就看苹果公司规定了。
结合本篇和上一篇iOS后台保活App并持续接收消息探究所述:
如果想使App处在后台的时候一直保活,持续处理自己代码逻辑,可有如下两种方案:
1、音乐Playback + MixWithOthers
2、定位 + “始终”
如果想外部激活app,并接收/下载内容,目前可有如下一种方案:
1、PushKit + Background Downloading
(后台下载可用Background Downloading技术实现后台持续不中断下载)
备注参考:
1、SlientPush具体代码实现参考:https://www.jianshu.com/p/a8bf0dc8ba8b
2、SlientPush和PushKit推送调试,均可用PushMeBaby,简单实用:https://github.com/Dwarven/PushMeBaby
3、CallKit为什么被禁用:https://baijiahao.baidu.com/s?id=1600471684499747492&wfr=spider&for=pc
网友评论