IPhone GPS в фоновом режиме никогда не возобновляется после паузы

Мое приложение должно отслеживать изменения местоположения пользователя в фоновом режиме и прекрасно работает, пока пользователь перемещается. Когда пользователь останавливается и CLLocationManager приостанавливается через 10-20 минут или около того. Это уведомление указывается следующим образом:

-(void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager{}

И это тоже прекрасно со мной. Отлично, я сохраняю батарею и т.д.

Проблема заключается в том, что CLLocationManager никогда не просыпается, когда пользователь снова начинает перемещаться и после делегированных методов никогда не запускается, пока я не поставлю свое приложение на передний план (становится активным):

//Never called back after CLLocationManager pauses:
-(void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager{}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{}

Почему locationManagerDidResumeLocationUpdates никогда не вызывается после того, как устройство снова начинает перемещаться? Если GPS не возобновляется автоматически (так как автоматически было приостановлено)? Есть ли способ возобновить работу GPS без взаимодействия с пользователем?

Приложение имеет следующее объявление в файле Info.plist:

enter image description here

И мои настройки CLLocationManager:

locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager setActivityType:CLActivityTypeFitness];
//I WANT pauses to save some battery, etc... That is why following line is commented out (default)
 //[locationManager setPausesLocationUpdatesAutomatically:NO];
 locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
 locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
 [locationManager startUpdatingLocation];

Ответ 1

Если вы ищете pausesLocationUpdatesAutomatically на форумах Apple, вы найдете недавний вопрос по аналогичным строкам, который получил ответ от разработчика Apple. Я не буду перепечатывать его прямо здесь, так как это частный форум, но суть в том, что приостановка местоположения - это случаи, когда пользователь забывает, что у них есть приложение, ориентированное на местоположение, и перестало его использовать. При приостановке обновлений их батарея не будет разряжаться так быстро. К сожалению, невозможно узнать, возобновляет ли их новое движение или что-то делает, поэтому обновления не возобновляются до тех пор, пока приложение не вернется на передний план. Их предложение - поймать вызов паузы и привлечь внимание пользователя, чтобы заставить их открыть приложение, если они все еще хотят обновления.

EDIT:

Из собственной документации Apple pausesLocationUpdatesAutomatically. Они предлагают:

После паузы ответственность заключается в том, чтобы снова возобновить службы определения местоположения, когда вы определите, что они необходимы. Core Location вызывает locationManagerDidPauseLocationUpdates(_:)метод вашего делегата менеджера по размещению, чтобы вы знали, что произошла пауза. В этом методе вы можете настроить локальный уведомление, триггер которого имеет тип UNLocationNotificationTriggerи установлен для уведомления, когда пользователь выходит из текущего региона. сообщение для локального уведомления должно побуждать пользователя запускать ваше приложение снова, чтобы оно могло возобновлять обновления.

Ответ 2

Яблочный документ очень слаб по этой теме. свойство pausesLocationUpdatesAutomatically позволяет яблоку отключать GPS, когда яблоко думает, что пользователю не нужен GPS.

Хотя документация не документирована, кажется, что установка этого свойства приводит к остановке GPS в фоновом режиме.

Различные сообщения описывают проблемы с этим свойством:, например, здесь:
iOS 6 CoreLocation не работает

В iOS 6 AutoPause не работает  Станислав Двойченко публикует рекомендацию Apple:

[Обновление - 4 марта 2013]. Я просмотрел презентацию Apple для изменения местоположения в iOS6, и они предлагают использовать изменения региона мониторинг для "отмены паузы" после получения события изменения области. Хоть это не подходит для моих сценариев, так как пользователь может пойти/запустить/диск для километра или два, пока такое событие не произойдет.

Я предлагаю: установите для этого свойства значение false.

Ответ 3

Если вы можете, используйте startMonitoringSignificantLocationChanges, потому что тогда (Apple):

Если вы запустите эту услугу, и ваше приложение впоследствии будет завершено, система автоматически перезапустит приложение в фоновом режиме, если придет новое событие.

Вы можете попробовать объединить это с мелкозернистым отслеживанием после того, как ваше приложение просыпается (например, пользователь снова вводит его).