29

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];
mfaani
  • 33,269
  • 19
  • 164
  • 293
Lukasz
  • 19,816
  • 17
  • 83
  • 139
  • when returning to foreground, do you receive all the location events since shut down of gps delivery, or are they all lost? – AlexWien Jul 07 '13 at 08:46
  • Yes, when I return to the foreground all location updates start again. – Lukasz Jul 07 '13 at 18:31
  • the question was, if you got the locations between background and foregeound all at once. (you get a list of locations) – AlexWien Jul 07 '13 at 19:05
  • Och sorry - it looks like I get only 1 newest location (loaton at the moment when I swith to foreground). All others seems to be lost. – Lukasz Jul 07 '13 at 22:02
  • so then property pausesLocationUpdatesAutomaticcaly probably is the cause. you could try to set it to false when you enter background, and to true when you enter foreground – AlexWien Jul 08 '13 at 07:38
  • 4
    It is not the solution. I want to pause to work. Documentation states that resume should be called when users starts moving again. I want to know why it doesnøt. – Lukasz Jul 08 '13 at 07:47
  • the docu is not sufficient. i have corectly answered that the property is the cause. why apple has implemented this way is not documented. you could file a bug to apple. the docu does give you any hard facts when GPS is stopped. – AlexWien Jul 08 '13 at 08:10
  • I updated with links to SO, and Apple recommendation – AlexWien Jul 08 '13 at 08:41
  • In my environmet SDK ios6, target ios5, device ios 6.1@iphone4 pausesLocationUpdatesAutomatically is NO by default. Consider upvoting and accepting, probably you will not get a better answer. – AlexWien Jul 10 '13 at 17:42
  • 1
    My question was not about what pausesLocationUpdatesAutomatically property does. I understand this function. My question is mainly about resuming GPS. I need to know exactly if pause is definite or if GPS may be resumed automatically. I will of course accept the answer when I conclude my research on this and it proves you are right. – Lukasz Jul 10 '13 at 19:02
  • 1. I'm assuming wrapping the `startUpdateLocations` inside a backgroundTask doesn't help right? 2. Can you create a small region and then from the `DidExitRegion` start do `startUpdateLocations` again? – mfaani Jul 25 '17 at 15:40

3 Answers3

31

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.

mfaani
  • 33,269
  • 19
  • 164
  • 293
Lewis Gordon
  • 1,711
  • 14
  • 19
  • 6
    I tried looking for the forum discussion you allude to, but I couldn't find it. Would you mind posting a link? Thanks! – Steven Wexler Jun 19 '15 at 20:15
  • I would also be interested in the discussion. – lostintranslation Jul 02 '15 at 04:23
  • Some here. Did anyone find the discussion on the Apple forums about this? – Stephen Johnson Jan 04 '17 at 17:19
  • 3
    No jokes. It should have been called: `locationManagerWasKilledNOTPausedAndAppIsToBeSuspendedRIGHTNowSoYouHaveNoWayOfContinuingLiveUpdatesYouMustUseOtherOptions`. Implied in pausing is ability to resume. Here you **don't** have that ability. – mfaani Jul 25 '17 at 15:15
  • From what I've learned you can only restart if you were paused while you were in **foreground**. If you're in background and your location was paused then the app is **suspended**. After that the only way to start locationTracking again is to launch app again and then start locationTracking – mfaani Sep 29 '18 at 21:07
3

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.

Community
  • 1
  • 1
AlexWien
  • 28,470
  • 6
  • 53
  • 83
  • 2
    Is this the only solution? I feels so strange Apple designed theirs delegate in such non-symmetric way. Delgate's pause callback should be balanced by resume without introducing any extra settings. Maybe activityType may have some affect on this. – Lukasz Jul 08 '13 at 09:50
  • 2
    Probably it's more a technical reason, not a delegate design. if GPS is off you cannot realiably detect moveement: Either by GSM cell change: (1000m acuracy) or wifi (if you have some wifi spots nearby). Or with accelration sensor: could work for vehicles when device is hard mounted. But will not work for pedestrians. If you move on your seat while sitting in the restaurant, this is difficult to distinguish to fitness relevant moving. – AlexWien Jul 08 '13 at 12:33
  • Do you mean doing `startUpdateLocations` inside the `locationmanagerdidpauselocationupdates` callback would just fail silently? – mfaani Jul 24 '17 at 12:45
1

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).

Terminus
  • 925
  • 10
  • 23