Правильное использование завершения фонового обновления HKObserverQueryHandler

HKObserverQuery имеет следующий метод, который поддерживает получение обновлений в фоновом режиме:

- initWithSampleType:predicate:updateHandler:

updateHandler имеет completionHandler который имеет следующую документацию:

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

Глядя на другие посты, кажется, что вокруг этого обработчика много путаницы. Ниже приведены некоторые вопросы, которые у меня есть по этому поводу:

  • Когда должен вызываться обработчик? Если вызывать слишком поздно, то HK может подумать, что приложение никогда не получало обновление запроса, в результате чего вы запускали алгоритм отката с 3 ударами в фоновом режиме. В документации говорится, что он должен вызываться после обработки других запросов. В зависимости от того, сколько времени потребуется для выполнения этих запросов, может показаться, что вы опасно приблизились к ударам фонового обновления.
  • Зачем это нужно? Разве система не должна знать, что приложение было запущено и получило фоновое обновление? Когда используешь CoreBluetooth в фоновом режиме оно просто разбудит ваше приложение в фоновом режиме на 10 секунд. Не нужно вызывать какой-либо обработчик или заниматься фоновым обновлением 3-х страйков.
  • Если вы нажмете на фоновое обновление 3 удара, и HK прекратит отправку обновлений, это постоянно? HK когда-нибудь снова начинает отправлять фоновые обновления? Что делать, если есть ошибка, которая препятствовала вызову обработчика, и теперь вы исправили это. Приложение застряло, никогда не получая обновления? Или он будет сброшен при повторном запуске или обновлении приложения?
  • Поддерживает ли HK ваше приложение в фоновом режиме, пока не будет вызван обработчик? Это часть его цели или просто побочный эффект? Если это является частью его цели, то как долго мы сможем бежать, прежде чем остановиться (и ударить первый удар фонового обновления)?

0 ответов

Когда следует вызывать обработчик?

Вызовите его после того, как сделаете свою работу. Ваш код не должен выполнять сложных операций. Приложение работает в фоновом режиме, и пользователь не видит, что изменилось. Вы можете просто установить "флаг", что данные обновляются и выполнять сложные операции после того, как пользователь запустил приложение. Если ваше решение либо уведомляет пользователя, либо не основано на сложных операциях, попробуйте выполнить рефакторинг кода, чтобы все необходимые данные были предварительно рассчитаны (например, в UserDefaults), а дополнительные данные просто извлекались с этими данными. Итак, для расчета достаточно 1-2 секунд.

Зачем это нужно?

Все такие обработчики имеют закрытие завершения. Они нужны iOS, чтобы знать, нормально ли работает ваше приложение. Если ваше приложение будет потреблять слишком много процессорного времени, iOS может работать медленно. Следовательно, Apple хочет быть уверенной, что iOS работает нормально, несмотря на плохие приложения.

Если вы нажмете 3-страйк фонового обновления и HK перестанет отправлять обновления, это навсегда?

Нет.

HK когда-нибудь снова начинает отправлять фоновые обновления?

Да. Но это зависит от многих факторов. Он может повторить попытку вызова вашего приложения через 1-2 дня. Если ничего не изменится, он будет звонить редко.

Поддерживает ли HK работу вашего приложения в фоновом режиме, пока не будет вызван обработчик?

Это неизвестно. Это зависит от многих факторов. Вероятно, если iPhone заряжается, это позволит дольше запускать ваше приложение, просто чтобы оценить, вызывается дескриптор завершения или нет. Если ваш iPhone не заряжается и батарея разряжена до 0%, скорее всего, iOS убьет ваше приложение. Таким образом, вы не должны выполнять какую-либо работу после вызова обработчика завершения. И постарайтесь, чтобы это было просто.

Рекомендации

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

1-2 секунды или меньше - хорошее время для фоновых обновлений.

Другие вопросы по тегам