使用 BGTaskScheduler 进行后台获取与调试模拟完美配合,但在实践中却不起作用

Ami*_*eza 6 xcode background ios swift

我在 appDelegate 的 didFinishLaunchingWithOptions 中注册后台获取任务:

BGTaskScheduler.shared.register(forTaskWithIdentifier: BackgroundScheduler.shared.backgroundTaskId, using: DispatchQueue.main) { task in

    BackgroundScheduler.shared.handleAppRefresh(task: task as! BGAppRefreshTask)
}
Run Code Online (Sandbox Code Playgroud)

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

刷新间隔为 10 * 60,即 10 分钟。

operation.fetch 方法检查设备的当前位置并向远程服务器发送请求。最后它发送本地通知,更新 UI 并调用以下代码:

task.setTaskCompleted(success: true)
Run Code Online (Sandbox Code Playgroud)

“位置更新”和“后台获取”功能均在 Xcode 中检查,并将所需设置添加到 info.plist。

当我使用以下调试命令测试后台获取功能时,一切正常,并且调试器中没有任何警告消息。

e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"TASK_IDENTIFIER"]
Run Code Online (Sandbox Code Playgroud)

但是,当我将应用程序留在后台(即使很长时间)时,iOS 也不会调用handleAppRefresh 函数。

Xcode:12.2,iOS:14.2

项目公共仓库: https://github.com/amirrezaeghtedari/CoronaVirousRegulations.git

我完全糊涂了。

Ami*_*eza 8

我将后台获取间隔设置为 10 分钟,等待大约 4 小时或更长时间后,iOS 在后台运行了我的应用程序。之后,我的应用程序会在后台不规则地调用,间隔从不到一小时到几个小时不等。很明显,我的实现没有问题,这些执行间隔取决于iOS策略。