3
votes

I’m writing an app with background location support. The app need to track user location points as they drive through towns on delivery routes.

I use startUpdatingLocation() from CLLocationManager, and everything works fine until the app has been in the background about 15 minutes.

The app then seems to terminate and tracking ends.

I know this continuous tracking (i.e MapMyRun) has to work, but I’m stumped as to how.

Edit: LocationManager configured as follows

self.locationManager?.desiredAccuracy = kCLLocationAccuracyBestForNavigation
self.locationManager?.distanceFilter = kCLDistanceFilterNone
self.locationManager?.allowsBackgroundLocationUpdates = true
self.locationManager?.pausesLocationUpdatesAutomatically = false
self.locationManager?.activityType = CLActivityType.automotiveNavigation
self.locationManager?.showsBackgroundLocationIndicator = true
4
Welcome to Stack Overflow. You should edit your question to show the relevant code (ie. how you configure your location manager) so that we can help you.Paulw11
What background modes are specified in your info.plist?Ashley Mills
@Paulw11 edits made. On their app. Looks a little wonky on here.Jared Barden
@AshleyMills just “location”Jared Barden
You need to set allowsBackgroundLocationUpdates to truePaulw11

4 Answers

0
votes

In order for the location updates to work in the background you need to enable the Background Mode capability for your app.

If you don't do that the app will terminate in the background after an X amount of time the OS thinks is appropriate.

In order to do that Click on your target, go to the capabilities Tab, enable the Background Modes and Tick the location updates. See the screenshot for more details

BG Modes

Try that and if it is still not working I suggest you upload your location manager code somewhere to take a look.

Hope that helps!

0
votes

iOS kills location service in background. You need to set it manually in iPhone settings.

To enable access, tap Settings > Location and select Always"

You can show an alert to inform the user and go to settings.

func checkUsersLocationServicesAuthorization(){
        /// Check if user has authorized Total Plus to use Location Services
        if CLLocationManager.locationServicesEnabled() {
            switch CLLocationManager.authorizationStatus() {
            case .notDetermined:
                // Request when-in-use authorization initially
                // This is the first and the ONLY time you will be able to ask the user for permission
                self.locationManager.delegate = self
                locationManager.requestWhenInUseAuthorization()
                break

            case .restricted, .denied:
                // Disable location features
                let alert = UIAlertController(title: "Allow Location Access", message: "MyApp needs access to your location. Turn on Location Services in your device settings.", preferredStyle: UIAlertController.Style.alert)

                // Button to Open Settings
                alert.addAction(UIAlertAction(title: "Settings", style: UIAlertAction.Style.default, handler: { action in
                    guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
                        return
                    }
                    if UIApplication.shared.canOpenURL(settingsUrl) {
                        UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                            print("Settings opened: \(success)")
                        })
                    }
                }))
                alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil))
                self.present(alert, animated: true, completion: nil)

                break

            case .authorizedWhenInUse, .authorizedAlways:
                // Enable features that require location services here.
                let alert = UIAlertController(title: "Allow Location Access", message: "Lookout does not have access to your location while in the background. To enable access, tap Settings > Location and select Always", preferredStyle: UIAlertController.Style.alert)

                // Button to Open Settings
                alert.addAction(UIAlertAction(title: "Settings", style: UIAlertAction.Style.default, handler: { action in
                    guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
                        return
                    }
                    if UIApplication.shared.canOpenURL(settingsUrl) {
                        UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                            print("Settings opened: \(success)")
                        })
                    }
                }))
                alert.addAction(UIAlertAction(title: "Not Now", style: UIAlertAction.Style.default, handler: nil))
                self.present(alert, animated: true, completion: nil)

                break
            }
        }
    }

For more accuracy call this method too

func startLocationService(){
    locationManager.startUpdatingLocation()
    locationManager.startMonitoringSignificantLocationChanges()
    locationManager.pausesLocationUpdatesAutomatically = false
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.showsBackgroundLocationIndicator = true
}

And don't forget to enable Background Modes in Target -> signing and capabilites

last check is to add permission in info.plist

Thanks all you have to do for live location in background

-1
votes

Check out

CLLocationManager.startMonitoringSignificantLocationChanges()

The Apple documentation here

-1
votes

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