Location Services Permission reset upon app upgrade on iOS - ios

Summary:
Is it possible for iOS/App Store to reset an app's Location Service permission on app upgrade?
Detailed:
In our recent app upgrade, we believe quite a few of users that had previously granted our app "Always" Location Services permission as a result of enabling certain features were prompted with a While in Use Location Services prompt on first launch of the new version of our app. Since there is no context around this permission prompt, many of our users likely selected Don't Allow at this time.
AFAIK, it is not possible for our app to reset the user's permission settings via code. Is anyone aware of a certain version of iOS and/or device combination that would lead to this behaviour upon app upgrade?
The only time when our app would prompt users for Location Services permissions is if the authorizationStatus is set to kCLAuthorizationStatusNotDetermined. Otherwise we would start to request for location updates.
Here's a snippet of our app's launch code:
CLLocationManager *lmFollowMe = [[CLLocationManager alloc] init];
[lmFollowMe setDesiredAccuracy:kCLLocationAccuracyKilometer];
[lmFollowMe setDistanceFilter:1000];
[lmFollowMe setDelegate:self];
if ([lmFollowMe respondsToSelector:#selector(setAllowsBackgroundLocationUpdates:)]) {
[lmFollowMe setAllowsBackgroundLocationUpdates:NO];
}
[self setFollowMeLocationManager:lmFollowMe];
...
if ([CLLocationManager locationServicesEnabled] == YES) {
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusDenied) {
...
} else if (status == kCLAuthorizationStatusRestricted) {
...
} else if (status == kCLAuthorizationStatusNotDetermined) {
if ([self followMeStarted] == NO) {
[self setFollowMeStarted:YES];
[[self followMeLocationManager] requestWhenInUseAuthorization];
}
} else {
[[self followMeLocationManager] startUpdatingLocation];
}
...
Thanks!

You can not change location permission through code, but if user denied location permission then you can show alert for ask location permission with 'Setting' & 'Cancel' buttons.
If user click on 'Setting' then you can redirect user to application's setting page to update location permission by following code.
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
Thanks.

Related

CLLocationManager permissions

I'm working on permissions for location, problem is next:
User turned off location services from privacy and installed the app. I have line of code that is asking to enable location services: if (![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied)... and this is working pretty fine. Problem is that app don't ask for allowing app to use location, then it asks the second time. Code for asking for permission:
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
NOTE: Everything works fine if locations services enabled, it asks for approval first time.
EDIT: Full code for permissions:
-(void)setupPermissions
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if (![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
}
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
}
Your code makes no sense. You have this:
if (something) {
}
if (somethingelse) {
[self.locationManager requestWhenInUseAuthorization];
}
So you have one if that is empty, and another if that always runs regardless of what the first if does. Perhaps you meant to use else if for the second condition?
(And keep in mind that, as you've already been told, calling requestWhenInUseAuthorization is pointless unless the status is NotDetermined.)
The only time you can get iOS to request user permissions is when the authorization status is NotDetermined.
If a user has denied your app, the only way you can get them to be prompted again is to uninstall the app, or reset privacy on the device.
The easiest approach would be to provide an alert controller with a link to settings so that they can turn it on themselves.
Here is a link that shows the process for doing that.

CLLocationManager Disable use of the location by the application

I have a switch for the user to disable / enable the use of the location by the application. I am having two problems.
1 - When the native ios popup appears to ask if he wants to allow the use of location, and he says no, the promixa time I request permission popup is no longer displayed, and the only way to enable the user permission It is in the iPhone settings.
2 - If the user has allowed the use of the location, but then at some point you want to disable the switch is present in the application, it can not.
below is the code I am using.
-(IBAction)avancar:(id)sender{
if (locationManager == nil) {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
}
if (switchPermissao.isOn) {
[locationManager startUpdatingLocation];
if(IS_OS_8_OR_LATER) {
[locationManager requestWhenInUseAuthorization];
[locationManager requestAlwaysAuthorization];
}
}else{
[locationManager stopUpdatingLocation];
[self performSegueWithIdentifier:#"tela2" sender:self];
}
}
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusDenied) {
[switchPermissao setOn:NO animated:YES];
}
else if (status == kCLAuthorizationStatusAuthorizedAlways
|| status == kCLAuthorizationStatusAuthorizedWhenInUse) {
[switchPermissao setOn:YES animated:YES];
}
[self performSegueWithIdentifier:#"tela2" sender:self];
}
RE: 1) The OS will only show the permission dialog once. After the user makes their selection, the OS will not show the permission dialog again even if your code asks for permission again. So, you must handle this with your code to present the user with a custom dialog/alert. To do this, use the CLLocationManager authorizationStatus to get the current status. Only when this status is kCLAuthorizationStatusNotDetermined will the OS show the system permission dialog. In all other cases you need to handle the permission with a custom dialog.
RE: 2) Your app cannot change the status of location services, this can only be changed by the user under the system Setting. To handle this you can present a custom dialog that will open the system Settings for your app so the user can change the status. You can use UIApplicationOpenSettingsURLString, in iOS 8, to open the system Settings for your app.

Location services behaving weird

I want to detect location services are enabled or not and based on that I want to enable or disable the button in my app. For that I have written
if([CLLocationManager locationServicesEnabled])
// Enable button
else
// Disbale button
But, I found a strange behaviour with this method. From Settings,
1) If I turns location services OFF, for all apps than above method returns NO.(As expected)
2) If I turns locationServices ON, But OFF for my particualr app, than it returns YES.
Is this the correct behaviour. If yes, than is there any other method to find whether location services are enabled or disbaled at app level. Any thoughts.
As you are using locationServicesEnabled method to find whether the location services are enabled for your app or not, I would like to clear that locationServicesEnabled detect whether the location services are enabled for the device or not. It does not check for particular application.
From the Apple Docs It returns a Boolean value indicating whether location services are enabled on the device
You may use locationManager:didFailWithError: to detect the location services for the particular app
From the Apple documentation
If the user denies your application’s use of the location service, this method reports a kCLErrorDenied error. Upon receiving such an error, you should stop the location service.
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
if ([[error domain] isEqualToString: kCLErrorDomain] && [error code] == kCLErrorDenied) {
// Location Services are denied.
}
}
You should check the authorizationStatus property of CLLocationManager to see whether your application is authorised to access location information -
if ([CLLocationManager locationServicesEnabled] && (CLLoctionManager.authorizationStatus == kCLAuthorizationStatusAuthorized)) {
// Enable button
}
else {
// Disable button
}
use this
+(BOOL)checkLocationService {
if (![CLLocationManager locationServicesEnabled])
return NO; //location service disabled
else if(kCLAuthorizationStatusAuthorized!=[CLLocationManager authorizationStatus])
return NO; //app's location service disabled
return YES;
}

