Поведение для значительного API определения местоположения при завершении/приостановлении?

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

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

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

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

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

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

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

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

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

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

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

Ответ 1

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

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

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

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

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

Ответ 2

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

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

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])
    

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

  • Если вместо этого вы в настоящее время работаете в фоновом режиме, и ваше приложение вручную перезагружается пользователем, вы получите applicationWillEnterForeground, за которым следует applicationDidBecomeActive.
  • Независимо от того, как это произошло, когда ваше приложение перезаписано (если оно не было запущено в фоновом режиме в результате фоновой задачи, и упомянутая задача приступила к мониторингу изменений), вам нужно явно указать это на startMonitoringSignificantLocationChanges снова, потому что обратный вызов больше не привязан после "сушки вымораживанием". И да, вам просто нужно реализовать код в файле doUpdateToLocation, как только вы снова подключите обработчик местоположения, когда вернетесь из приостановленного состояния.

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

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

Удачи!

Ответ 3

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

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