4

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?

2
  • That's for when the app is not "launched", right? Commented Nov 16, 2023 at 11:02
  • I asume that this is after you launch the app for the first time... then keep updating location in the background every 1 minute in that case, but really I want to do it every day... Commented Nov 16, 2023 at 11:24

1 Answer 1

6
.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.

https://developer.apple.com/documentation/backgroundtasks/starting_and_terminating_tasks_during_development

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.

https://developer.apple.com/documentation/corelocation/cllocationmanager/1423531-startmonitoringsignificantlocati

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.