我有一个后台任务,该任务应返回一系列课程,然后将其发送到Apple Watch。我正在通过didReceiveMessage
在WatchConnectivity
内部调用任务。
后台任务需要执行一些操作,例如打开领域数据库,查询结果和访问document目录,然后将响应返回到课程字典。当手表输出其获取课程数据时,逻辑似乎起作用。问题是我不认为后台任务实际上在调用方法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
}
如果getWatchCourses()
结果是硬编码的,那么这也不起作用。该应用程序可以在后台执行此逻辑,还是可以正常工作?
还值得指出的是,在线上没有任何文献记载, 他们总是指将简单的文字回复发送回手表, 不是处理器密集型的:(
谢谢
答案 0 :(得分:2)
您正在使用尾随闭合进行操作,该操作用于清理。还有更多事情要在后台任务启动后立即结束,因此您的关闭将永远不会调用。
以下是工作示例,背景任务如何工作
var backgroundTaskIdentifier:UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
var updateTimer: Timer?
现在,当您开始运行示例运行计时器时
updateTimer = Timer.scheduledTimer(timeInterval: 0.5, target: self,
selector: #selector(calculateNextNumber), userInfo: nil, repeats: true)
// register background task
beginBackgroundTask()
,当您结束计时器时,结束后台任务;应该始终不间断地结束后台任务
func beginBackgroundTask () {
backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: { [weak self] in
self?.endBackgroundTask() // It will call to cleanup
})
assert(backgroundTaskIdentifier != UIBackgroundTaskInvalid)
}
func endBackgroundTask () {
UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier)
backgroundTaskIdentifier = UIBackgroundTaskInvalid
}
所以就您而言
注意:还请注意苹果给出的执行后台任务的时间限制
编辑
确保已从项目设置中启用了后台功能
尝试
beginBackgroundTask()
let watchModel = WatchCourseModel()
let courses = watchModel.getWatchCourses()
print("Courses: \(courses)")
foundCourses.append(contentsOf: courses)
endBackgroundTask()
答案 1 :(得分:1)
如果您选中documentation,将会看到完整功能的原型为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
}
这将启动后台任务,然后您异步执行工作并将结果传递回手表并结束后台任务。
答案 2 :(得分:0)
您可以通过将QOS类型用作.background来创建后台任务
DispatchQueue.global(qos: .background).async {
//background code
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])
DispatchQueue.main.async {
//your main thread
}
}