Swift LocationManager didChangeAuthorizationStatus Always Called

Mike Walker picture Mike Walker · May 7, 2015 · Viewed 14.5k times · Source

I have a view controller which implements the CLLocationManagerDelegate. I create a the CLLocationManager variable:

let locationManager = CLLocationManager()

Then in the viewDidLoad, I set properties:

// Set location manager properties
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.distanceFilter = 50

The problem comes that the function gets called even before I check the authorization status.

func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    if (status == .AuthorizedWhenInUse) {
        // User has granted autorization to location, get location
        locationManager.startUpdatingLocation()
    }
}

Can anyone inform me what could be causing this to occur?

Answer

Bart Vandendriessche picture Bart Vandendriessche · May 7, 2015

- locationManager:didChangeAuthorizationStatus: is called shortly after the CLLocationManager is initialised.

You can request authorization inside the delegate method if you want:

func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    switch status {
    case .notDetermined:
        locationManager.requestAlwaysAuthorization()
        break
    case .authorizedWhenInUse:
        locationManager.startUpdatingLocation()
        break
    case .authorizedAlways:
        locationManager.startUpdatingLocation()
        break
    case .restricted:
        // restricted by e.g. parental controls. User can't enable Location Services
        break
    case .denied:
        // user denied your app access to Location Services, but can grant access from Settings.app
        break
    default:
        break
    }
}

Be aware that you need to assign the delegate in a 'timely' matter if you want this to work.

If you would somehow delay the delegate assignment, e.g. by setting it asynchronously, you might miss the initial call to - locationManager:didChangeAuthorizationStatus:.