5

I would like to ideally update the user's location every 5 minutes if the application is within a background state, or in the foreground state. This is a very location sensitive app, so knowing the location at all times is quiet crucial.

There have been many answers relating to this question on SO, but a lot of them deal with iOS 6 and earlier. After iOS 7, a lot of background tasks have changed and Im having difficulty in finding a way to implement periodic location updates in the background.

2 Answers2

2

You'll want to use CoreLocation's delegate. As soon as you get a coordinate, stop CoreLocation, set a timer to start it again in 5 minutes.

With iOS 8, you'll need to set a plist entry for NSLocationWhenInUseUsageDescription and/or NSLocationAlwaysInUseDescription.

The Apple documentation is very clear on how to do all of this.

-(void)startUpdating{
    self.locationManager = [[CLLocationManager alloc]init];
    self.locationManager.delegate = self;
    [self.locationManager requestWhenInUseAuthorization];
    [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    [self.locationManager startUpdatingLocation];

}

-(void)timerFired{
    [self.timer invalidate];
    _timer = nil;
    [self.locationManager startUpdatingLocation];
}

// CLLocationDelegate
- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations{
    if(locations.count){
        // Optional: check error for desired accuracy
        self.location = locations[0];
        [self.locationManager stopUpdatingLocation];
        self.timer = [NSTimer scheduledTimerWithTimeInterval:60 * 5 target:self selector:@selector(timerFired) userInfo:nil repeats:NO];
    }
}
VaporwareWolf
  • 10,143
  • 10
  • 54
  • 80
  • Will this continue to work when the app has entered the background? – initWithQuestion Sep 23 '14 at 03:58
  • Some modes yes. Read the documentation. – VaporwareWolf Sep 23 '14 at 06:27
  • I notice that ``[self.locationManager stopUpdatingLocation]`` is featured twice, should the timerFired method be ``[self.locationManager startUpdatingLocation]``? I believe that ``self.location = [locations lastObject]`` is more appropriate since the last object is always the most recent. Lastly, could you explain why the timer invalidation logic is called? – initWithQuestion Sep 23 '14 at 15:51
  • Yes, that was a typo (start/stop) which is now edited/fixed. Timer invalidate stops it from firing any more. It's just cleanup. Since that parameter is set to NO, it will do nothing since it's called after the timer fires anyhow. You can likely remove it. lastObject will work fine. This delegate fires so often that I doubt you'll ever have much difference between [0] and [last]. – VaporwareWolf Sep 23 '14 at 17:04
  • When app goes to background and suspended by iOS, timer will be paused and location manager will not awake app and deliver location update, is it so? – BaSha Jul 31 '17 at 04:46
0

There is quite a bit of information in regards to this on the apple documentation.

Also, there are some additional answers here and here with previous answers from stackoverflow. There looks to be enough information in there which should be able to help you!

Community
  • 1
  • 1
sdoowhsoj
  • 200
  • 1
  • 1
  • 9
  • Both of those answers are before iOS 8 and some of those methods have been already deprecated. – initWithQuestion Sep 22 '14 at 19:05
  • 1
    They are meant to help lead you in the right direction. When you have a question the documentation should be there to help provide you with any information that you need. There is tons of information on Apple's documentation about apps running in the background that you should read. – sdoowhsoj Sep 22 '14 at 19:32