Фоновая задача iOS не остается активной, если она запущена, когда телефон заблокирован (экран выключен)

У меня есть приложение iOS, которое взаимодействует с устройствами BLE. Фоновый режим Аксессуары Bluetooth LE активен, поэтому приложение может подключаться и взаимодействовать с устройствами BLE, даже если оно находится в фоновом режиме. Когда устройство BLE подключено, приложение выполняет код в фоновом режиме, отвечая на обратные вызовы, связанные с BLE, но после отключения устройства BLE приложение больше не может выполнять код в фоновом режиме (приложение остается активным только в течение нескольких секунд после отключения устройства BLE). ).

Что мне нужно, так это способ выполнить задачу конечной длины (примерно 1-2 минуты) после отключения устройства BLE.

Прочитав документацию Apple, я попытался использовать метод beginBackgroundTaskWithExpirationHandler:. При вызове этого метода приложение должно запросить дополнительное время выполнения (примерно 3 минуты).

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

Я попытался зарегистрировать фоновую задачу, вызвав beginBackgroundTaskWithExpirationHandler, отвечающий на обратный вызов отключения BLE, и обнаружил странное поведение, которое зависит от того, заблокирован ли телефон или нет, когда вызывается beginBackgroundTaskWithExpirationHandler:

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

(Я пробовал с iPhone 6, iPhone 8 Plus, iPhone 5s, все с iOS 12.1.4)

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

Это предполагаемое поведение для фоновых задач? Приостанавливает ли ОС фоновую задачу, если она запущена, когда телефон находится в заблокированном состоянии?

Есть ли другой способ запустить задачу конечной длины продолжительностью 1-2 минуты из обратного вызова, который запускается, когда приложение находится в фоновом режиме, а телефон заблокирован?

Заранее спасибо,


person Andrea Gorrieri    schedule 03.04.2019    source источник
comment
Предполагаемое поведение, в противном случае вы всегда сможете запускать backgroundTask из другой задачи, чтобы приложение продолжало работать. Вы также можете проверить developer.apple.com/documentation/uikit/uiapplication/ сколько времени у вас осталось на это, если вы на самом деле запускаете его с переднего плана.   -  person MartinM    schedule 03.04.2019
comment
Привет MartinM, действительно очень интересное наблюдение. Однако любопытно, что задача остается активной, если запущена, когда приложение находится в фоновом режиме с включенным экраном. В этих настройках я смогу поддерживать работу приложения в фоновом режиме, как вы говорите...   -  person Andrea Gorrieri    schedule 03.04.2019


Ответы (1)


Согласно :

application(_:performFetchWithCompletionHandler:)

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

Таким образом, у вас есть 30 секунд, чтобы выполнить любую задачу в фоновом режиме.

person Mohammad Zaid Pathan    schedule 03.04.2019
comment
Привет Зайд, спасибо за ваш ответ. Похоже, это относится к функции фоновой выборки. В настоящее время эта фоновая функция не активна в моем приложении, вместо этого я использую beginBackgroundTaskWithExpirationHandler:. Может быть, я могу попробовать использовать фоновую выборку для запуска задачи в фоновом режиме, когда периферийное устройство BLE отключается, но, к сожалению, мне нужно больше 30 секунд :( . - person Andrea Gorrieri; 03.04.2019