I am experiencing a problem in a tracking app, but only on iOS 11. The app passively records your GPS position in the background under certain conditions.
The problem that occurs on iOS 11 is that seemingly randomly CLLocationManager stops reporting GPS events for anywhere from 10 to 900+ seconds.
The location manager is set up like the following:
let locationManager = CLLocationManager()
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.startMonitoringSignificantLocationChanges()
locationManager.desiredAccuracy = 10
locationManager.activityType = .automotiveNavigation
Thinking that the thread CoreLocation is managing and using for all callbacks could be overburden.
I have tried delegating to a different thread for processing, so the app does not tie up CoreLocations resources. This is done using an operation queue that is set up like the following:
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
queue.qualityOfService = .userInitiated
with the callback using that operation queue:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
queue.addOperation {
// process locations
}
}
Introducing the operation queue did not help avoid the gaps, but it did make it so that when the gap occurs the location manager reports a bunch of (different) locations with the same timestamp.
The locations with the same timestamps is not all the missing locations, i.e. if there is a gap of 200 seconds, I might only get 15 locations with the same timestamp.
I am hoping someone here can tell me why this is happening and what I can do to avoid these gaps.
Thanks in advance.
After much review, trials, discussion with Apple we now seem have resolve the issue. Even though Apple will only guarantee GPS tracking the background if the app is in the foreground when the tracking starts. The fix we have applied is changing the following:
locationManager.startMonitoringSignificantLocationChanges()
... to:
locationManager.stopMonitoringSignificantLocationChanges()
locationManager.startMonitoringSignificantLocationChanges()
The theory is that the settings for the app become corrupted when applying true to the "monitoring" setting during startup. If first you set the "monitoring" setting to false and afterwards to true, no corruption occurs.
This fix is live in the app store app for several hundreds of people and tracking in the background is working fine.