Поведінка інтерфейсу API значної зміни після його припинення / призупинення?


108

Це розділ із документації CLLocationManager, що описує поведінку програми за допомогою startMonitoringSignificantLocationChanges :

Якщо ви запускаєте цю послугу, а ваша програма згодом припиняється, система автоматично запускає програму на другий план, якщо приходить нова подія. У такому випадку словник параметрів передається додатку: didFinishLaunchingWithOptions: метод делегата вашої програми містить ключ UIApplicationLaunchOptionsLocationKey, щоб вказати, що ваша програма була запущена через подію локації. Після повторного запуску потрібно все-таки налаштувати об’єкт диспетчера місцеположень та викликати цей метод, щоб продовжувати отримувати події місцеположення. Після перезавантаження служб локації поточна подія негайно доставляється вашому делегату. Крім того, властивість місцеположення об’єкта вашого менеджера локації заповнюється самим останнім об’єктом локації ще до того, як ви запускаєте служби локації.

Тож я розумію, що якщо ваш додаток припиняється (і я вважаю, що якщо ви не зателефонуєте stopMonitoringSignificantLocationChanges from applicationWillTerminate ), ви отримаєте пробуджений параметр UIApplicationLaunchOptionsLocationKey до програми: didFinishLaunchingWithOptions . У цей момент ви створюєте свій CLLocationManager , зателефонуйте startMonitoringSignificantLocationChanges і виконайте обробку вашого фонового місцезнаходження протягом обмеженого часу . Так що я добре з цим шматочком.

У попередньому параграфі йдеться лише про те, що відбувається, коли додаток припинено, він не підказує, що робити, коли додаток призупинено. Документація для didFinishLaunchingWithOptions говорить:

Додаток відстежує оновлення місцеположення у фоновому режимі, очищено та тепер відновлено. У цьому випадку словник містить ключ, який вказує на те, що додаток було перезапущено через нову подію локації.

Запропонуйте, що ви отримаєте цей дзвінок лише після запуску програми (через зміну місця розташування) після того, як ви припините.

Однак абзац про службу суттєвих змін у Посібнику з програмування поінформованості про місцеположення повинен сказати наступне:

Якщо ви залишите цю послугу запущеною, а ваша програма згодом буде призупинена або припинена, служба автоматично прокидає вашу програму, коли надійдуть нові дані про місцезнаходження. Під час пробудження вашій програмі відкладається на другий план і надається невелика кількість часу для обробки даних про місцезнаходження. Оскільки ваша програма знаходиться у фоновому режимі, вона повинна робити мінімальну роботу та уникати будь-яких завдань (наприклад, запитів у мережі), які можуть запобігти її поверненню до закінчення виділеного часу. Якщо цього не відбувається, Ваша заявка може бути припинена.

Це говорить про те, що вас прокидають дані про місцезнаходження, якщо ваш додаток призупинено, але не вказується, як вас прокидають:

  • Чи отримує UIApplicationDelegate зворотний дзвінок, який повідомляє мені про те, що я поновлююсь з призупиненого стану у фоновий стан?
  • Чи розпочинає отримувати менеджер місцеположення (який був замороженим під час призупинення роботи програми) для отримання LocationManager: didUpdateToLocation: від зворотних викликів локації ?
  • Чи потрібно мені просто реалізувати код у своєму повідомленні didUpdateToLocation, яке перевіряє стан програми та робить мінімальну обробку, якщо у фоновому режимі?

Під час написання цього запису я думаю, що, можливо, я просто відповів на власне запитання, але було б чудово, щоб моє розуміння цього підтвердило хтось більш обізнаний.

Відповіді:


80

Оскільки я задав це запитання, я зробив досить тестування (в основному в поїзді між домом та роботою) і підтвердив, що поведінка для призупинених програм така, як я підозрював у кінці запитання.

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

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

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

Примітка. Точка шоста у попередній відповіді є невірною. Заморожені висушені програми, які заморожуються , отримують зворотні дзвінки CLLocationManagerDelegate, коли вони прокидаються з призупиненого стану.


1
Викреслив №6 у своїй відповіді, щоб не бентежити людей.
Аарон

За іронією долі, я також відчував таку ж розгубленість, коли розвивався для значних змін. У мене все ще є сумніви щодо того, що станеться, якщо додаток закрито. чи не відбудеться зворотний виклик UIApplicationDelegate? це правильний спосіб запуску програми. якщо менеджер місцеположення ще не працює, як він може отримувати сповіщення у фоновому режимі? (час ще на НДДКР)
darshansonde

Дякую за зразок програми, він був дуже корисним для мене. У мене виникає питання: Що робити, якщо я використовував стандартну послугу локації у фоновому режимі, а не істотну, додаток також буде перезапущено після закінчення в цьому випадку? Я поставив це питання тут докладно, я був би радий , якщо ви могли б полегшити мене:] stackoverflow.com/questions/12239967 / ...
aslisabanci

2
Не працював на ios7 stackoverflow.com/questions/18946881 / ...
Ігор

