后台任务不调用 Swift 中的类

use*_*436 5 ios uibackgroundtask swift watchkit

我有一个后台任务,应该返回一系列课程,然后将其发送到苹果手表。didReceiveMessage我正在通过调用内部任务WatchConnectivity

后台任务需要执行一些操作,例如打开领域数据库、查询结果和访问文档目录,然后将响应返回到课程字典。当手表输出其获取的课程数据时,该逻辑似乎有效。问题是我认为后台任务实际上并没有调用该方法getWatchCourses()

DispatchQueue.global().async {

    var foundCourses = [[String : Any]]()
    let application = UIApplication.shared
    backgroundTask = application.beginBackgroundTask(withName: "app.test.getCourses") {
        let watchModel = WatchCourseModel()
        let courses = watchModel.getWatchCourses()
        print("Courses: \(courses)")
        foundCourses.append(contentsOf: courses)
    }
    replyHandler(["response": foundCourses])
    application.endBackgroundTask(backgroundTask)
    backgroundTask = UIBackgroundTaskInvalid
}
Run Code Online (Sandbox Code Playgroud)

如果结果是硬编码的,这也不起作用getWatchCourses()。应用程序可以在后台执行此逻辑吗?或者它应该工作吗?

还值得指出的是,网上没有任何地方记录了这一点,他们总是指将简单的文本响应发送回手表,而不是处理器密集型的东西:(

谢谢

Pau*_*w11 3

如果你检查文档,你会发现完整的函数原型是beginBackgroundTask(withName:expirationHandler:)

您通过尾随闭包指定的代码是- 如果您在允许的后台执行时间耗尽之前expirationHandler未调用,则将调用该代码。endBackgroundTask过期处理程序为您提供了在应用程序因超出其后台时间而终止之前执行任何清理的最后机会。

由于您几乎立即调用endBackgroundTask并从函数返回,因此不会调用到期处理程序。

你真正想要的是这样的:

var foundCourses = [[String : Any]]()
let application = UIApplication.shared
backgroundTask = application.beginBackgroundTask(withName: "app.test.getCourses") {
DispatchQueue.global().async {
    let watchModel = WatchCourseModel()
    let courses = watchModel.getWatchCourses()
    print("Courses: \(courses)")
    foundCourses.append(contentsOf: courses)
    replyHandler(["response": foundCourses])
    application.endBackgroundTask(backgroundTask)
    backgroundTask = UIBackgroundTaskInvalid
}
Run Code Online (Sandbox Code Playgroud)

这将启动后台任务,然后异步执行工作并将结果传递回手表并结束后台任务。