3

I'm an test an existing locations functionality in iOS 8.0 using the simulators that come with XCode 6. I am unable to get CLLocationManager.startUpdatingLocation to trigger either CLLocationManagerDelegate.locationManager:didUpdateLocations or CLLocationManagerDelegate.locationManager:didFailWithError.

I don't get the ""My App" Would Like to Use Your Current Location" alert, like I do on the iOS 7.0.3 simulators. I have used the Maps app to verify that the simulated locations set.

This works fine in the iOS 7.0.3 simulators.

Where I'm I going wrong?

Adrian Toman
  • 11,316
  • 5
  • 48
  • 62

5 Answers5

9

iOS 8 requires that you call either CLLocationManager.requestWhenInUseAuthorization or CLLocationManager.requestAlwaysAuthorization before you call CLLocationManager.startUpdatingLocation.

@interface MyViewController : UIViewController <CLLocationManagerDelegate>

@property CLLocationManager *locationManager;

@end

requestWhenInUseAuthorization and requestAlwaysAuthorization run asynchronously so you want to make sure that your CLLocationManager object isn't cleaned-up before the use can respond to the alert.

- (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 as well. Within this method you can check if the user has given the app permission or not, and act accordingly.

If [CLLocationManager authorizationStatus] = nil then locationManager:didChangeAuthorizationStatus: will be called when the authorizationStatus is set to kCLAuthorizationStatusNotDetermined and again when the user make their selection from the alert dialog.

Adrian Toman
  • 11,316
  • 5
  • 48
  • 62
  • Adrian do you know how to display the status bar message, when the app is in the background. Google maps does it when the navigation is turned on. “Google Maps is using your Location” – Tomasz Dubik Oct 13 '14 at 21:39
2

...Also to add to Adrian Toman's answer

Do not forget to add NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription to you 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 are asking for their permission to use their location.

MiMo
  • 4,905
  • 3
  • 22
  • 23
2
-(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 following in Info.plist

enter image description here

neo D1
  • 1,710
  • 13
  • 15
0

In addition to Adrian Toman's answer if the device is WiFi only try to disable/enable location settings.

Niko Zarzani
  • 1,372
  • 2
  • 15
  • 28
0

I once encountered this problem, when I called startUpdatingLocation, locationManager:(CLLocationManager *)manager didUpdateLocations: did not get response. Even if I followed all instruction which others provided here, I couldn't get this method triggered.

Finally I realized one thing critical to it was it needed set the delegate of the locationManager to "self" (where you implemented the method locationManager:(CLLocationManager *)manager didUpdateLocations:).

Eventually, everything ran well after that.