Этот ответ может быть немного неправильным, потому что на самом деле больше невозможно использовать функцию дефферирования, даже если документ не был удален.Но цель состояла в том, чтобы включать / выключать местоположение через определенные промежутки времени, чтобы не включать его постоянно для экономии энергии.
Чтобы приблизиться к полному включению / выключению, можно переключаться между высокой и низкой точностью,это сэкономит энергию наверняка.(высокая точность обычно <10 м будет использовать модуль GPS, низкая точность> 500 м будет обычно AGPS .
Сначала запустите NSTimer с нужным интервалом, затем начните обновление с высокой точностью.При получении местоположения в didUpdateLocations измените с высокой точности на низкую точность. Обратный вызов NSTimer запрашивает новое высокоточное обновление местоположения (то есть вызывает setupHighAccuracy
). Таким образом, таймер устанавливает частоту обновлений высокой точности. Это также будет работатьв фоновом режиме, потому что служба определения местоположения все еще работает. При остановке обновлений приложение остановится в фоновом режиме. При остановке и повторном запуске диспетчера местоположений оно немедленно вызовет didUpdateLocation, но при проверке отметки времени местоположение может быть буферизовано..
Ниже показаны некоторые фрагменты, чтобы начать работу. Для производственного кода потребуется дополнительная фильтрация и тестирование:
@property (retain, nonatomic) NSTimer *atimer;
static BOOL _lowAccuracy;
- (void)timerCallback {
[self setupHighAccuracy];
}
- (void)setupTimer
{
if(self.atimer != nil)
{
return;
}
UIApplication *app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier bgTaskId =
[app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTaskId];
bgTaskId = UIBackgroundTaskInvalid;
}];
dispatch_async( dispatch_get_main_queue(), ^{
self.atimer = [NSTimer scheduledTimerWithTimeInterval:15.0 // consider higher interval
target:self
selector:@selector(timerCallback)
userInfo:nil
repeats:YES];
}
[app endBackgroundTask:bgTaskId];
bgTaskId = UIBackgroundTaskInvalid;
});
}
- (void)setupHighAccuracy
{
if(_lowAccuracy)
{
[_locationManager performSelectorOnMainThread:@selector(stopUpdatingLocation) withObject:nil waitUntilDone:YES];
_locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; // or kCLLocationAccuracyBest, tune yourself
_locationManager.activityType = CLActivityTypeFitness;
_locationManager.distanceFilter = 15; // or 0, tune yourself
_lowAccuracy = false;
[_locationManager performSelectorOnMainThread:@selector(startUpdatingLocation) withObject:nil waitUntilDone:YES];
}
}
- (void)setupLowAccuracy
{
if(!_lowAccuracy)
{
s_initialized = true;
[_locationManager performSelectorOnMainThread:@selector(stopUpdatingLocation) withObject:nil waitUntilDone:YES];
_locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
_locationManager.activityType = CLActivityTypeFitness;
_locationManager.distanceFilter = 3000;
_lowAccuracy = true;
[_locationManager performSelectorOnMainThread:@selector(startUpdatingLocation) withObject:nil waitUntilDone:YES];
}
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
CLLocation *location = locations.lastObject;
if(!_lowAccuracy) {
// update system with location here
[_locationManager.delegate setupLowAccuracy];
self.s_lastLocation = location;
}
}