Background Location Services Not Working in iOS 7

iOS 7 background location service stops

You can in general not be sure your app will be kept alive. A user might want to terminate it actively or the system might be in need of the resources your app is using, and therefore terminate it. I guess you are experiencing this problem due to resource constraints.

You might get around it by using the the Background fetch introduced in iOS7. The OS will at regular interval allow your app to start up again.

Try reading this excellent document describing the feature:

You can, however, not prevent the user from force your app to close.

iOS 7 - Background Location app getting killed when getting a background location

1) Its supposed to redundant and not needed when you use background location, however I've found if you're not getting the execution behaviour you expect when using location then throwing in a beginBackgroundTaskWithExpirationHandler when updateLocations: gets called can sometimes fix issues like this.

2) Another thing that you could try is setting pausesLocationUpdatesAutomatically to NO to see if it fixes things for you, but if it does it could use the batteries some more.

3) Also another thing to try is if you have other background modes set at the same time as location (in particular backgroundFetch and remoteNotifications) you could try toggling them off temporarily to see if its having an adverse affect.

4) One final thing, see if there are any other location based apps installed on your phone which are currently running, in my experience I've found if there's more than one location app running and they have different location manager setting set then one app can affect the behaviour of the other.

None of these should have any affect on your program and they might not. And people reading this might think these suggestions are crazy and just should not work.However I've been developing a couple of different location apps in parallel for the past few months and after many many many many debug sessions, logging sessions, observing location app behaviour when running in the background, I've come to the definite conclusion and am 100% convinced that all is not as it seems and is supposed to be (nor as is documented, nor is as it should be according to accumulated group wisdom and stack overflow answers) when it comes to location behaviour.

There's something mysterious and screwy going on in location land sometimes.

Location Services not working in background called by WatchKit

Three things to check and be aware of:

  1. Location Permissions like [self.locationManager requestAlwaysAuthorization]; are only acknowledged once by the OS. If you have already requested permission, doesn't matter the level, the OS will NOT display a request to the user. The OS will just pass over the request and leave the permission level as is. The only time you can be assured that the OS will display the request to the user is if the [CLLocationManager authorizationStatus] returns kCLAuthorizationStatusNotDetermined. In every other case, you must manually request permission by displaying an Alert or other form of UI display. Also note that the OS retains whether or not it already displayed the request, even if you delete your app and reinstall it. So to test, you need to reset your Simulator's Content or your iPhone's Location Privacy.

  2. Make sure you have added the plist keys for NSLocationAlwaysUsageDescription AND NSLocationWhenInUseUsageDescription If you don't add this to your plist, the OS will ignore any Location Permission Requests.

  3. If you want to use requestAlwaysAuthorization to get location data from the phone (not the watch app extension) while the phone app is in the background, will also require you register for Background Modes Location updates under Project>Target>Capabilities.

Use a background task to give your app time to respond when in the background. Something like this:

-(void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *replyInfo))reply{

UIApplication *app = [UIApplication sharedApplication];

UIBackgroundTaskIdentifier bgTask __block = [app beginBackgroundTaskWithName:@"watchAppRequest" expirationHandler:^{

[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;


//make your calls here to your tasks, when finished, send the reply then terminate the background task

//send reply back to watch

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[app endBackgroundTask:bgTask];

Related Topics

Leave a reply