Поведение для существенного изменения местоположения API, когда прекращено / приостановлено? - PullRequest
109 голосов
/ 06 августа 2010

Это раздел документации CLLocationManager , описывающий поведение приложения с помощью startMonitoringSignificantLocationChanges :

Если вы запустите эту услугу и ваш заявка впоследствии прекращено, система автоматически перезапускает приложение в фон, если новое событие прибывает. В такой случай, словарь опций перешел к применение: didFinishLaunchingWithOptions: метод вашего приложения делегата содержит ключ UIApplicationLaunchOptionsLocationKey указать, что ваша заявка была запущен из-за события местоположения. После перезапуска вы должны еще настроить объект диспетчера местоположения и вызвать этот метод, чтобы продолжить получение места событий. Когда ты перезапустить службы определения местоположения, текущий событие доставлено вашему делегату немедленно. Кроме того, расположение собственность вашего менеджера Объект заселен наиболее недавнее местоположение объекта еще до вас начать локацию услуг.

Так что я понимаю, что если ваше приложение завершает работу (и я предполагаю, что если вы не вызовете stopMonitoringSignificantLocationChanges из applicationWillTerminate ), вы проснетесь с UIApplicationLaunchOptionsLocationKey параметр для приложения: didFinishLaunchingWithOptions . В этот момент вы создаете CLLocationManager , вызываете startMonitoringSignificantLocationChanges и выполняете фоновую обработку местоположения в течение ограниченного времени . Так что я в порядке с этим битом.

В предыдущем параграфе говорится только о том, что происходит, когда приложение завершается, и не предлагается, что вы делаете, когда приложение приостановлено. Документация для didFinishLaunchingWithOptions гласит:

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

Предполагается, что вы будете получать этот вызов только при запуске приложения (из-за изменения местоположения) после того, как вы были прерваны.

Однако параграф Служба значительных изменений в Руководстве по программированию осведомленности о местоположении содержит следующее:

Если вы оставите эту службу запущенной и ваша заявка впоследствии приостановлено или прекращено, услуга автоматически просыпается приложение, когда новые данные о местоположении прибывает. Во время пробуждения ваш приложение ставится в фоновом режиме и уделить немного времени обработать данные о местоположении. Так как ваше приложение в фоновом режиме, это должно делать минимальную работу и избегать любые задачи (например, запрос сеть), которая может помешать этому возвращение раньше назначенного времени истекает. Если это не так, ваш заявка может быть прекращена.

Это говорит о том, что вы проснулись с данными о местоположении, если ваше приложение было приостановлено, но не упоминает, как вы проснулись:

  • Получает ли UIApplicationDelegate обратный вызов, сообщающий, что я возвращаюсь из приостановленного состояния в фоновое состояние?
  • Менеджер местоположений (который был заморожен при приостановке приложения) начинает получать locationManager: didUpdateToLocation: fromLocation обратные вызовы?
  • Нужно ли просто реализовать код в моем сообщении didUpdateToLocation , которое проверяет состояние приложения и выполняет минимальную обработку в фоновом режиме?

В процессе написания этого, я думаю, что я, возможно, только что ответил на свой собственный вопрос, но было бы здорово, чтобы мое понимание этого подтвердилось кем-то более знающим.

Ответы [ 3 ]

80 голосов
/ 14 августа 2010

С тех пор, как я задал этот вопрос, я провел немало тестов (в основном на поезде между домом и работой) и подтвердил, что поведение приостановленных приложений такое же, как я подозревал в конце вопроса.

То есть ваше приостановленное приложение проснулось, вы не получите никаких обратных вызовов от своего делегата приложения, вместо этого вы получите обновления своего местоположения через существующий CLLocationManagerDelegate . Вы можете определить, что вы работаете в фоновом режиме, проверив applicationState и выполнить ограниченную работу для случая, когда вы проснулись из приостановленного состояния, чтобы выполнить обработку местоположения.

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

Я пришел к такому выводу с помощью проводки для проверки местоположения, которую вы можете загрузить и попробовать. Это довольно простое приложение, которое позволяет вам включать значительные изменения и API изменения GPS через пользовательский интерфейс и регистрировать все полученные ответы.

Н.Б. Пункт шесть в предыдущем ответе неверен. Замораживание приостановленные приложения получают CLLocationManagerDelegate обратные вызовы, когда они просыпаются из приостановленного состояния.

25 голосов
/ 10 августа 2010

Мое понимание следующее (я нахожусь в процессе написания приложения, которое использует этот API, но еще не завершил этот компонент для начала тестирования):

  1. Ваше приложение запускается в первый раз, вы регистрируетесь на startMonitoringSignificantLocationChanges и предоставляете функцию обратного вызова. Пока ваше приложение работает, оно будет вызывать этот обратный вызов всякий раз, когда оно получает существенное изменение.
  2. Если ваше приложение переведено в фоновый режим, UIApplication получит applicationWillResignActive , за которым следует applicationDidEnterBackground .
  3. Если ваше приложение будет убито, пока оно приостановлено в фоновом режиме, вы не будете уведомлены; однако, если ваше приложение будет убито во время его работы (насколько мне известно, передний план или фон), вы получите момент с applicationWillTerminate . Вы не можете запросить дополнительное фоновое время от этой функции.
  4. Несмотря на то, что ОС была убита в фоновом режиме, ОС перезапустит ваше приложение. Если ваше приложение просто запускается ОС для изменения, вы получите вызов application didFinishLaunchingWithOptions :

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])
    

    поможет вам определить, вернулись ли вы из фонового изменения местоположения.

  5. Если вместо этого вы в данный момент работаете в фоновом режиме, и ваше приложение вручную перезапускается пользователем, вы получите applicationWillEnterForeground , за которым следует applicationDidBecomeActive .
  6. Независимо от того, как это произошло, когда ваше приложение было перезапущено (если только оно не работало в фоновом режиме в результате фоновой задачи и в указанной задаче начался мониторинг изменений), вам нужно явно сообщить об этом startMonitoringSignificantLocationChanges снова, потому что обратный вызов больше не прикрепляется после «сублимационной сушки». И да, вам просто нужно реализовать код в didUpdateToLocation, как только вы повторно подключите какой-либо обработчик местоположения, когда возвращаетесь из приостановленного состояния.

Это то, чем я сейчас занимаюсь при разработке кода. Как я упоминал ранее, я не совсем готов проверить это на устройстве, поэтому не могу сказать, правильно ли я все интерпретировал, поэтому, комментаторы, не стесняйтесь поправлять меня (хотя я много читал о тема).

О, и если по какой-то причине вам не повезет, вы выпустите приложение, которое делает то, что я хочу, я могу заплакать:)

Удачи!

1 голос
/ 27 января 2015

Если приложение вызвано из приостановленного состояния в результате изменения местоположения, приложение запустится в фоновом состоянии.

Все объекты будут активными, и вы получите обновление местоположения в существующем делегате.

...