How to Revoke / Cancel / Unregister "Location Services" inside of the iOS app

Is it possible to revoke the Location Services within an iPhone app?
I would like to change the [CLLocationManager authorizationStatus] from kCLAuthorizationStatusAuthorized to kCLAuthorizationStatusDenied or kCLAuthorizationStatusRestricted, like we can do with the Notifications status, calling: [[UIApplication sharedApplication] unregisterForRemoteNotifications].
+[CLLocationManager authorizationStatus] is a read-only method. That is something a user sets, that is beyond the control of your app.
What you should be doing is stopping the CLLocationManager from updating if you are finished with it. Create a property or iVar for location manager, then when you no longer need updates just call:
[myLocationManager stopUpdatingLocation];
You can also check the authorisation status before starting location updates like so:
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
// start updating location
}

CLLocationManager suddenly not asking for permission and not showing up in Privacy tab

In my app, I created a class that deals with location services. For example, I start location services like this:
- (void)startLocationServices{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
if([CLLocationManager locationServicesEnabled] == YES && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized)
{
[locationManager startUpdatingLocation];
}
else {
//NSLog(#"Location services is not enabled");
//[self locationDeniedPolicy];
}}
I make my viewcontrollers subclasses of this location class if I ever needed the location of the user.
The location class itself is a subclass of UIViewController.
This used to work fine. When the user navigates to a view controller that is a subclass of this location class, it would ask for location permission for the first time. Also, the app would be listed in the privacy tab of the Settings app.
I suddenly realized that the app is no longer showing up in the Privacy tab and is not also asking for location permission. It does not use the location services at all! I have no idea why this happened? Was it an update to xcode that changed things? No idea!
Any clue?

Resources