Чи знаєте ви, скільки часу минуло, щоб ваш додаток було припинено? А потім замість цього отримати зворотній зв'язок appDelegate? (Це як 30 хвилин? 2 години? 5 годин?) Причина, яку я прошу, це тому, що я створив регіон для моніторингу. Пробував багато разів, щоб побачити, як мій додаток запускається, але лише один раз я перезапустив додаток. Інший раз didExitRegionзворотний виклик, але мені не вдалося startLocationUpdatesзвідти, як це не було через запуск програми ...
Honey

25

Моє розуміння полягає в наступному (я зараз пишу заявку, яка спирається на цей API, але не заповнила цей компонент достатньо, щоб почати тестування):

  1. Ваша програма запускається вперше, ви реєструєтеся для запускуMonitoringSignificantLocationChanges та надаєте функцію зворотного дзвінка. Поки ваша програма працює, вона буде викликати цей зворотний виклик кожного разу, коли отримає значну зміну.
  2. Якщо ваша програма буде виведена на другий план, UIApplication отримає applicationWillResignActive , а потім додаток applicationDidEnterBackground .
  3. Якщо ваша програма буде вбита під час її призупинення у фоновому режимі, вам не надійде сповіщення; однак, якщо ваша програма буде вбита під час її запуску (передній план або фон, наскільки мені відомо), ви отримаєте мить із програмоюWillTerminate . Ви не можете вимагати додаткового фонового часу від цієї функції.
  4. Незважаючи на те, що загинули у фоновому режимі, ОС відновить вашу програму. Якщо ваша програма просто запуститься ОС для зміни, ви отримаєте виклик до програми didFinishLaunchingWithOptions :

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])

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

  5. Якщо замість цього ви працювали у фоновому режимі, і ваш додаток користувач перезавантажив вручну, ви отримаєте програмуWillEnterForeground, а потім додатокDidBecomeActive .
  6. Незалежно від того, як це сталося, коли ваша програма перезапущена (якщо вона все ще не працює у фоновому режимі в результаті фонового завдання і зазначена задача почала моніторинг змін), вам потрібно чітко сказати їй, щоб знову запуститиMonitoringSignificantLocationChanges, оскільки зворотний виклик немає довше прикріплюється після "заморожування". І так, вам просто потрібно реалізувати код у didUpdateToLocation, коли ви знову приєднаєте якийсь обробник локації, повернувшись із призупиненого стану.

Це те, що я зараз роблю з розробкою коду. Як я вже згадував, я не дуже готовий протестувати це на пристрої, тому не можу сказати, чи правильно все інтерпретував, тож, коментатори, будь ласка, не соромтеся мене виправити (хоча я прочитав істотне читання на тема).

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

Удачі!


1
@Tegeril +1 Дякую за відповідь. Я починав чути цвіркуни на цьому. :) Я здивований, що програми, які почалися з припинення роботи, потребують повторного виклику startMonitoringSignificantLocationChanges. Чи є у вас посилання на doco, де це описано? Я розумію, що завантаження з призупиненого стану дозволить створити всі ваші об’єкти такими, як вони були, коли додаток було призупинено. Тож я б очікував, що прохання про суттєві зміни набудуть чинності.
RedBlueThing

Ви можете про це говорити? "Після повторного запуску потрібно все-таки налаштувати об'єкт диспетчера місцеположень та викликати цей метод, щоб продовжувати отримувати події місцеположення". Але я думаю, що це стосується випадку, коли ви додаток запущено із стану, що припинився (подією локації). Це, в основному, корінь мого питання: "Що відбувається з призупиненою справою?".
RedBlueThing

Морган Грінґер на форумах Dev запропонував це: "Вам потрібно створити менеджер CLLocationManager, встановити делегата та зателефонувати startMonitoringSignificantLocationChanges при запуску програми, інакше в Core Location не буде нікуди доставляти оновлення". в контексті перезавантаження програми незалежно від стану, що припинився або призупинено. З "додаток було відновлено після запускуMonitoringSignificantLocationChanges і що тепер?"
Аарон

Я погоджуюся, що це все ще може бути невизначеним навіть у контексті цього форуму (на плакаті обговорювались пробудження з фону, але Морган використовував більш загальний перезапуск програми). Я все ще думаю, що вам потрібно зателефонувати, щоб знову перевірити, коли ваша програма перезапускається, якщо ви хочете працювати з функцією суттєвих змін. Якщо ви хочете замість цього запустити фонове завдання та оновити стандартну службу локації та функціональність GPS, це альтернативний варіант. Я не вірю, що вам потрібно перереєструватися при кожному запуску із суттєвими змінами, щоб все-таки запустити його знову.
Аарон

1
Я радий, що з цього вийшло щось остаточне, що повинно мені допомогти в майбутньому :)
Аарон

1

Якщо додаток викликається з призупиненого стану в результаті зміни місцезнаходження, програма запуститься у фоновому стані.

Усі об'єкти будуть живими, і ви отримаєте оновлення місцеположення в існуючому делегаті.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.