iOS:降低后台位置更新的频率



我在一个应用程序中进行后台位置跟踪,但它太频繁了。我不确定设置更新位置的最小时间间隔的最佳技术是什么。我只想每隔2分钟左右保存一次位置数据。有些人说要使用NSTimer,但我不确定如何或在哪里将其纳入我当前的代码中。以下是我在AppDelegate中的所有位置跟踪代码,有人知道在我当前代码的情况下降低位置更新频率的最佳技术吗?

- (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");
}

此外,由于我所做的很多工作都是从各种教程中编译的,请随时指出我在性能或电池使用方面做得不正确的地方。谢谢

在其他(开源(项目中,我看到了以下节能策略:

  • 将请求的精度(setDesiredAccurcy(降低得很大(不是"kCLLocationAccuracyBest",而是"kCLLocation AccuracyKilometer"(
  • 通过在"distanceFilter"中设置一个大阈值来减少回调"didUpdateLocations:"计数
  • 如果不需要写入(使用其他条件,如时间(,则从回调返回

无论如何,我认为这里不需要额外的计时器。你想做的是从粗略的精度开始(如果可以的话!(,并将距离过滤器设置为一个高值(例如超过10米(。

此外,您还可以执行以下操作:在"didUpdateLocations:"回调中,如果"lastSaveTime"在if(lastSaveTime + 5 < thisSaveTime) { ... }之前超过5分钟,则仅调用"saveLocation",假设时间以秒为单位。

正如您在中声明的那样

-(void) initializeRegionMonitoring

距离滤波器的值为10

self.locationManager.distanceFilter = 10;

因此,当用户移动到10米后,您的didUpdateLocations将被调用,

如果要最小化此委托方法的调用,则必须增加distanceFilter的值。

  1. 当用户时启动服务当地方精确度小于locationManager的精确度
  2. 位置管理器应该自动暂停&尝试使用简历locations委派。

  3. 检查上次位置和新位置的时间。

  4. 这将减少一些电池电量。

self.locationManager.distanceFilter = 10;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
[self.locationManager startUpdatingLocation];

试试这个。。。。!!

最新更新