I've configured background task in plist.info
with an identifier updateCountry
and Background Modes fetch and processing as capability.
I have locationManager with these functions:
func registerBackgroundTask() {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "updateCountry", using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
print("register backgoundtask")
}
}
func handleAppRefresh(task: BGAppRefreshTask) {
print("registrando pais")
scheduleBackgroundTask()
DispatchQueue.global().async {
self.detectCountry()
task.setTaskCompleted(success: true)
print("Background task completed.")
}
}
func scheduleBackgroundTask() {
print("request updateCountry")
let request = BGAppRefreshTaskRequest(identifier: "updateCountry")
request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 1) // 1 minute
do {
try BGTaskScheduler.shared.submit(request)
print("Background task scheduled successfully.")
} catch {
print("Unable to submit task: \(error)")
}
}
I'm calling this functions in this way where handleAppRefresh
calls a class function to detect the country where you are and add to an array... Everything seems fine, and I have no error, but nothing is printed in the console and doesn't work or update country list...
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(container)
.backgroundTask(.appRefresh("updateCountry")) {
await locationManager.registerBackgroundTask()
}
}
Anyone knows how to fix it or where is the problem?
.backgroundTask(.appRefresh("updateCountry"))
is the SwiftUI version of
BGTaskScheduler.shared.register
Change your code to something like
.backgroundTask(.appRefresh("updateCountry")) {
//The task you want performed.
scheduleBackgroundTask() //Must be sync or async/await, don't use GCD
detectCountry() //Must be sink or async/await, don't use GCD
}
And don't forget to call scheduleBackgroundTask()
somewhere else for the first time.
When in development mode you can trigger a background task on demand by placing a breakpoint after submit
do {
try BGTaskScheduler.shared.submit(request)
print("Background task scheduled successfully.")
//ADD breakpoint here
} catch {
print("Unable to submit task: \(error)")
}
Then when you run the app and the breakpoint gets triggered type in the debugger.
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"TASK_IDENTIFIER"]
with TASK_IDENTIFIER
being "updateCountry" in your case.
But something to be aware... Background Tasks won't run every minute. You can suggest that but Apple will decide when to run, dont expect anything more often than every hour.
For something like location you are better off using LocationManager
.
https://developer.apple.com/documentation/corelocation/handling_location_updates_in_the_background#
And since you are monitoring "Country" "Significant Change In Location" might be the right solution.