Reputation: 3519
I am doing background location tracking in an app and it is firing way too often. I'm not sure what is the best technique for setting a minimum time interval for updating location. I only want to save location data every 2 minutes or so. Some have said to use an NSTimer but I'm not sure how or where to incorporate that in my current code. Below is all of my location tracking code in AppDelegate, does anyone know the best technique for decreasing the frequency of location updates given my current code?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
{
isBackgroundMode = NO;
_deferringUpdates = NO;
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 = 10;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
}
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
[self saveLocation];
//tell the centralManager that you want to deferred this updatedLocation
if (isBackgroundMode && !_deferringUpdates)
{
_deferringUpdates = YES;
[self.locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:60];
}
}
- (void) locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
_deferringUpdates = NO;
}
-(void) saveLocation {
// save information database/ communication with web service
}
- (void)applicationWillResignActive:(UIApplication *)application {
isBackgroundMode = YES;
[self.locationManager stopUpdatingLocation];
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
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");
}
Also since a lot of what I am doing is compile from various tutorials, please feel free to point out anything I am doing incorrectly in terms of performance or battery usage. Thanks!
Upvotes: 1
Views: 892
Reputation: 31
Location manager should be paused automatically & try to use resume locations delegate.
Check time of last location and new location.
This will reduce some battery.
Upvotes: 0
Reputation: 1541
self.locationManager.distanceFilter = 10;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
Try This....!!
Upvotes: -1
Reputation: 11127
As you have declared in your
-(void) initializeRegionMonitoring
the value of distance filter to 10
self.locationManager.distanceFilter = 10;
Therefore, after user move to 10 meters, your didUpdateLocations
will be called,
If you want to minimize the call of this delegate method, then you have to increase the value of distanceFilter
.
Upvotes: 1
Reputation: 1677
In other (open source) projects I have seen the following strategies to save power:
Any way I do not see the need for an extra timer here. What you want to do is start with a rough accuracy (if you can!) and additionally set your distanceFilter to a high value (more than 10 meters for example).
What you can do additionally is this: in your "didUpdateLocations:" callback, let the "saveLocation" only be called if "lastSaveTime" is more than 5 minutes ago if(lastSaveTime + 5 < thisSaveTime) { ... }
assuming time measured in seconds.
Upvotes: 4