-[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] error
Solution 1
It is due to both:
[self.locationManager startUpdatingLocation];
and
_MapName.showsUserLocation = YES;
You need to check if the user has given permission before you call these. Also make sure you turn off User Location in the MKMapKit on the storyboard (this one took me days to track down).
Do something like:
CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus];
if (authorizationStatus == kCLAuthorizationStatusAuthorized ||
authorizationStatus == kCLAuthorizationStatusAuthorizedAlways ||
authorizationStatus == kCLAuthorizationStatusAuthorizedWhenInUse) {
[self.locationManager startUpdatingLocation];
_MapName.showsUserLocation = YES;
}
Depending on your app you may not want to ask for the user's permission on launch since that is not recommended.
Solution 2
The error message is pretty literal. Don't call [self.locationManager startUpdatingLocation]
until you have authorization. Your [self.locationManager requestWhenInUseAuthorization]
, per the docs, is asynchronous.
When the current authorization status is
kCLAuthorizationStatusNotDetermined
, this method runs asynchronously and prompts the user to grant permission to the app to use location services.
This means you are both prompting for access as well as starting your scan at the same time.
Instead, try implementing -[CLLocationManagerDelegate locationManager:didChangeAuthorizationStatus:]
and starting your scan there after it's been determined that you have authorization.
Solution 3
On swift :
let locationManager: CLLocationManager = CLLocationManager()
let authorizationStatus = CLLocationManager.authorizationStatus()
override func viewDidLoad() {
super.viewDidLoad()
if(authorizationStatus == .AuthorizedWhenInUse || authorizationStatus == .AuthorizedAlways) {
locationManager.startUpdatingLocation()
}
else
{
locationManager.requestWhenInUseAuthorization()
}
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
}
Don't forget to add into Info.plist file these keys:
Solution 4
The keyword in the info file is ("In" instead of "Is"):
NSLocationWhenInUseUsageDescription
Max1980
Updated on July 09, 2022Comments
-
Max1980 almost 2 years
This is my code, showing both the alert and the blue dot for the current position on the map:
MapName.h
#import <UIKit/UIKit.h> #import <MapKit/MapKit.h> #import <CoreLocation/CoreLocation.h> @interface MapName : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate> @property (strong, nonatomic) IBOutlet MKMapView *MapName; @property (strong, nonatomic) CLLocationManager *locationManager; @end
MapName.m
- (void)viewDidLoad { [super viewDidLoad]; self.locationManager = [[CLLocationManager alloc]init]; self.locationManager.delegate = self; if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { [self.locationManager requestWhenInUseAuthorization]; } [self.locationManager startUpdatingLocation]; //Center the map [self gotoLocation]; //Show current position _MapName.showsUserLocation = YES; }
I've added the key
NSLocationWhenIsUseUsageDescription
as a string to the Info.plist. I'm still getting the same error on Xcode. -
Max1980 almost 10 yearsSorry, typing mistake. It is actually in instead of is. Working fine on iPhone 5s but getting the error and not showing the current location on Xcode6
-
Peter Pei Guo almost 10 yearsDebug and see whether you ever entered the if block. You are using ios 8 sdk?
-
Max1980 almost 10 yearsI am using ios 8 sdk indeed @PeterPeiGuo
-
Max1980 almost 10 yearsThanx for the answer @incanus. Where should implement the -[CLLocationManagerDelegate locationManager: didChangeAuthorizationStatus:] tho? I'm still doing it wrong I suppose
-
Max1980 almost 10 yearsI've put everything in the Delegate files and it's now working without any error on Xcode6, as in the answer example. Can't get it working only when I open a random map in my app: the alert shows right when I open the app for the first time. Is that the only possible way?
-
Max1980 over 9 yearsThanx Jerome!! I'll try it right away! I've seen that other apps are asking for permission right at lauch (eg. Skyscanner) so, since my app consists of 10 different maps, maybe it's better asking only once at the beginning. My iPad version has just been put up for distribution so I guess that's not a problem with Apple. I'm sorry it took you days to figure out the Storyboard user location option (I should have said I've used it). Therefore I really appreciate your effort!! Thanx a lot
-
jjmias over 9 years@Max1980 Yeah of course you can ask permission right at launch and depending on your app you might want to. I know since my app, Pinpoint - Stay together, even when you're apart!, has a sign up process we noticed a large increase in the user conversion rate (via Flurry) when we moved permission access to the appropriate parts of the app. For instance, we ask for location permission when the user is on the map, address book permission when the user goes to add a friend, etc. Apple won't reject you one way or another.
-
Joshua Powell over 9 yearsFor more detail on implementing this for less experienced iOS developers like myself, this article was extremely helpful. nevan.net/2014/09/core-location-manager-changes-in-ios-8
-
Douglas Frari over 9 yearsSee this explanation: nevan.net/2014/09/core-location-manager-changes-in-ios-8 (update to iOS 8 + Mapkit)
-
SteveCaine almost 9 yearsI got this warning even though I was waiting until the user had granted permission in the Settings app alert; the key was as Jerome Miastkowski (above) states: in the storyboard/xib file you have to clear the "Shows [_] User Location" checkbox for the Map View in Xcode's Attributes Inspector (4th pane in Xcode's Utilities panel on the right). It's cleared by default, but I had checked it rather than have to set this flag in code (self.mapView.showsUserLocation = YES;). Wrong choice for iOS 8, it seems, needs to be clear until you're granted access.