我在appDelegate:的didFinishLaunchingWithOptions中注册后台获取任务
BGTaskScheduler.shared.register(forTaskWithIdentifier: BackgroundScheduler.shared.backgroundTaskId, using: DispatchQueue.main) { task in
BackgroundScheduler.shared.handleAppRefresh(task: task as! BGAppRefreshTask)
}
handleAppRefersh函数为另一个刷新任务进行调度,并调用该操作的fetch方法,还传递一个完成处理程序,以便在完成fetch操作后运行。
func handleAppRefresh(task: BGAppRefreshTask) {
os_log("handleAppRefresh exetued.")
scheduleAppRefresh()
task.expirationHandler = {
os_log("backgroundFetch expiration called")
}
operation.fetch() {
os_log("backgroundFetch fetch called")
task.setTaskCompleted(success: true)
}
}
scheduleAppRefresh提交BGAppRefreshTAskRequest以重复后台获取执行。
func scheduleAppRefresh() {
os_log("scheduleAppRefresh exetued.")
let request = BGAppRefreshTaskRequest(identifier: backgroundFetchId)
request.earliestBeginDate = Date(timeIntervalSinceNow: AppSettings.refreshInterval)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
os_log("Could not schedule app refresh:", error.localizedDescription)
}
}
refreshInterval为10*60,表示10分钟。
operation.etch方法检查设备的当前位置,并向远程服务器发送请求。最后,它发送本地通知,更新UI并调用以下代码:
task.setTaskCompleted(success: true)
两个";位置更新";以及";背景提取";在Xcode中检查的功能和添加到info.plist.中的所需设置
当我使用下面的debug命令测试后台获取功能时,一切都很正常,调试器中没有任何警告消息。
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"TASK_IDENTIFIER"]
但是,当我把应用程序放在后台很长时间时,iOS永远不会调用handleAppRefresh函数。
Xcode:12.2,iOS:14.2
项目公开回购:https://github.com/amirrezaeghtedari/CoronaVirousRegulations.git
我完全弄糊涂了。
我将后台获取间隔设置为10分钟,等待了大约4个小时或更长时间后,iOS在后台运行了我的应用程序。之后,我的应用程序会不定期地在后台调用,间隔不到一到几个小时。很明显,我的实现没有问题,这些执行间隔取决于iOS策略。
WWDC 2020后台执行解密
据称,有很多因素决定了你的应用程序何时真正运行后台刷新。操作系统的神经引擎会在用户启动应用程序时进行学习,以便在之前执行更新。他们在2019年会议上首次提到这一点。