MSU_Bulldog
MSU_Bulldog

Reputation: 3519

iOS: Background location app using too much battery

I have an app that gets location updates in the background every 2 minutes and 25 meters traveled. My problem is that while the location tracking is working perfectly, it is seriously draining my battery. Battery usage over a 24 hour period was 30% compared to my next closest app at 14%. Is there some trick to decreasing the battery usage of my app while maintaining my accuracy and time period of location updates?

Could it be draining the battery because of the frequency of calls to didUpdateLocations:? Or could it be that I am communicating with a web service in the background for each location update? I'm really at a loss as to how to improve the battery usage, any help is much appreciated!

Below is my code in AppDelegate for getting location and sending updates to the server:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     self.locationManager = [CLLocationManager new];
    [self.locationManager setDelegate:self];
    if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [self.locationManager requestAlwaysAuthorization];
    }
    [self.locationManager startUpdatingLocation];
    [self.locationManager startMonitoringSignificantLocationChanges];

    [self initializeRegionMonitoring];
}

-(void) initializeRegionMonitoring {
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;

    // notify changes when the device has moved x meters
    self.locationManager.distanceFilter = 25; // or set to 20 meters
    self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    [self.locationManager startUpdatingLocation];
    [self.locationManager startMonitoringSignificantLocationChanges];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSDate *lastDate = [defaults objectForKey:@"lastSavedDate"];

    if ([[NSDate date] timeIntervalSinceDate:lastDate] < 120) {
        NSLog(@"LAST SAVE TIME LESS THAN 2 MINUTES");
        return;
    }

    [self saveLocation];    

    //tell the centralManager that you want to deferred this updatedLocation
    if (isBackgroundMode && !_deferringUpdates)
    {
        NSLog(@"THIS IS GETTING CALLED EVERY TIME");
        _deferringUpdates = YES;
        [self.locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:120];
    }
}

- (void) locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {

    _deferringUpdates = NO;
}

-(void) saveLocation {
    // This code saves location data to a web service
}

- (void)applicationWillResignActive:(UIApplication *)application {
    isBackgroundMode = YES;

    [self.locationManager stopUpdatingLocation];
    [self.locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
    [self.locationManager setDistanceFilter:25];
    self.locationManager.pausesLocationUpdatesAutomatically = NO;
    self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
    [self.locationManager startUpdatingLocation];
}


-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
    return true;
}

-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    [self saveLocation];

   completionHandler(UIBackgroundFetchResultNewData);
    NSLog(@"Fetch completed");
}

Upvotes: 1

Views: 1877

Answers (2)

Amit.S
Amit.S

Reputation: 441

self.locationManager.pausesLocationUpdatesAutomatically=YES;
//monitor locations for significant location change
[self.locationManager startMonitoringSignificantLocationChanges];

If your app does't require accurate location of the user you can try using significant location change which is more memory optimised way but at the end it depends on the situation what is more important i.e high location accuracy or the battery usage. I have done significant testing on this method and usually it updates the location every 4-5 mins or 500 meters whichever is earliest.

Upvotes: 1

Blind Ninja
Blind Ninja

Reputation: 1081

[self.locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];    
[self.locationManager setDistanceFilter:25];

Change these attributes to less accurate. You can save significant battery. These configurations depends what kind of app it is. If it is some kind of calorie burn app , it might be much accurate. You are updating every 2 minutes , so its should be set on average value of approximate distance covered in time with some threshold.

Upvotes: 1

Related Questions