Let's say I have a Task that I want to extend into the background with beginBackgroundTask(expirationHandler:). Furthermore, I'd like to leverage cooperative cancelation of subtasks when responding to the expiration handler. Unfortunately, the expirationHandler: closure parameter is not async, so I'm unable to do something like:
actor MyTaskManagerOne {
var backgroundID = UIBackgroundTaskIdentifier.invalid
func start() {
Task {
let doTheWorkTask = Task {
await self.doTheWork()
}
backgroundID = await UIApplication.shared.beginBackgroundTask {
doTheWorkTask.cancel()
// next line: compile error, since not an async context
await doTheWorkTask.value // ensure work finishes up
// next line: generates MainActor compilation warnings despite docs allowing it
UIApplication.shared.endBackgroundTask(self.backgroundID)
}
await doTheWorkTask.value
}
}
func doTheWork() async {}
}
So instead, I think I have to do something like this. It, however, generates runtime warnings, since I'm not directly calling endBackgroundTask(_:) at the end of the expirationHandler:
actor MyTaskManagerTwo {
var backgroundID = UIBackgroundTaskIdentifier.invalid
func start() {
Task {
let doTheWorkTask = Task {
await self.doTheWork()
}
backgroundID = await UIApplication.shared.beginBackgroundTask {
doTheWorkTask.cancel()
// 1. not calling endBackgroundTask here generates runtime warnings
}
await doTheWorkTask.value
// 2. even though endBackgroundTask gets called
// here (as long as my cooperative cancellation
// implementations abort quickly in `doTheWork()`)
await UIApplication.shared.endBackgroundTask(self.backgroundID)
}
}
func doTheWork() async {}
}
As best I can tell, the MyTaskManagerTwo actor works and does not cause a watchdog termination (as long as cancellation is sufficiently fast). It is, however, producing the following runtime warning:
Background task still not ended after expiration handlers were called: <_UIBackgroundTaskInfo: 0x302753840>: taskID = 2, taskName = Called by libswift_Concurrency.dylib, from <redacted>, creationTime = 9674 (elapsed = 28). This app will likely be terminated by the system. Call UIApplication.endBackgroundTask(_:) to avoid this.
Is the runtime warning ok to ignore in this case?