ios – locationManagerDidChangeAuthorization not being called


I implemented a class conforming to CLLocationManagerDelegate with the singleton pattern. Calling requestWhenInUseAuthorization (i.e. requestPermission() in the code below) propts the user to accept, as expected. However, locationManagerDidChangeAuthorization(_ manager: CLLocationManager) is not always called once the user taps “Allow once”.
I have not found any pattern when it is called and when not, it seems very inconsistent (It is never called on the first time ever called for each fresh app download. This happens both on a real device as well as the simulator.

When I implement a function forceInit() and call it very early in my app, all works well. Thus I assume this is caused by the Singleton being lazily initialised, and somehow the delegate function not being called if the singleton initialises “too late”.

Am I doing something wrong? Why would I need to initialise the Singleton early, when it is being initialised anyways when needed by the requestPermission() call?


class LocationService: NSObject, CLLocationManagerDelegate {
    
    static var shared: LocationService = LocationService()
    
    @Published private(set) var authorizationStatus: CLAuthorizationStatus
    
    private let clLocationManager: CLLocationManager
    
    public override init() {
        clLocationManager = CLLocationManager()
        authorizationStatus = clLocationManager.authorizationStatus
        
        super.init()
        
        clLocationManager.delegate = self
        clLocationManager.desiredAccuracy = kCLLocationAccuracyBest
        clLocationManager.startUpdatingLocation()
    }
    
    func forceInit() { // why do I need this? I would rather not explicitly initialise...
        authorizationStatus = clLocationManager.authorizationStatus
    }
    
    func requestPermission() {
        self.clLocationManager.requestWhenInUseAuthorization()
    }

    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        print("AAA NEW AUTH: \(manager.authorizationStatus)") // not printed unless forceInit() is called right on app launch
        self.authorizationStatus = manager.authorizationStatus
        // TODO
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let newLocation: CLLocation = locations.first else { return }
        
        // do sth
    }
}

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img