I am trying to get the user's current location using the following code, but it doesn't work. I have added both NSLocationWhenInUseUsageDescription
key and NSLocationAlwaysUsageDescription
key to my Info.plist
file.
Below is the code
var locationManager = CLLocationManager();
override func viewDidLoad() {
super.viewDidLoad()
startReceivingLocationChanges();
}
func startReceivingLocationChanges() {
let authorizationStatus = CLLocationManager.authorizationStatus()
if authorizationStatus != .authorizedAlways {
// User has not authorized access to location information.
print("not authorized");
return
}
if !CLLocationManager.locationServicesEnabled() {
print("not enabled");
return
}
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.distanceFilter = 100.0 // In meters.
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let lastLocation = locations.last!
print(lastLocation)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error);
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
print("inside didChangeAuthorization ");
}
i have read through the apple documents and above is the code that apple suggests. What am i missing here ? Any kind of help is really appreciated. Thanks
EDIT for some reason requestAlwaysAuthorization() is not available. see the screenshot below
requestAlwaysAuthorization()
isn't available because you're working in macOS, and the documentation shows that that method is only available in iOS and watchOS. See the list of SDK's on the right side of the page, near the top:Just make sure the location manager is authorized to find user's location. You should call
locationManager.requestAlwaysAuthorization()
before calling for location updates.Also check that your simulator debugging simulates the user location.
The issue here is that on macOS prior to 10.15 one does not explicitly call to request location access like one does on iOS. The user permission prompt is automatically presented when you call
startUpdatingLocation()
.In your code above execution never gets to that call because your function
startReceivingLocationChanges
always returns in the first statement where it checks current status (which will be "status not yet determined" most likely). So it never gets to thestartUpdatingLocation()
call further down in that function and thus never prompts the user to allow location reporting.In macOS 10.15
requestAlwaysAuthorization()
is available, but doesn't seem to be required if you just need to use location when your app is in use.Also, on macOS
.authorized
seems to be preferred over.authorizedAlways
(documented to be synonyms), though with the addition of therequestAlwaysAuthorization()
function in 10.15 they may change this (though the documentation has not been updated to indicate this having happened at the time of this answer).If you are not calling
requestAlwayAuthorization()
then it seems that only theNSLocationWhenInUseUsageDescription
info.plist key is needed.Additionally, it is necessary to set the "Location" checkbox in "Hardened Runtime" under "Signing & Capabilities" for the macOS application project. This is required on Xcode 11.2.1 on macOS 10.14.6 where I'm testing this. Older setups, or ones not adopting the hardened runtime (now the default), may have to set this in a different location in the project build settings.
Here's the source for a NSViewController subclass that checks for location manager and the current location successfully in Xcode 11.2.1 on macOS 10.14.6:
This works for me on macOS if I say yes to the "enable location services" prompt when I launch the app the first time.
Console output is (slightly obfuscated):
Steps to make this sample:
NSLocationWhenInUseUsageDescription
key to the info.plist