Reputation: 3519
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
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
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