Short answer: You can't catch that notification. You can infer about the user choice and act consequently by using CLLocationManager
methods (the longer answer below).
Longer answer:
Firstly, welcome on Stack Overflow. Before kindly posing your question, and trying to be collaborative with people that are here to help, it's a good idea to search if somebody else previously posed the same question.
A brief search gave (just to mention some of them):
Now, let's try to summarize them all, starting from iOS docs:
If your app relies on location services to function properly, you should include the UIRequiredDeviceCapabilities key in the app’s Info.plist file. You use this key to specify the location services that must be present in order for your app to run. The App Store uses the information in this key from preventing users from downloading apps to devices that do not contain the listed features.
Important: If your app uses location services but is able to operate successfully without them, do not include the corresponding strings in the UIRequiredDeviceCapabilities key.
So, if your app really needs to access the user's position you should add location-services
and eventually gps
to UIRequiredDeviceCapabilities
.
Then, somewhere in your code - when needed, you have to check if the location services are enabled.
[CLLocationManager locationServicesEnabled]
they may be disallowed for three reasons:
- The user can disable location services in the Settings app.
- The user can deny location services for a specific app.
- The device might be in Airplane mode and unable to power up the necessary hardware.
You are interested in the second case: the user refused to allow your app to use the location services.
Again, from the docs:
Important: In addition to hardware not being available, the user has the option of denying an application’s access to location service data. During its initial uses by an application, the Core Location framework prompts the user to confirm that using the location service is acceptable. If the user denies the request, the CLLocationManager object reports an appropriate error to its delegate during future requests. You can also check the application’s explicit authorization status using the authorizationStatus method.
[CLLocationManager authorizationStatus]
That may return:
kCLAuthorizationStatusNotDetermined
if the user has not yet made a choice regarding whether this application can use location services.
kCLAuthorizationStatusRestricted
this application is not authorized to use location services. The user cannot change this application’s status, possibly due to active restrictions such as parental controls being in place.
kCLAuthorizationStatusDenied
The user explicitly denied the use of location services for this application or location services are currently disabled in Settings.
kCLAuthorizationStatusAuthorized
This application is authorized to use location services.
If[CLLocationManager locationServicesEnabled]
returns NO
and you attempt to start location services anyway (i.e. calling [locationManager startUpdatingLocation]
), the system prompts the user to confirm whether location services should be re-enabled. Given that location services are very likely to be disabled on purpose, the user might not welcome this prompt.
I suppose you know, and did all the previous steps (I'm only sure you checked the authorizationStatus
). You refused to show us the significant code of your app so I can only suppose the overall logic behind. Now you said your app hangs. This should be because you didn't catch the error properly? Catching the error is the way to re-prompt the user, if you wish.
After calling [locationManager startUpdatingLocation]
, if not authorized, your delegate should define a locationManager:didFailWithError: in order to catch the kCLErrorDenied.
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
You may show, at this point, a UIAlert
to insist asking the user to give you access to its position, or trigger a change in the UI or whatever you like.
Final notes
I hope you understand why I was asking for the code: the reason was to offer you an alternative solution instead of reply "You can't catch the 'Cancel' notification".
If this answer does not satisfy your question please elaborate why you need to catch the pushing of the "Cancel"/"Do not allow" button, so we can provide alternatives.
Clearly my advice is to not annoy people to death by continuously ask them for enabling location services if they don't want.
Post scriptum: Maybe that the answer looks pedantic and obvious in certain parts if not all to you, but we are here to provide answers also for future readers.