Why dosen't CLLocationManager startUpdatingLocation fire in iOS8?
I am testing existing location functionality in iOS 8.0 using the simulators that ship with XCode 6. I cannot get CLLocationManager.startUpdatingLocation to trigger CLLocationManagerDelegate.locationManager: didUpdateLocations or CLLocationManagerDelegate.rorlocationManager: didFail .
I don't get the warning "My App" I like to use your current location "as on iOS 7.0.3. I used the Maps app to make sure my customized locations are set.
This works great in iOS 7.0.3 simulators.
Where am I going wrong?
iOS 8 requires you to call CLLocationManager.requestWhenInUseAuthorization or CLLocationManager.requestAlwaysAuthorization before making a call CLLocationManager.startUpdatingLocation
.
@interface MyViewController : UIViewController <CLLocationManagerDelegate>
@property CLLocationManager *locationManager;
@end
requestWhenInUseAuthorization
and requestAlwaysAuthorization
run asynchronously, so you want your CLLocationManager object not to get cleaned up before use can respond to the warning.
- (void) viewDidAppear:(BOOL)animated {
if ([CLLocationManager locationServicesEnabled]) {
self.locationManager = [CLLocationManager new];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
SEL selector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([self.locationManager respondsToSelector:selector]) {
[self.locationManager requestWhenInUseAuthorization];
} else {
[self.locationManager startUpdatingLocation];
}
} else {
...
}
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
[self.locationManager startUpdatingLocation];
} else if (status == kCLAuthorizationStatusAuthorized) {
// iOS 7 will redundantly call this line.
[self.locationManager startUpdatingLocation];
} else if (status > kCLAuthorizationStatusNotDetermined) {
...
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
...
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
...
}
When you implement CLLocationManagerDelegate
, you now need to implement the locationManager: didChangeAuthorizationStatus: method . Within this method, you can check if the user has granted permission to the app or not and act accordingly.
If [CLLocationManager authorizationStatus] = nil
, then locationManager:didChangeAuthorizationStatus:
will be called if authorizationStatus is set kCLAuthorizationStatusNotDetermined
and again when the user makes their choice in the alert dialog.
... Also add to Adrian Toman's answer
Don't forget to add NSLocationWhenInUseUsageDescription
or NSLocationAlwaysUsageDescription
to your application-Info.plist file.
Once you add the property to your plist, you also need to add a string value to it, this string value will be presented to the user when you ask for permission to use them.
-(void)statLocationManager
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; //whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
[locationManager requestWhenInUseAuthorization]; // Add this Line
}
And add the following to Info.plist
In addition to Adrian Toman, please answer if the WiFi device is only trying to disable / enable location settings.
I ran into this problem once when I called startUpdatingLocation
, locationManager:(CLLocationManager *)manager didUpdateLocations:
didn't get a response. Even though I followed all the instructions others provided here, I could not get this method running.
Finally, I realized that it is important that this is necessary for the locationManager delegate to "itself" (where you implemented the method locationManager:(CLLocationManager *)manager didUpdateLocations:
).
In the end, everything went well after that.