iOS: App is not asking user's permission while

2020-01-25 13:31发布

I am trying to fetch user location in my iOS app. I have included corelocation framework in my project first. Then on a button click I am invoking the core location api as below. When I am trying to install this in a device, the core location never asks the user permission. When I try to fetch the location on button click, I am getting kCLAuthorizationStatusNotDetermined as the authorisationStatus. Please help me in this. I have no clue what is happening.

- (IBAction)fetchLessAccurateLocation:(id)sender {
    [self.txtLocation setText:@""];

    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    locationManager.distanceFilter = 1000;

    if ([self shouldFetchUserLocation]) {
        [locationManager startUpdatingLocation];
    }
}

This is my shouldFetchUserLocation method:

-(BOOL)shouldFetchUserLocation{

    BOOL shouldFetchLocation= NO;

    if ([CLLocationManager locationServicesEnabled]) {
        switch ([CLLocationManager authorizationStatus]) {
            case kCLAuthorizationStatusAuthorized:
                shouldFetchLocation= YES;
                break;
            case kCLAuthorizationStatusDenied:
            {
                UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"Error" message:@"App level settings has been denied" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil];
                [alert show];
                alert= nil;
            }
                break;
            case kCLAuthorizationStatusNotDetermined:
            {
                UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"Error" message:@"The user is yet to provide the permission" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil];
                [alert show];
                alert= nil;
            }
                break;
            case kCLAuthorizationStatusRestricted:
            {
                UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"Error" message:@"The app is recstricted from using location services." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil];
                [alert show];
                alert= nil;
            }
                break;

            default:
                break;
        }
    }
    else{
        UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"Error" message:@"The location services seems to be disabled from the settings." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil];
        [alert show];
        alert= nil;
    }

    return shouldFetchLocation;
}

Here is my core location delegate method:

- (void)locationManager:(CLLocationManager *)manager
    didUpdateLocations:(NSArray *)locations __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0){

    NSLog(@"location fetched in delegate");

    CLLocation* location = [locations lastObject];
    NSDate* eventDate = location.timestamp;
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];

    if (abs(howRecent) < 15.0) {
        // If the event is recent, do something with it.
        NSLog(@"inside loop.... latitude %+.6f, longitude %+.6f\n",
              location.coordinate.latitude,
              location.coordinate.longitude);
    }
    NSLog(@"latitude %+.6f, longitude %+.6f\n",
          location.coordinate.latitude,
          location.coordinate.longitude);
    [self.txtLocation setText:[NSString stringWithFormat:@"\nlatitude: %+.6f \nlongitude:   %+.6f", location.coordinate.latitude, location.coordinate.longitude]];

    [locationManager stopUpdatingLocation];
    [locationManager stopMonitoringSignificantLocationChanges];

    if(locationManager!=nil){
        locationManager.delegate= nil;
        locationManager= nil;
    }
}

12条回答
相关推荐>>
2楼-- · 2020-01-25 14:13

You must have NSLocationWhenInUseUsageDescription added to you're info.plist. Its a bit weird but just add it as a string value with no text and then when you want location start with:

CLLocationManager * locationManager = [[CLLocationManager alloc] init];

[locationManager requestWhenInUseAuthorization];
查看更多
姐就是有狂的资本
3楼-- · 2020-01-25 14:14

When prompting for location you must not forget those things (iOS 8+):

  1. Add this flag on your info.plist of the app : NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription depend if you want always access to location or only when app is in usage (the second is recommended if you don't need always access). This is the most important because it is new and weird.
  2. If you request always permission don't forget to add location updates as background mode on your target capabilities
  3. Make sure you are asking for the right permission when initialise location manager:

    -(void)initLocationManager{
        locationManager = [[CLLocationManager alloc] init];
        locationManager.delegate=self;
    
        [locationManager requestAlwaysAuthorization]; // HERE ASK FOR THE RELEVANT
    }
    

For testing in simulator I suggest you to "Reset all content and settings" from it's options. That's the only way to get the exact same experience a new user of the app would get.

查看更多
爷的心禁止访问
4楼-- · 2020-01-25 14:14

I ran into this issue, implemented all of the things necessary including the pList keys and my app was still not requesting location.

Turns out the issue was that the locationManager variable cannot be a local - it needs to be an instance variable.

So instead of

-(void) updateLocation {
   CLLocationManager *locationManager = ...
}

it needs to be:

CLLocationManager *locationManager;

-(void) updateLocation {
  self.locationManager = ...
}
查看更多
我命由我不由天
5楼-- · 2020-01-25 14:15

I had a similar issue, but caused for a different reason. Adding it here in case it could help anyone else.

I stopped receiving the asking for authorization message, and since it was working before the requirements described in the other answers were already fulfilled: the key in the plist, checking authorization status and then asking for permission in ios8+.

In my case the issue was related to "Access Guide" mode. This is an app for a kiosk, and it only starts to range beacons once "Access Guide" is activated. But it seems that the ask for authorization messages aren't sent while in this mode. I could fix it just moving the ask for authorization procedure to the DidLoad of the first displayed view.

The same thing happens with the request to use the camera.

查看更多
萌系小妹纸
6楼-- · 2020-01-25 14:24

If you face this issue on iOS8, please use :requestWhenInUseAuthorization.

查看更多
ら.Afraid
7楼-- · 2020-01-25 14:27

In iOS 8 you need to do two extra things to get location working: Add a key to your Info.plist and request authorization from the location manager asking it to start. There are two Info.plist keys for the new location authorization. One or both of these keys is required. If neither of the keys are there, you can call startUpdatingLocation but the location manager won’t actually start. It won’t send a failure message to the delegate either (since it never started, it can’t fail). It will also fail if you add one or both of the keys but forget to explicitly request authorization.

So the first thing you need to do is to add one or both of the following keys to your Info.plist file:

NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription

Both of these keys take a string which is a description of why you need location services. You can enter a string like “Location is required to find out where you are” which, as in iOS 7, can be localized in the InfoPlist.strings file.

Next you need to request authorization for the corresponding location method, WhenInUse or Background. Use one of these calls:

[self.locationManager requestWhenInUseAuthorization]
[self.locationManager requestAlwaysAuthorization]

For more information.

查看更多
登录 后发表回答