CLLocationManager sometimes stops updating while app is in background
Asked Answered
F

5

5

I have an app which uses CLLocationManager to track the user's route, drawing dots along the path taken. The app runs in the background using Required background modes > App registers for location updates.

As I understand, anything that happens in the background needs to be called from locationManager:didUpdateToLocation:fromLocation as this is the method that gets called with each location update.

The problem I'm having is that sometimes this stops getting called. It seems to happen when the user's location does not change much within the space of maybe 15 minutes or so. As far as I can tell, calls to locationManager:didUpdateToLocation:fromLocation just stop, presumably to save the battery. Unfortunately, it doesn't resume again when you're back on the move.

I presume there's no way to override this behaviour, so I would like to use Notification Centre to inform the user that the app is no longer recording the route. The problem is, how can the app know that this has happened? If locationManager:didUpdateToLocation:fromLocation is not called, I can't fire my notification. If it is being called, the notification should not fire.

Is there some kind of system notification that says location updates will cease?

I'm finding it quite hard to debug this as I can't take my Mac everywhere when I'm out and about testing the location on the device (there's only so much you can do in the simulator). Any tips for debugging would also be much appreciated!

Frantz answered 4/1, 2013 at 13:27 Comment(8)
Which iOS version are you testing this against?Marentic
The app supports iOS 5.1 and above. My devices are running iOS 6, so when I'm out and about, that what's being used.Frantz
interesting, but this might be an iOS bug. You should test against an app that uses navigation and see if the same problem occurs there. Are you sure you are not stopping location updates in your code anywhere?Marentic
I have a BOOL called isRecording, which needs to be YES for the dots to be drawn. Is it possible this BOOL is getting released by iOS?Frantz
It is a possibility. You can test it locally in Xcode. leave the app running for more than 15 minutes and then manually stop the code and see what's going on.Marentic
I've now tested this. The BOOL isRecording remains set to YES, even when the location updates have ceased.Frantz
@Frantz Can you please post your code as an answer here. I am running into same problemDispraise
yourLocationManager.pausesLocationUpdatesAutomatically = NOFrantz
M
8

If you haven't found the answer, I think it is because of a new attribute added to CLLocationManager called pausesLocationUpdatesAutomatically. The attribute defaults to YES, and its behaviour is exactly as you describe. Try setting it to NO and I think it will fix your problem.

Munitions answered 22/2, 2013 at 18:41 Comment(0)
G
5

Starting in iOS9, make sure you're also setting this property on your location manager:

[locationManager setAllowsBackgroundLocationUpdates:YES]

Goddess answered 5/4, 2016 at 20:36 Comment(0)
C
1

There's a delegate for location update did Fail

-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error

There are a few kinds of errors: kCLErrorDenied kCLErrorNetwork Add code here to handle them in the delegate method above not updating location, perhaps a UIAlertView to tell the user.

Personally, I call [locationManager stopUpdatingLocation]; on any error then restart it with an error message depending on the reason for the failure.

ALSO re background, check code in your appDelegate:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    [self saveContext];
    if ([CLLocationManager significantLocationChangeMonitoringAvailable]) {
        // Stop normal location updates and start significant location change updates for battery efficiency.
        [self.locationHandler.locationManager stopUpdatingLocation];
        [self.locationHandler.locationManager startMonitoringSignificantLocationChanges];
    }
    else {
        NSLog(@"Significant location change monitoring is not available.");
    }
}

LASTLY re: testing. You can simulate some errors in location by changing the location movement in the simulator. For example, going from running to driving will cause an error. Going from running to a single specific custom location will cause an error. They should all appear in the delegate method for locationManager above.

Cheesecake answered 4/1, 2013 at 15:50 Comment(11)
Thanks for your answer. I'm going to explore locationManager:didFailWithError further and see if I can make this work.Frantz
Added [self.locationManager stopUpdatingLocation]; [self.locationManager startUpdatingLocation]; to locationManager:didFailWithError: I can simulate an error in the way you describe, but it doesn't reproduce the bug. To reproduce the bug, I have to run the app on my device, go somewhere, stay in the same place for a while, then go somewhere else. Today it stopped recording the route after I'd been in the same place for a while, but started recording again when I opened the app. Still struggling to figure out how I can either keep it going or notify the user that recording has stopped.Frantz
Consider adding code to "WillResignActive" in the appDelegate. Something similar to what I have in "DidEnterBackground" above. Maybe add your start and stop here?Cheesecake
I can't find anything to indicate when or why the updates are not happening. The app is happily running in the background but if you stay around the same location for 10 minutes, it stops updating and doesn't start again unless you bring the app to the foreground. I've found a solution to the problem of how to notify the user that this is happening.Frantz
iOS could be deallocating your memory.Cheesecake
It's not releasing my BOOL, isRecording (see comments below the question). Maybe it's releasing other things, but whatever it's doing doesn't seem to be documented so I'm shooting in the dark trying to figure it out.Frantz
not your BOOL. I'm wondering if the entire app is getting released.Cheesecake
Consider using NSTimer to awake your location tracking after fifteen minutes on DidEnterBackground.Cheesecake
The entire app isn't getting released. When I relaunch it, even after it has stopped updating the location, the view I left it at is the one that comes up, and it immediately starts updating the location again. It basically acts as if it had never been out of the foreground - except that a bunch of location updates are missing!Frantz
Turns out the reason for the problem is documented. pausesLocationUpdatesAutomatically is a new property of CLLocationManager introduced in iOS 6. It needs to be set to NO, as described here: https://mcmap.net/q/131439/-ios-6-and-location-services-not-workingFrantz
#14503661Cheesecake
F
0

I've managed to solve the problem by adding a local notification that fires with a 90 second delay every time a new location is added to the route. When the next location is added, the previous notification is cancelled and a new one is scheduled. This way, if it stops updating, a notification is received by the user (albeit with a 90 second delay). It's not ideal, and it may not be great for battery life, but it is a solution and it's the best I've got for the time being.

Frantz answered 18/1, 2013 at 12:18 Comment(1)
Can you please post your code as an answer here. I am running into same problemDispraise
U
0

@Ron, I meet the same problem as beev describe, and i had already set pausesLocationUpdatesAutomatically to NO. I think because iOS will kill some apps that didn't be triggered in 10 minutes when it's under background. So add local notification maybe a good choice at the moment.

Unsnap answered 27/3, 2013 at 7:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.