Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone GPS in background never resumes after pause

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];
like image 503
Lukasz Avatar asked Jul 05 '13 08:07

Lukasz


3 Answers

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.

like image 151
Lewis Gordon Avatar answered Sep 29 '22 13:09

Lewis Gordon


The apple doc is very weak on that topic. property pausesLocationUpdatesAutomatically allows apple to shut down GPS when apple thinks that the user does not need GPS.

Although not documented, it seems that setting this property leads to a stop of GPS in background mode.

Various posts describe the problems with that property: , e.g here:
iOS 6 CoreLocation does not work

In iOS 6 AutoPause doesn't work Stanislav Dvoychenko posts the reccomendation of Apple:

[Update - 4-Mar-2013]. I looked through the Apple's presentation for location changes in iOS6 and they suggest to use the region changes monitoring to "un-pause" once you get region changes event. Though this is not suitable for my scenarios as user might go/run/drive for a kilometer or two until such an event happens.

I suggest: set that property to false.

like image 42
AlexWien Avatar answered Sep 29 '22 13:09

AlexWien


If you can, use startMonitoringSignificantLocationChanges because then (Apple):

If you start this service and your application is subsequently terminated, the system automatically relaunches the application into the background if a new event arrives.

You can try combine this with finer-grained tracking once your app wakes up (e.g. user re-enters it).

like image 20
Terminus Avatar answered Sep 29 '22 13:09

Terminus