Background Location Services not working in iOS 7 Background Location Services not working in iOS 7 ios ios

Background Location Services not working in iOS 7


Here is the solution that I used to get continuous location from iOS 7 devices no matter it is in foreground or background.

You may find the full solution and explanation from blog and also github:-

  1. Background Location Update Programming for iOS 7 and 8

  2. Github Project: Background Location Update Programming for iOS 7 and 8

Methods and Explanation:-

  1. I restart the location manager every 1 minute in function didUpdateLocations

  2. I allow the location manager to get the locations from the device for 10 seconds before shut it down (to save battery).

Partial Code Below:-

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{for(int i=0;i<locations.count;i++){    CLLocation * newLocation = [locations objectAtIndex:i];    CLLocationCoordinate2D theLocation = newLocation.coordinate;    CLLocationAccuracy theAccuracy = newLocation.horizontalAccuracy;    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];    if (locationAge > 30.0)        continue;    //Select only valid location and also location with good accuracy    if(newLocation!=nil&&theAccuracy>0       &&theAccuracy<2000       &&(!(theLocation.latitude==0.0&&theLocation.longitude==0.0))){        self.myLastLocation = theLocation;        self.myLastLocationAccuracy= theAccuracy;        NSMutableDictionary * dict = [[NSMutableDictionary alloc]init];        [dict setObject:[NSNumber numberWithFloat:theLocation.latitude] forKey:@"latitude"];        [dict setObject:[NSNumber numberWithFloat:theLocation.longitude] forKey:@"longitude"];        [dict setObject:[NSNumber numberWithFloat:theAccuracy] forKey:@"theAccuracy"];        //Add the vallid location with good accuracy into an array        //Every 1 minute, I will select the best location based on accuracy and send to server        [self.shareModel.myLocationArray addObject:dict];    }}//If the timer still valid, return it (Will not run the code below)if (self.shareModel.timer)    return;self.shareModel.bgTask = [BackgroundTaskManager sharedBackgroundTaskManager];[self.shareModel.bgTask beginNewBackgroundTask];//Restart the locationMaanger after 1 minuteself.shareModel.timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self                                                       selector:@selector(restartLocationUpdates)                                                       userInfo:nil                                                        repeats:NO];//Will only stop the locationManager after 10 seconds, so that we can get some accurate locations//The location manager will only operate for 10 seconds to save batteryNSTimer * delay10Seconds;delay10Seconds = [NSTimer scheduledTimerWithTimeInterval:10 target:self                                                selector:@selector(stopLocationDelayBy10Seconds)                                                userInfo:nil                                                 repeats:NO]; }

Update on May 2014: I got a few requests for adding sample codes on sending the location to server for a certain time interval. I have added the sample codes and also combined a fix for BackgroundTaskManager to solve a glitch for background running over an extended period of time. If you have any questions, you are welcomed to join us for a discussion here: Background Location Update Programming for iOS 7 with Location Update to Server Discussion

Update on January 2015: If you want to get the location update even when the app is suspended, please see: Get Location Updates for iOS App Even when Suspended


If you look at WWDC 2013 Session video #204 - What's new with multitasking pdf, page number 15 clearly mentions that apps wont launch in the background if user kills it from the app switcher. Please see the image,

enter image description here


I think they made an optimization (probably using motion sensors), to detect "relatively" stationary positioning of the phone and they stop the location updates. This is only a speculation, but my tests currently show:

  1. Starting location updates; (tested with accuracy of 10 and 100 meters, 3 times each)
  2. Turn device's screen off to put the app in the background;
  3. Leave the device stationary (e.g. on a desk) for 30 min.

The data I log shows the geo-updates stop coming after ~ 15m and 30s. With that all other background processing you do is also terminated.

My device is iPhone 5 with iOS 7.

I am 95% sure, this wasn't the case on iOS 6/6.1. Where getting geo updates with 100m accuracy used to give you pretty much continuous running in background.

Update

If you restart the location manager every 8 minutes, it should run continuously.

Update #2

I haven't tested this in latest, but this is how I restarted it when I wrote the post. I hope this is helpful.

- (void)tryRestartLocationManager{    NSTimeInterval now = [[NSDate date] timeIntervalSince1970];    int seconds = round(floor(now - locationManagerStartTimestamp));    if ( seconds > (60 * 8) ) {        [locationManager stopUpdatingLocation];        [locationManager startUpdatingLocation];        locationManagerStartTimestamp = now;    }}