iOS 9 Swift Programming Cookbook (2015)
Chapter 8. Maps and Location
8.2 Requesting the User’s Location in Background
Problem
You want to receive updates on the user’s location while in the background. Being a good iOS citizen, you won’t ask for this unless you really need it for the main functionality of your app.
Solution
Set the allowsBackgroundLocationUpdates property of your location manager to true and ask for location updates using the requestAlwaysAuthorization() function.
Discussion
When linked against iOS 9, apps that want to ask for a user’s location when the app is in the background have to set the allowsBackgroundLocationUpdates property of their location manager to true. We are going to have to have a look at an example. Start a single view controller app, place a button on your UI with IB, and give it a title similar to “Request background location updates”. Then hook it to a method in your view controller and name the method requestBackgroundLocationUpdates(). In your Info.plist file, set the string value of theNSLocationAlwaysUsageDescription key and make sure that it explains exactly why you want to access the user’s location even in the background. Then go into the Capabilities section of your target, and under Background Modes, enable “Location updates” (Figure 8-1).
Figure 8-1. Enabling location updates in Background Modes in your project
Now import CoreLocation in your code and make your view controller conformant to CLLocationManagerDelegate. Create your location manager and make sure that the allowsBackgroundLocationUpdates property is set to true.
lazy var locationManager: CLLocationManager = {
let m = CLLocationManager()
m.delegate = self
m.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
m.allowsBackgroundLocationUpdates = true
return m
}()
When the user presses the button, ask for location updates:
@IBAction func requestBackgroundLocationUpdates() {
locationManager.requestAlwaysAuthorization()
}
Wait until the user accepts the request and then start looking for location updates:
func locationManager(manager: CLLocationManager,
didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if case CLAuthorizationStatus.AuthorizedAlways = status{
manager.startUpdatingLocation()
}
}
Last but not least, implement the usual location manager methods to get to know when the user’s location has changed:
func locationManager(manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) {
//TODO: now you have access to the location. do your work
}
func locationManager(manager: CLLocationManager,
didFailWithError error: NSError) {
//TODO: handle the error
}
See Also