Reputation: 2992
According to the new changes I did update my code for the CLLocationManager
as well as added the NSLocationAlwaysUsageDescription
and NSLocationWhenInUseUsageDescription
key.
manager = [[CLLocationManager alloc] init];
manager.delegate = self;
manager.distanceFilter = kCLDistanceFilterNone;
manager.desiredAccuracy = kCLLocationAccuracyBest;
NSLog(@"%d",[CLLocationManager authorizationStatus]); // always output 0
// check if iOS 8
if ([manager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[manager requestAlwaysAuthorization];
}
[manager startUpdatingLocation];
Problem: the app doesn't request any more location management i.e. I can not find it under Settings -> Privacy -> Location Service and the locationManager:(CLLocationManager *)aManager didUpdateLocations:(NSArray *)locations
still is not triggered. Is there anything I am missing?
Edit: [CLLocationManager authorizationStatus]
is 0
i.e. kCLAuthorizationStatusNotDetermined
, hence I would assume that the problem is with [manager requestAlwaysAuthorization]
for reference this is my localised InfoPlist.strings
(maybe it cause the problem):
<key>NSLocationAlwaysUsageDescription</key>
<string>Text</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Text</string>
The call [manager requestAlwaysAuthorization]
is executed, locationManager:didFailWithError:
is implemented but is not triggered.
Tried with a different Plist, but still no success:
<key>NSLocationWhenInUseUsageDescription</key>
<string>Text</string>
<key>NSLocationUsageDescription</key>
<string>Text</string>
One more thing to note: my Plist are localised, can this be an issue?
Upvotes: 2
Views: 2721
Reputation: 664
You're saying your not seeing the alert requesting authorization at all, confirmed the delegate method didChangeAuthorizationStatus is not firing, and you went to the Settings app -> privacy -> location service and the program was not listed there and not listed as no to location services. Because of this it sounds like a plist issue.
In terms of the info.plist, I did it in Xcode( a little simpler for me without language localization) going to info tab and inputing 'NSLocationWhenInUseUsageDescription' ( and you'd also want to add 'NSLocationAlwaysUsageDescription') and inputting the description. It is working if you see the popup ( which is asynchronous). If it can't find your description for why you want location service it wont show the alert to the user(which has to display your description) which of course means you won't get authorization.
From the apple documentation on infoplist.strings https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/InfoPlistKeyReference.pdf :
"The routines that look up key values in the Info.plist file take the user’s language preferences into account and return the localized version of the key (from the appropriate InfoPlist.strings file) when one exists. If a localized version of a key does not exist, the routines return the value stored in the Info.plist file."
So these keys do have to be added to the info.plist (which can be done in xcode info tab of the project) and only if it finds a file for another language will it try to use your localized values.
I would go into the project, select the target, and then in the Info tab next to build settings, make sure you see the plist key NSLocationAlwaysUsageDescription has been added and a description. When adding the plist keys I did not find choosing from the drop down menu, and there was a choice, Privacy - Location Usage Description, worked for me. Just copy in that word 'NSLocationAlwaysUsageDescription' and add a description. You can also do the when in use. It has to be there for this to work. It needs to find the global before it will look for a local plist key. For debugging you can delete the keys from the localized plists to start and verify it works with the global plist value. Or rather: "remove the localised constants from plist and have only the global one" There is no reason with only global plist values it should not work then. You need only add localized values later, if you have language needs for multiple translations, once you confirm the global works. The order should be to get the global only working first as the best practice because with that step checked off you know then if the first part is working. New items you don't need to translate the main plist description can be added and not localized.
If you want a second language note this example from https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html.
The format of info.plist is:
<key>CFBundleDisplayName</key>
<string>TextEdit</string>
But if you have a French infoPlist.strings the format is:
CFBundleDisplayName = "TextEdit";
Upvotes: 4
Reputation: 61
Are you maintaining a strong reference to your CLLocationManager
object ? According to Apple doc it is mandatory when requesting permission :
https://developer.apple.com/Library/mac/documentation/CoreLocation/Reference/CLLocationManager_Class/index.html#//apple_ref/doc/uid/TP40007125-CH3-SW72
Upvotes: 0
Reputation: 1297
Maybe you have your plist different, here is what I use in my app and works ok, we are using the WhenInUse option:
plist:
<key>NSLocationWhenInUseUsageDescription</key>
<string>Use location services only when the app is in use</string>
Location manager initialization:
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
Location Manager delegate methods:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
self.coordinate = newLocation.coordinate;
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
NSLog(@"%@", error.description);
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse) {
[self startUpdatingLocation];
[self startMonitoringSignificantLocationChanges];
} else {
[self setDefaultCoordinate];
}
} else {
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
[self startUpdatingLocation];
[self startMonitoringSignificantLocationChanges];
} else {
[self setDefaultCoordinate];
}
}
}
As soon as [self.locationManager requestWhenInUseAuthorization];
is called, I get the authorization alert, it works in devices and simulator.
Also, you said your plist is localized, do you have localization key in all of them?
Upvotes: 0
Reputation: 130
If you run on Simulator some time simulator can not take custom location. To solve this problem first select Debug -> Location -> Apple then select Debug -> Location -> Custom Location. It will help you.
Upvotes: 0