Reputation: 1730
I'm working on an app that needs to process cached location data in the background periodically. While the task usually completes in less than 30 seconds, it could potentially be battery- and network-intensive, as it reverse-geocodes multiple cached locations. And since the task can be considered "database maintenance", I would like to implement it as a background processing task (BGProcessingTask
).
I am trying to use SwiftUI's backgroundTask(_:)
scene modifier to handle the task. I have watched the "Efficiency Awaits" WWDC video (https://developer.apple.com/wwdc22/10142) and read the documentation, and I have not found any information about how to handle BGProcessingTasks
. BackgroundTask
provides appRefresh
and urlSession
tasks, but not background processing tasks.
I have tried registering a BGProcessingTaskRequest
, and then handling it with .appRefresh
. A simplified version of my code looks like this:
struct MyApp: App {
@Environment(\.scenePhase) private var scenePhase
var body: some Scene {
WindowGroup {
ContentView()
}
.onChange(of: scenePhase) { _, newValue in
if case .background = newValue {
scheduleBackgroundTasks()
}
}
.backgroundTask(.appRefresh("com.MyCompany.MyApp-ProcessLocations")) {
scheduleBackgroundTasks()
do {
try await AppDataStore.processLocations()
} catch {
print(error)
}
}
}
}
func scheduleBackgroundTasks() {
let taskDate = nextTaskDate()
let bgTaskRequest = BGProcessingTaskRequest(
identifier: "com.MyCompany.MyApp-ProcessLocations"
)
bgTaskRequest.earliestBeginDate = taskDate
bgTaskRequest.requiresExternalPower = true
bgTaskRequest.requiresNetworkConnectivity = true
try? BGTaskScheduler.shared.submit(bgTaskRequest)
}
The task successfully runs when triggering it with the debugging method used in the WWDC videos, but since I can't find any published info on the subject, I don't know if it's safe to do this in production.
What are the implications of handling the processing task with .appRefresh
? For example will the system allow my app to run for the amount of time allocated to processing tasks, or will it be terminated after 30 seconds like an app refresh task? Will the backgroundTask
modifier correctly tell the system when the task completes?
Finally, if the backgroundTask
modifier can't be used, how should background processing tasks be handled in a SwiftUI app?
Upvotes: 1
Views: 295