简体   繁体   中英

iOS application asking the user two times to turn on location services when trying to access location with the location services turned off

I am trying to fetch user location at one button click in my iOS application. I am using below code to initiate the location manager.

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

if ([CLLocationManager locationServicesEnabled]) {
    [locationManager startUpdatingLocation];
}
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;
}

When the location services is turned on and the user is clicking the button, then it's working fine and the location is fetching correctly.

But when the location services is off and user tries to click the button, as per my code he alert should display as above. But before it reaches else loop, iOS displays a system level pop-up like below.

在此处输入图片说明

On top of this system level alert view, my own alert view is getting displayed. This is pretty frustrating. The problem is that if the user cancels the system level pop-up instead of going to settings and tries to click the button, second time also same thing (two alerts scenario) is happening. However, if the user continues the same step, then the system level alert is not displayed now. That means the system level pop-up as displayed above is coming for 2 times only and after that nothing is happening. How to handle this scenario. Please help.

Usually one would write:

if ([CLLocationManager locationServicesEnabled])
{
    [locationManager startUpdatingLocation];
}

and let the iOS and the user sort it out. Merely calling [CLLocationManager locationServicesEnabled] will trigger the system dialog (for the first time). Following code is not tested but should work the way you want it to:

if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized)
{
    if ([CLLocationManager locationServicesEnabled])
    {
        [locationManager startUpdatingLocation];
    }
}
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;
}

EDIT:

The result of my last code would be that user would not even get prompted to enable location updates for your app. You might do the following:

if ([[NSUserDefaults standardUserDefaults] objectForKey:@"userWasAskedForLocationOnce"])
{
    if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized)
    {
        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;
    }
}
else
{
    [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES]
                                              forKey:@"userWasAskedForLocationOnce"];

    if ([CLLocationManager locationServicesEnabled]) //this will trigger the system prompt
    {
        [locationManager startUpdatingLocation];
    }
}

In this case user would get a system prompt to enable location updates for the first time. If they enable them, they would not get any prompts later on. If not, they would get your custom warning on subsequent launches - until they enable location updates in settings app.

Note 1: for testing this code you might want to delete your app from device from time to time (user-defaults are persistent until you delete your app)

Note 2: while this code should achieve the desired behavier it might be annoying to the user. Your UI should be arranged so that the user would know the locations services are disabled - alert is a bit overkill if this part of code is executed automatically at startup. If it is executed after a certain user's action (tapping a button) then it is ok to show alert.

I'm not sure about this. But whenever user accepts or denies the request to access their current location, a protocol callback locationManager:didChangeAuthorizationStatus: is called. Refer this for more details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM