Reputation: 853
I'm using background refresh to schedule local notifications and update my widget. The problem is that the task registration method isn't called!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.Mahmoud.AdaniLite.AppRefresh", using: nil) { task in
print("Registered")
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
return true
}
I also have a break point inside the register method with a print statement but non of both worked!
I have done my research and so far i have tried the following already:
Any help or guidance is deeply appreciated!
Upvotes: 6
Views: 5642
Reputation: 2585
If you register and schedule properly, and want to test your task, you can do the following.
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"YOUR_REFRESH_TASK_ID"]
Upvotes: 0
Reputation: 81
I had exactly the same problem as you, and I've been trying to solve it for several hours!
And I've found a solution!
Here are the steps:
In the AppDelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
// …
SchedulingService.shared.registerBackgroundTasks()
return true
}
My service:
class SchedulingService {
static let shared = SchedulingService()
func registerBackgroundTasks() {
let isRegistered = BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.YOUR.refresh", using: nil) { task in
print("Background task is executing: \(task.identifier)")
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
print("Is the background task registered? \(isRegistered)")
}
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "com.YOUR.refresh")
request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 2)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error)")
}
}
private func handleAppRefresh(task: BGAppRefreshTask) {
// <!-- Your background logic here -->
// <!-- LocalNotificationService.sharedInstance.initScheduleNotifications() -->
task.setTaskCompleted(success: true)
scheduleAppRefresh()
}
}
Now, put a breakpoint in the closure at this line:
self.handleAppRefresh(task: task as! BGAppRefreshTask)
Relaunch your app with Xcode (no need to modify the Scheme), put your app in the background with a swipe up, and wait between 5 to 20 minutes, doing nothing else. Make sure your debugger is still attached to your app, and feel free to add print statements throughout to trace execution. Eventually, you should enter the closure and hit your breakpoint. After that, press "Continue" and wait another 2 to 3 minutes, and you should see the self.handleAppRefresh(task: task as! BGAppRefreshTask)
function trigger again.
I hope this helps.
Please note that I'm using an iPhone 11 with a cable. Xcode Version 15.2
Upvotes: 1
Reputation: 285
You’ve only registered your task handler so far. You also need to schedule your background task.
Please see this guide for more information: https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/using_background_tasks_to_update_your_app
It can be a bit unpredictable when your background task will be executed, and might not happen at all exactly when you expect it to.
This outlines how you can debug your task handlers to make sure they’re registered and have correct requests submitted: https://developer.apple.com/documentation/backgroundtasks/starting_and_terminating_tasks_during_development
Upvotes: 0