Gabrielle Earnshaw
Gabrielle Earnshaw

Reputation: 338

iOS location updates are infrequent when starting location monitoring while app is in the background

I have an app that uses CLLocationManager to request location updates. Monitoring is started when the app receives a notification from an external bluetooth device. The app listens for notifications from the device while it is both in the foreground and the background, and location updates are started successfully in both cases.

If monitoring is started while the app is in the foreground, I get location updates as per the distance filter I have configured on the location manager.

However if monitoring is started while the app is in the background, I still get location updates, but very infrequently. Does anyone know if this is expected behaviour, or if I have potentially configured something incorrectly?

The setup in the code is as follows:

fileprivate lazy var locationManager = CLLocationManager()

func initLocationManager(distanceFilter: CLLocationDistance = 270,
                             desiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyNearestTenMeters,
                             activityType: CLActivityType = .automotiveNavigation) {
    locationManager.requestAlwaysAuthorization()
    locationManager.allowsBackgroundLocationUpdates = true
    if canGetLocationUpdate() {
        locationManager.desiredAccuracy = desiredAccuracy
        locationManager.distanceFilter = distanceFilter
        locationManager.activityType = activityType
        locationManager.delegate = self
    }
}

func startLocationMonitoring() {
    if CLLocationManager.locationServicesEnabled() {
        locationManager.startUpdatingLocation()
    } else {
        log.error("Unable to start location monitoring")
    }
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    for location in locations {
        log.debug("Got location \(location.coordinate) with speed \(location.speed) and accuracy \(location.horizontalAccuracy)")
    }
}

And the following is in Info.plist:

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key><string>To allow the app...</string>
<key>NSLocationAlwaysUsageDescription</key><string>To allow the app...</string>
<key>NSLocationWhenInUseUsageDescription</key><string>To allow the app...</string>
...
<key>UIBackgroundModes</key>
<array>
    <string>bluetooth-central</string>
    <string>location</string>
</array>

Upvotes: 7

Views: 418

Answers (2)

kd02
kd02

Reputation: 430

The location updates your app gets while in the background is completely handled by iOS and out of your apps control.

According to Apple's documentation regarding background location services:

Enabling this mode does not prevent the system from suspending the app, but it does tell the system that it should wake up the app whenever there is new location data to deliver. Thus, this key effectively lets the app run in the background to process location updates whenever they occur.

For more information refer to Background Execution

Upvotes: 0

Arthur Sahakyan
Arthur Sahakyan

Reputation: 566

From apple docs

If your iOS app must keep monitoring location even while it’s in the background, use the standard location service and specify the location value of the UIBackgroundModes key to continue running in the background and receiving location updates. (In this situation, you should also make sure the location manager’s pausesLocationUpdatesAutomatically property is set to YES to help conserve power.) Examples of apps that might need this type of location updating are fitness or turn-by-turn navigation apps.

Seems like iOS restrict location updates in background to save device power.

Upvotes: 2

Related Questions