WWDC2019 Session 707 : Advances in App Background Execution
上面是 session 视频原 link ,大概 40 min,整个视频分为两部分,重点介绍了在 App 的开发中使用 Background Execution 的一些场景与建议,以及新的 BackgroundTask Framework
- Background Execution 介绍
- 谨慎考虑后台执行任务
- 立刻执行的短时间后台任务
- VoIP 推送的后台任务
- 静默 APNS 推送的后台任务
- 后台下载任务 Background URL Session
- 新的 BackgroundTask Framework
- 新框架简介
- 后台任务时间管理
- 代码详解
Background Execution 介绍
所有的后台执行任务一般由2种机制触发
一种是 App 的主动请求,当 App 进入后台的时候,主动请求延续前台未执行完的操作
一种是 Event 被动触发,一些设备的特殊事件触发了后台任务执行,比如用户进入了某些区域等
谨慎考虑后台执行任务
apple 希望开发者慎重考虑,设计后台要执行的任务。因为后台任务会直接影响到用户的
- 电量
- 性能
- 隐私
从这样的一幅图可以看出来,每一行都是一个 App 的时间轴,从早晨开始使用手机到晚上手机充电,FG 代表这 App 在前台运行,BG 代表 App 在后台执行。
- 电量:FG 代表着用户的主动选择,但每个 App 各自开格子的 BG ,就会导致额外的电量消耗,从而增加用户整体的手机电量消耗
- 性能:当一个 App 在前台 FG 执行的时候,可能其他 App 在后台正在执行 BG ,当过多的 App 的 BG 在同一时间进行执行,势必消耗更多的 CPU ,从而影响前台 App FG 的性能表现
- 隐私:后台执行任务是用户不可感知的,所以要谨慎在后台任务中处理那些用户隐私敏感的数据
立刻执行的短时间后台任务(Sending Message)
一般用于在用户主动进入后台的时候,给 App 一些额外的时间,允许在后台运行一些操作(例如磁盘存储,信息发送等),这类后台任务一般都是开始于 App 的前台运行,结束终止在 App 的后台任务。
1 | func send(_ message: Message) { |
在后台任务执行完毕后,要确保执行 endBackgroundTask 来告知系统终止任务,如果任务执行时间过长会触发 expirationHandler ,可以写一条本地推送来告知用户“消息后台发送失败,请打开 App 重新发送”
VoIP 推送的后台任务
这类后台任务可以使用 VoIP 的这种推送的方式触发执行,VoIP 基于 PushKit 相比于 APNS 好处是可以通过后台推送,立刻直接唤醒 App 去执行一些后台任务,
VoIP 只有在网络电话这样的功能才能申请,多用于配合 CallKit 直接在收到推送的时候,发起通话界面
1 | func registerForVoIPPushes() { |
上面就是一个基本的 VoIP 的代码,先注册 PKPushRegistry ,然后在 didReceiveIncomingPushWith 的时候唤起 CallKit 执行网络电话功能
静默 APNS 推送的后台任务
除了 VoIP 这种推送方式,还可以使用 APNS 这种我们最熟悉的推送,苹果有 Background Fetch & Remote Notification 这些能力通过 APNS 提供后台任务执行的机会
- 首先配置一个静音的,没有提示的推送
- 服务器下发这个“静音”推送
- 当 App 收到这个“静音”推送的时候
- 系统会选择恰当的时机,触发并执行后台任务(下载一些内容数据)
- 用户回到前台,看到最新的界面数据
后台下载任务 Background URL Session
普通的网络请求大家都用过是 URLSession ,还有一种可以专门在后台期间执行下载的网络请求即 Background URLSession
1 | // Set up background URL session |
通过 URLSessionConfiguration.background 来创建的 URLSession 就具有后台下载的能力,而设置 discretionary 可以更进一步定义后台下载的时机触发准则(并发精准触发条件,而是由系统衡量在合适的时机进行下载)
1 | // Set timeout intervals |
可以通过 earliestBeginDate 来设置后台下载任务不早于一定时间开始,countOfBytesClientExpectsToSend 和 countOfBytesClientExpectsToReceive 可以设置后台下载任务大概所消耗的流量,从而让系统更合适的安排后台下载的触发
新的 BackgroundTask Framework
新框架简介
全新的后台任务框架,可以更精准的规划后台任务的触发时间点,可以对所有后台任务规划一个时间表,根据不同任务的配置,来实现更灵活的后台任务触发,甚至可以实现一些后台任务,只有在充电时间才会执行
新的 BackgroundTask 有两种类型
- Background Processing Tasks 后台处理型任务
- 在系统认为合适的不同时机,触发执行几分钟
- 可以执行一些大型数据维护等工作
- 也可以执行 CoreML 等机器学习的训练
- 可以关闭 CPU 的监控来执行密集工作
- 在系统认为合适的不同时机,触发执行几分钟
- Background App Refresh Tasks
- 30 秒钟的执行时间
- 可以让 App 全天保持数据最新
苹果系统会记录并学习用户使用 App 的日常习惯,然后在判断用户将要打开 App 之前,触发 Background App Refresh Tasks 。如果 App 用户平时使用频率很低,将不会触发
后台任务时间管理
如图所示:
可以在 App 前台,输入法扩展,分享扩展的前台代码中提交 BackgroundTask 给 BGTaskScheduler 这个后台任务管理器。
BGTaskScheduler 会根据 电量状态/时间/联网状态/设置 来判断适合的时间来执行对应的任务,当任务需要执行来,会激活 App 并执行该后台任务
代码详解
后面的视频中有详细的一整套 demo ,代领大家体验 Background Processing Tasks 与 Background App Refresh Tasks 两种 Task。整个视频介绍内容覆盖很全面,包括:
- 工程配置
- Demo 编写
- 运行展示
- 编译调试
- 使用建议