CLLocationManager: getting kCLErrorDenied in widget

I am having some problem with accessing the CLLLocationManager location from my widget. It works fine with Xcode 15 running on a iOS17 simulator. But running it on a iOS17 device gives me an error in the delegate:

To access the location manager, I have this class:

class WidgetLocationManager: NSObject, CLLocationManagerDelegate {
    var locationManager: CLLocationManager?
    private var handler: ((CLLocation?) -> Void)?

    override init() {
        super.init()
        DispatchQueue.main.async {
            print("WidgetLocationManager: init")
            
            self.locationManager = CLLocationManager()
            if self.locationManager!.authorizationStatus == .notDetermined {
                print("WidgetLocationManager: init - auth status is Undetermined")
            } else {
                print("WidgetLocationManager: init - auth status = \(self.locationManager!.authorizationStatus)")
            }
        }
    }
    
    func fetchLocation(handler: @escaping (CLLocation?) -> Void) {
        self.handler = handler
        self.locationManager = CLLocationManager()
        self.locationManager!.delegate = self
        self.locationManager!.requestLocation()
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        if let lastLocation = locations.last {
            if (CLLocationCoordinate2DIsValid(lastLocation.coordinate) == true && abs(lastLocation.timestamp.timeIntervalSinceNow) < 60 && lastLocation.horizontalAccuracy < 200.0 && lastLocation.horizontalAccuracy > 0.0) {
                
                self.handler!(locations.last!)
            }
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("WidgetLocationManager: locationManager didFailWithError = \(error)")
        self.handler!(nil)
    }
}

When run on device, I get an error:

WidgetLocationManager: locationManager didFailWithError = Error Domain=kCLErrorDomain Code=1 "(null)"

Code = 1 in CLError is kCLErrorDenied ("Access to location or ranging has been denied by the user")

This is despite getting the following output in the init method:

WidgetLocationManager: init - auth status = CLAuthorizationStatus(rawValue: 4)

The weird thing is that it works fine in the simulator. On device, I've tried deleting and reinstalling the app a couple of times, restarting the device, making sure the privacy setting is correct etc.

Also, on the iOS17 device, when I am in the "Add Widget" page, the location manager runs fine in the preview screen, and shows the 'current location' to the user. But as soon as I add the widget to the home screen, it starts giving me this problem where the location can't be found, and I have to display an error message in the widget.

I have the following keys in the Info.plist for the widget:

  • NSLocationAlwaysAndWhenInUseUsageDescription
  • NSLocationWhenInUseUsageDescription
  • NSWidgetWantsLocation

The app target also has the following keys in the Info.plist:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysAndWhenInUseUsageDescription

Any idea for what I can try to fix this problem?

Thanks.

Accepted Reply

I fixed it by resetting the "Location and Privacy" settings on my iPhone!

Replies

hi

I don't have a solution for the problem you described but I believe I have the very same problem which I described here: https://developer.apple.com/forums/thread/737879 CLLocationManager sends location data to 'didUpdateLocations' when running in the simulator but not on the physical device.

The only difference I noticed is that the error that 'didFailWithError' is a different one than the one you have received. In my app the same error code arrives (Error Domain=kCLErrorDomain Code=1 "(null)") but its description says "Operation could not be completed". I noticed this error also when running the app in the simulator but nevertheless the location data is delivered even though this error was shown at the beginning of location data delivery. On the physical device the error arrives and no location data arrive.

Thomas

  • Hi. Thanks, they do seem like very similar problems. In my case, it seems to happen on my main iPhone mostly, and seems to work fine on a couple of test devices. Do you have that experience as well? Is it working in production for you? Have you tried iOS16? I'm wondering if it's just a bug with the app not reading the correct permissions on my device, for my app.

  • Ya, I just reset the Privacy and Location settings on my iPhone, and it works fine now.

  • great! thank you very much, I did also reset the location/privacy and now it work

Add a Comment

I fixed it by resetting the "Location and Privacy" settings on my iPhone!