-[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] error

36,981

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:

enter image description here

Solution 4

The keyword in the info file is ("In" instead of "Is"):

NSLocationWhenInUseUsageDescription
Share:
36,981
Max1980
Author by

Max1980

Updated on July 09, 2022

Comments

  • Max1980
    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
    Max1980 almost 10 years
    Sorry, 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
    Peter Pei Guo almost 10 years
    Debug and see whether you ever entered the if block. You are using ios 8 sdk?
  • Max1980
    Max1980 almost 10 years
    I am using ios 8 sdk indeed @PeterPeiGuo
  • Max1980
    Max1980 almost 10 years
    Thanx for the answer @incanus. Where should implement the -[CLLocationManagerDelegate locationManager: didChangeAuthorizationStatus:] tho? I'm still doing it wrong I suppose
  • Max1980
    Max1980 almost 10 years
    I'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
    Max1980 over 9 years
    Thanx 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
    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
    Joshua Powell over 9 years
    For 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
    Douglas Frari over 9 years
    See this explanation: nevan.net/2014/09/core-location-manager-changes-in-ios-8 (update to iOS 8 + Mapkit)
  • SteveCaine
    SteveCaine almost 9 years
    I 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.