后台任务 (.backgroundTask) 在 SwiftUI 中不起作用

background task (.backgroundTask) doesn't work in SwiftUI

提问人:Gonzalo M. Rivas 提问时间:11/16/2023 最后编辑:soundflixGonzalo M. Rivas 更新时间:11/17/2023 访问量:83

问:

我已经配置了后台任务,并具有标识符和后台模式获取和处理功能。 我有具有以下功能的locationManager:plist.infoupdateCountry

func registerBackgroundTask() {
    BGTaskScheduler.shared.register(forTaskWithIdentifier: "updateCountry", using: nil) { task in
        self.handleAppRefresh(task: task as! BGAppRefreshTask)
        print("register backgoundtask")
    }
}

func handleAppRefresh(task: BGAppRefreshTask) {
    print("registrando pais")
    scheduleBackgroundTask()
    DispatchQueue.global().async {
        self.detectCountry()
        
        task.setTaskCompleted(success: true)
        print("Background task completed.")
    }
}

func scheduleBackgroundTask() {
    print("request updateCountry")
    let request = BGAppRefreshTaskRequest(identifier: "updateCountry")
    request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 1) // 1 minute
    
    do {
        try BGTaskScheduler.shared.submit(request)
        print("Background task scheduled successfully.")
    } catch {
        print("Unable to submit task: \(error)")
    }
}

我以这种方式调用这个函数,其中调用一个类函数来检测您所在的国家/地区并添加到数组中......一切似乎都很好,我没有错误,但是控制台中没有打印任何内容,也无法正常工作或更新国家/地区列表......handleAppRefresh

var body: some Scene {
    WindowGroup {
        ContentView()
        
    }
    .modelContainer(container)
    .backgroundTask(.appRefresh("updateCountry")) {
        await locationManager.registerBackgroundTask()
    }
}

有人知道如何解决它或问题出在哪里?

swift swiftui 任务后台 获取 bgtaskscheduler

评论

0赞 Larme 11/16/2023
这是在应用程序未“启动”时,对吧?
0赞 Gonzalo M. Rivas 11/16/2023
我假设这是在您第一次启动应用程序之后......在这种情况下,然后每 1 分钟在后台更新一次位置,但我真的想每天都这样做......

答:

2赞 lorem ipsum 11/16/2023 #1
.backgroundTask(.appRefresh("updateCountry"))

是 SwiftUI 的版本

 BGTaskScheduler.shared.register

将代码更改为类似

.backgroundTask(.appRefresh("updateCountry")) {
    //The task you want performed.
    scheduleBackgroundTask() //Must be sync or async/await, don't use GCD
    detectCountry() //Must be sink or async/await, don't use GCD

}

别忘了第一次打电话给其他地方。scheduleBackgroundTask()

在开发模式下,可以通过在submit

do {
    try BGTaskScheduler.shared.submit(request)
    print("Background task scheduled successfully.")

    //ADD breakpoint here
} catch {
    print("Unable to submit task: \(error)")
}

然后,当你运行应用并触发断点时,调试器中的类型。

e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"TASK_IDENTIFIER"]

在您的情况下是“updateCountry”。TASK_IDENTIFIER

https://developer.apple.com/documentation/backgroundtasks/starting_and_terminating_tasks_during_development

但需要注意的是......后台任务不会每分钟运行一次。你可以提出建议,但苹果会决定何时运行,不要指望任何事情比每小时都更频繁。

对于位置之类的东西,您最好使用 .LocationManager

https://developer.apple.com/documentation/corelocation/handling_location_updates_in_the_background#

而且,由于您正在监视“国家/地区”,因此“位置的重大变化”可能是正确的解决方案。

https://developer.apple.com/documentation/corelocation/cllocationmanager/1423531-startmonitoringsignificantlocati