Hi, I have a couple questions about background app refresh. First, is the function RefreshAppContentsOperation()
where to implement code that needs to be run in the background? Second, despite importing BackgroundTasks, I am getting the error "cannot find operationQueue in scope". What can I do to resolve that? Thank you.
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "peaceofmindmentalhealth.RoutineRefresh")
// Fetch no earlier than 15 minutes from now.
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error)")
}
}
func handleAppRefresh(task: BGAppRefreshTask) {
// Schedule a new refresh task.
scheduleAppRefresh()
// Create an operation that performs the main part of the background task.
let operation = RefreshAppContentsOperation()
// Provide the background task with an expiration handler that cancels the operation.
task.expirationHandler = {
operation.cancel()
}
// Inform the system that the background task is complete
// when the operation completes.
operation.completionBlock = {
task.setTaskCompleted(success: !operation.isCancelled)
}
// Start the operation.
operationQueue.addOperation(operation)
}
func RefreshAppContentsOperation() -> Operation {
}
Indeed. I guess I should be able to recognise our own documentation code )-:
Anyway, with that context, I can answer your specific questions:
is the function
RefreshAppContentsOperation()
where to implement code that needs to be run in the background?
Yes and no. In this example RefreshAppContentsOperation
is meant to be an Operation
subclass that implements the app refresh operation. If you want to use this approach, you’d create your own subclass of Operation
and then implement the main()
method on that. For example:
final class RefreshAppContentsOperation: Operation {
override func main() {
… your code here …
}
}
However, there are other approaches you might adopt. For example, you might start a Task
and run Swift async code within that task.
Note The term task is overloaded in this context. The Background Tasks framework uses it to refer to the state that’s tracking the work and Swift concurrency uses it to refer to the state of the code that’s actually doing the work.
I am getting the error “cannot find operationQueue in scope”
Right. That’s because the doc assumes that you’re using Operation
to managed this work. If you were doing that then you would have an operation queue lying around. If you’re not, then you have a choice:
-
You can use
Operation
as assumed by the doc. In that case, you’d need to create your own operation queue and supply it in the place ofoperationQueue
. -
You can use some other mechanism, in which case you won’t need an operation queue at all. For example, in Swift concurrency you can start a
Task
without worrying about where it starts (Swift concurrency has the concept of a global executor that runs tasks by default).
Historically, I was a big fan of Operation
and I’d use it all the time for stuff like this. These days, however, I’d definitely do this work with Swift concurrency.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"