iPhone GPS in background never resumes after pause

Lukasz picture Lukasz · Jul 5, 2013 · Viewed 9.8k times · Source

My application needs to track user location changes in the background and works fine as long as user moves around. When user stops and CLLocationManager pauses after 10-20 minutes or so. It is indicated by this notification:

-(void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager{}

And this is also fine with me. Great, I save some battery, etc.

The problem is that CLLocationManager never wakes up when user starts moving again and following delegate methods are never fired until I put my application to the foreground (gets active):

//Never called back after CLLocationManager pauses:
-(void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager{}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{}

Why is locationManagerDidResumeLocationUpdates never called after device starts moving again? Shouldn't GPS resume automatically also (since was paused automatically)? Is there a way to resume GPS without user's interaction?

Application has following declared in Info.plist file:

enter image description here

And my CLLocationManager settings are:

locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager setActivityType:CLActivityTypeFitness];
//I WANT pauses to save some battery, etc... That is why following line is commented out (default)
 //[locationManager setPausesLocationUpdatesAutomatically:NO];
 locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
 locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
 [locationManager startUpdatingLocation];

Answer

Lewis Gordon picture Lewis Gordon · Jul 15, 2013

If you search for pausesLocationUpdatesAutomatically on the Apple forums you'll find a recent question along similar lines which has had a response from an Apple developer. I won't repost it directly here since it is a private forum, but the gist is that the location pausing is for instances when the user forgets that they have got a location aware app running and have stopped using it. By pausing updates their battery won't be drained as quickly. Unfortunately it's not possible to know whether new movement is them resuming the activity or doing something else, so updates don't resume until the app comes back to the foreground. Their suggestion is to catch the pause call and get the user's attention somehow to get them to open the app if they still want updates.

EDIT:

From Apple's own documentation of pausesLocationUpdatesAutomatically. They suggest:

After a pause occurs, it is your responsibility to restart location services again when you determine that they are needed. Core Location calls the locationManagerDidPauseLocationUpdates(_:) method of your location manager's delegate to let you know that a pause has occurred. In that method, you might configure a local notification whose trigger is of type UNLocationNotificationTrigger and is set to notify when the user exits the current region. The message for the local notification should prompt the user to launch your app again so that it can resume updates.