2

Questions in this vein are asked a lot on this site, but they're all filled with confusion or out of date answers, and I was wondering if anyone could give me a definitive answer as to how to solve the problem in my case? I'd like to update the location in the background somewhat frequently, but turn off location services when uneeded so that power is saved. So I have periodic background updates working as such

 func applicationWillResignActive(application: UIApplication) {
  NSNotificationCenter.defaultCenter().postNotificationName(BeginBackGroundMode, object:self)

}

This function this notification calls ncludes this -

locationManager.pausesLocationUpdatesAutomatically = false
timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: Selector("onTick"), userInfo: nil, repeats: true)         

so this is repeated in the background

  func onTick(){
    println("ticking")  
    println("\(Coordinates!.latitude)")
    println( "\(Coordinates!.longitude)")


    self.locationManager.allowDeferredLocationUpdatesUntilTraveled(CLLocationDistanceMax, timeout: 4)



}

  func locationManager(manager: CLLocationManager!,didFinishDeferredUpdatesWithError error: NSError!) {
    locationManager.startUpdatingLocation()



}

This works, but I feel like I might not be going about it the right way, so any improvements in code elegance or understanding would be awesome. As for my question, where in the process should I turn location on and off to save battery? Or are there other way's you'd reccomend saving battery? (I need max accuracy). Thanks in advance

soqratic
  • 21
  • 1
  • 2
  • 1
    Once your app is in the background then the `NSTimer` will no longer execute. The best approach for reducing battery consumption is to use significant location change mode in the background – Paulw11 Jul 24 '15 at 12:57

1 Answers1

4

For starters Paulw11 is correct that the NSTimer will NOT execute once the application goes into the background. Apple only provides up to 30 seconds todo any work before the application becomes suspended.

However, the proper way to handle this situation is simply to change the type of location updates you are performing. While in the background you should be using the "Significant Location Change" event. The way this works is when the user's location changes in an significant way, then the system will update your application. This is the most battery efficient way to track location while the application is in the background.

Once your application comes back into the foreground, then you can stop the significant location change event, and start the normal location tracking.

Please see some sample code below. This is in objective-c, but can easily be ported over to Swift.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOption
{
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    locationManager.distanceFilter = 1.0f; //one meter

    if ([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
        [locationManager requestAlwaysAuthorization];

    [self.window makeKeyAndVisible];

    return YES;
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [locationManager stopUpdatingLocation];
    [locationManager startMonitoringSignificantLocationChanges];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    [locationManager stopUpdatingLocation];
    [locationManager startUpdatingLocation];
}
miken.mkndev
  • 1,821
  • 3
  • 25
  • 39
  • Need to make a few adjustments Visit http://stackoverflow.com/questions/24063798/cllocation-manager-in-swift-to-get-location-of-user (answer by jayesh kavathiya) – Muhammad Umar Oct 26 '16 at 10:43