BackgroundGeolocation.registerHeadlessTask(headlessTask) does not work on iOS
QL-Uday opened this issue · 7 comments
Hello, I've been trying to perform some calculation based on location updates in killed state on iOS. As I read the package provide us the "bg.BackgroundGeolocation.registerHeadlessTask(backgroundGeolocationHeadlessTask);" method which opens a separate isolate for our background task. So we used this, and this worked fine for Android. The problem is that when we used this method on iOS it didn't work.
Your Environment
- Plugin version: 4.16.4
- Platform: iOS
- OS version: 17.2
- Device manufacturer / model: iPhone SE (3rd generation)
- Flutter info (
flutter doctor
): 3.24.0 - Plugin config:
Config(
logLevel: Config.LOG_LEVEL_VERBOSE,
desiredAccuracy: Config.DESIRED_ACCURACY_HIGH,
distanceFilter: 1.0,
stopOnTerminate: false,
startOnBoot: true,
enableHeadless: true,
debug: true,
isMoving: true,
backgroundPermissionRationale: PermissionRationale(
title: kAllowLocationInBackground,
message: Platform.isAndroid
? kAndroidLocPermissionMessage
: kIOSLocPermissionMessage,
positiveAction: kGoToSettings,
negativeAction: kCancel),
)
Expected Behavior
bg.BackgroundGeolocation.registerHeadlessTask(backgroundGeolocationHeadlessTask); should work in iOS and Android
Actual Behavior
bg.BackgroundGeolocation.registerHeadlessTask(backgroundGeolocationHeadlessTask); only works in Android
Steps to Reproduce
- call the bg.BackgroundGeolocation.registerHeadlessTask(backgroundGeolocationHeadlessTask); method
- setup the event Listeners
- setup the Config
- Call the BackgroundGeolocation.start() funtion.
- Kill the app
- The headless task doesn't executes
Context
The Task that I am performing in HeadlessTask:- I am reading the location updates and saving it to Objectbox DB and then comparing it from the previous location logs and doing some calculation to find the nearest location to a specific point. means I am doing some reads and write to ObjectBox DB performing some calculations. But nothing happens when I call this method on iOS in killed state.
Debug logs
Logs
PASTE_YOUR_LOGS_HERE
There’s no such thing as headless iOS. That’s why the API docs for Config.enableHeadless note that it’s iOS only.
the iOS operating system is fundamentally different than Android. Android has a concept of “services” that are able to run when you app is terminated — ios does not.
see api docs Config.stopOnTerminate to learn about iOS behaviour after an app is terminated.
@christocracy I understand that, according to the Config.stopOnTerminate page of the plugin, when the user moves beyond the stationary geofence (usually around 200 meters), iOS will fully "reboot" your application in the background, including restarting the Flutter app, and the plugin will resume location tracking.
Given this, can I perform my tasks while receiving location updates after this reboot? If so, does the plugin provide any methods or APIs to facilitate this? Would BackgroundFetch.registerHeadlessTask() be useful for my use case?
The tasks I need to perform with each location update include:
- Opening and accessing an ObjectBox database.
- Performing read operations on location data.
- Executing write operations, including saving the new location updates to the ObjectBox store.
- Sending the updated location to a backend API.
- Performing calculations based on previously recorded location logs.
- Updating the location value in the store and sending the new calculated location to the backend.
- Closing the ObjectBox Store.
There are approximately 20 write operations and 12 read operations involved in this process.
does the plugin provide any methods or APIs to facilitate this? Would BackgroundFetch.registerHeadlessTask()
It makes no sense to talk of “headless task” with-respect-to iOS.
when your app is launched automatically in the background by iOS due to moving at least 200 meters, there’s nothing special you need to do. Your app comes alive just as it launched by the homescreen icon.
And btw, there’s no such thing as stopOnTerminate: false for iOS BackgroundFetch. When the user terminates an iOS app, the OS will no longer fire background-fetch events. This is noted at the top of the background-fetch GitHub readme
Can I perform tasks when my app is brought to life in the background? I understand that it won't be in the foreground after moving beyond 200 meters.
Why don’t you experiment with iOS in the Simulator with location simulated with “Freeway Drive”?
Thanks @christocracy , I understood that the app comes alive just as it launched by the homescreen icon. and I can call whatever method I need to call at app start. As it would be called at app start.