Rage
Rage

Reputation: 970

How do apps like life360 get location updates in terminated state?

I need to receive location updates even when the app is terminated by the user. Apps like life360 receive accurate location updates in all app states: terminated, background, and foreground. The following two documentations from Apple reinforce that it is possible to get location updates after the app has been terminated:

https://developer.apple.com/documentation/corelocation/getting_the_user_s_location/handling_location_events_in_the_background

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

Strangely enough, I contacted apple directly because I have not been able to get location updates in a terminated state. This is the exact response:

It is expected behavior that an app will not be woken in the background by a Significant Location Change if the app had previously been force-quit by the user. Force quit is a drastic choice by the user to say that they do not want the app to run, often because it misbehaved in some unrecoverable manner.

The only location API that will relaunch an app after a force quit is Region Monitoring.

This begs the question, who is right? Is the documentation incorrect or out of date? How does life360 continuously track the location of my family despite being in a terminated state? Does Apple give special treatment to life360?

Upvotes: 3

Views: 980

Answers (1)

Akshay
Akshay

Reputation: 167

I worked on an app similar to life 360 which used location tracking when the app was terminated or was in the background. This was a relatively simple feat. You have to set your location manager instance to track significant location changes as soon as your app is killed or pushed to the background. This will reduce the battery consumption and the accuracy but will help stop the battery drainage, otherwise iOS may not start your app even after significant location change has been detected. Here is the sample code as to how I achieved this

func applicationWillEnterForeground(_ application: UIApplication) {
    LocationHelper.handleEnterForeground()
}

func applicationDidEnterBackground(_ application: UIApplication) {
    LocationHelper.handleEnterBackground()
}

func applicationWillTerminate(_ application: UIApplication) {
    LocationHelper.handleAppKilled()
}

In LocationManager.swift :

var locationManager = CLLocationManager()

override init() {
    super.init()
    locationManager.delegate = self
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.pausesLocationUpdatesAutomatically = true
    locationManager.activityType = .automotiveNavigation
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.distanceFilter = 25
    
    if hasLocationPermission() {
        self.locationManager.startUpdatingLocation()
    } else {
        self.asklocationPermission()
    }
}

static func handleEnterForeground() {
    LocationHelper.shared = LocationHelper()
    LocationHelper.shared.locationManager.desiredAccuracy = kCLLocationAccuracyBest
    LocationHelper.shared.locationManager.startUpdatingLocation()
}

static func handleEnterBackground() {
    LocationHelper.shared = LocationHelper()
    LocationHelper.shared.locationManager.stopUpdatingLocation()
    LocationHelper.shared.locationManager.startMonitoringSignificantLocationChanges()
}

static func handleAppKilled() {
    LocationHelper.shared = LocationHelper()
    LocationHelper.shared.locationManager.stopUpdatingLocation()
    LocationHelper.shared.locationManager.startMonitoringSignificantLocationChanges()
}

Upvotes: 1

Related Questions