xcodecore-locationwatchos

Core Location not working properly with stand-alone WatchOS App


I'm working on a stand-alone WatchOS App that relies on the user's location data.

I'm trying to fetch user's current location using CLLocationManager, by having an instance called manager, then calling requestWhenInUseAuthorization() method.

Somehow, the location permission dialog doesn't show up on the Apple Watch, I get the notDetermined authorizationStatus.

I've ensured the following to make sure I didn't miss anything:

  1. Added the NSLocationWhenInUseUsageDescription key/value pair to Info.plist file.
  2. Marking the WatchOS App as stand-alone.
  3. Specifying custom coordinates through the simulated Apple Watch on Simulator, Features -> Location -> Custom Location...
  4. Enabled Location Services on the simulated Apple Watch, and the location sharing setting for the app is set to When Shared

Update: I've tried running the app on a real Apple Watch and it still results in the same state.

Here's the LocationManager.swift file:

import CoreLocation

class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
    private let manager = CLLocationManager()
    @Published var location: CLLocation?
    
    override init() {
        super.init()
        manager.delegate = self
        manager.requestWhenInUseAuthorization()
        manager.startUpdatingLocation()
        
        print("LocationManager initialized and requesting location")
        
        switch manager.authorizationStatus {
        case .notDetermined:
            print("Location authorization status: notDetermined") // <--- It keeps returning this.
        case .restricted:
            print("Location authorization status: restricted")
        case .denied:
            print("Location authorization status: denied")
        case .authorizedAlways:
            print("Location authorization status: authorizedAlways")
        case .authorizedWhenInUse:
            print("Location authorization status: authorizedWhenInUse")
        @unknown default:
            print("Location authorization status: unknown")
        }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        if let firstLocation = locations.first {
            location = firstLocation
            manager.stopUpdatingLocation()
            print("Location updated: \(firstLocation)")
        }
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("Failed to get location: \(error.localizedDescription)")
    }
}



Solution

  • Ok it seems I was using the outdated method of updating Info.plist by creating a custom file. A recent update to XCode doesn't include this file when creating new projects. The file is now part of Project -> Target -> Info as mentioned here