'CLLocationManager: didChangeAuthorizationStatus not called in iOS 13

I have an app that has been working fine for several years, but location services are not working properly for iOS 13 on newer iPhones. Works fine on 7 and below. When the CLLocationManager is initialized the CLLocationManager: didChangeAuthorizationStatus method is not called.

Here is the code:

var firstMapLoad = true
let locationManager = CLLocationManager()
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self

....

    // MARK: - CLLocationManagerDelegate

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status:    CLAuthorizationStatus) {
        print ("locationManager: didChangeAuthorization called")
        if (CLLocationManager.locationServicesEnabled()) {
            switch status {
            case .notDetermined:
                // Request when-in-use authorization initially
                locationManager.requestWhenInUseAuthorization()
                print ("locationManager: notDetermined & requestWhenInUseAuthorization")
                break
            case .authorizedWhenInUse:
                // Enable basic location features
                locationManager.startUpdatingLocation()
                print ("locationManager: authorizedWhenInUse & startUpdatingLocation")
                break
            case .authorizedAlways:
                // Enable any of your app's location features
                //enableMyAlwaysFeatures()
                break
            case .restricted, .denied:
                //determine if system or app loc svcs disabled
                print ("locationManager: restricted or denied")
                noAppLocationService()
                break
            @unknown default:
                print("locationManager: unknown authorization state")
            }
        }else{
            viewOnlyMode()
        }
     }

     func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let GPSAccuracy:CLLocation = locations[0] as CLLocation
        print ("locationManager: didUpdateLocations")
        if let location = locations.last?.coordinate {
            if (currentLocation.latitude != location.latitude) || (currentLocation.longitude != location.longitude) {
                self.currentLocation = location
                GPSHorizontalAccuracy = GPSAccuracy.horizontalAccuracy
                //                print("LocManAccuracy: \(GPSAccuracy.horizontalAccuracy)")
                //                print("LocManLatitude: \(GPSAccuracy.coordinate.latitude)")
                //                print("LocManLongitude: \(GPSAccuracy.coordinate.longitude)")
                //                print("LocManCurrLat: \(currentLocation.latitude)")
                //                print("LocManCurrLong: \(currentLocation.longitude)")
                if firstMapLoad {
                    // Set the map’s center coordinate and zoom level.
                    let camera = GMSCameraPosition.camera(withTarget: self.currentLocation, zoom: 13)
                    self.viewMap?.animate(to: camera)
                    firstMapLoad = false;

                }
            }
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("Location Error = \(error.localizedDescription)")
    }

When I run it on the iPhone 11 Pro Max simulator in Xcode, if the iPhone simulator has been reset and run the app for the first time I get the authorization alert with the 3 choices. I select "when in use" and the app works fine - the didChangeAuthorization function is called twice (once when location manager is initialized and then when I select "when in use"). didUpdateLocations is then called and the app gets location updates.

If I stop the app, delete it from the simulator and then re-run from Xcode the app does not request user permission for location services. didChangeAuthorization is not called when the location manager is initialized and thus location services are not started and the app doesn't receive any location updates. I have observed the same behavior on a real iPhone 11 Pro.

I tried setting the permission for the app to "never" in the app location settings, stopped the app and then deleted the app on the simulator. When I ran from Xcode the next time the app did not ask for location permissions, but did display an alert that location services were disabled. It appears that the settings from the previous installation were retained even though the app was deleted.



Solution 1:[1]

In my case, the delegate's method signature was wrong for iOS 14+

iOS <=13, deprecated in iOS 14

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {

iOS 14+

func locationManagerDidChangeAuthorization(_ manager: CLLocationManager)

If you're targeting iOS <14, you should implement both

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1