TTimer не работает, пока приложение iOS находится в фоновом режиме

У меня есть приложение, которое должно выполнять некоторые действия на основе TTimer.

Когда приложение становится неактивным (в фоновом режиме), таймер перестает работать.

Я не смог найти никаких подходящих вариантов для UIBackgroundModes.

Как я могу заставить таймер продолжать работать?


person DanielH    schedule 14.01.2016    source источник
comment
Приложение приостанавливается вскоре после перехода в фоновый режим. Вы можете разрешить своему приложению работать в фоновом режиме, но оно все равно будет работать, только если пользователь разрешил приложениям работать в фоновом режиме. Просто узнайте, как это сделать с помощью Xcode/ObjectiveC, после чего вы сможете преобразовать его для использования в своем приложении Delphi.   -  person Hans    schedule 14.01.2016


Ответы (1)


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

В разделе Проект > Параметры > Информация о версии вы можно добавить к ключу массива UIBackgroundModes строковые значения для служб, которые требуют продолжения работы в фоновом режиме. Это добавляется в info.plist для вашего проекта на iOS.

Вы можете обратиться к документация Apple о том, что делают эти значения. . .

  • Значение – описание
  • аудио — приложение воспроизводит звуковой контент в фоновом режиме.
  • местоположение. Приложение предоставляет пользователю информацию о местоположении и требует использования стандартных служб определения местоположения (в отличие от службы определения местоположения со значительными изменениями) для реализации этой функции.
  • voip. Приложение предоставляет услуги передачи голоса по IP. Приложения с этим ключом автоматически запускаются после загрузки системы, чтобы приложение могло восстановить службы VoIP. Приложениям с этим ключом также разрешено воспроизводить фоновый звук.
  • fetch. Приложению регулярно требуется новый контент из сети. Когда это удобно, система запускает или возобновляет работу приложения в фоновом режиме и дает ему небольшое время для загрузки любого нового контента. Это значение поддерживается в iOS 7.0 и более поздних версиях.
  • remote-notification. Приложение использует удаленные уведомления как сигнал о наличии нового контента, доступного для загрузки. Когда поступает удаленное уведомление, система запускает или возобновляет работу приложения в фоновом режиме и дает ему небольшое время для загрузки нового контента. Это значение поддерживается в iOS 7.0 и более поздних версиях.
  • newsstand-content. Приложение обрабатывает контент, который был недавно загружен в фоновом режиме с помощью платформы Newsstand Kit, чтобы контент был готов, когда пользователь этого хочет. Это значение поддерживается в iOS 5.0 и более поздних версиях.
  • external-accessory. Приложение взаимодействует с аксессуаром, который через регулярные промежутки времени передает данные. Это значение поддерживается в iOS 5.0 и более поздних версиях.
  • Bluetooth-central: приложение использует инфраструктуру CoreBluetooth для связи с аксессуаром Bluetooth в фоновом режиме. Это значение поддерживается в iOS 5.0 и более поздних версиях.
  • периферийное устройство Bluetooth. Приложение использует платформу CoreBluetooth для связи в периферийном режиме с аксессуаром Bluetooth. Система предупредит пользователя о потенциальных последствиях для конфиденциальности приложений с этим набором ключей. Дополнительные сведения о конфиденциальности см. в разделе «Рекомендации по сохранению конфиденциальности пользователей». Это значение поддерживается в iOS 6.0 и более поздних версиях.

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

person Jim McKeeth    schedule 15.01.2016
comment
Спасибо за ваш ответ, но, как я уже упоминал, ни одно из значений UIBackgroundModes не кажется актуальным. Мне нужен этот таймер, чтобы продолжать работать. - person DanielH; 16.01.2016
comment
@DanielH, к сожалению, это единственные варианты, предоставляемые Apple. Это ограничение платформы. Я думал, вы имели в виду, что не можете найти какие-либо параметры для установки UIBackgroundMode, поэтому я объяснил, как их установить. - person Jim McKeeth; 16.01.2016
comment
@Tim - Другими словами, нет возможности запустить таймер в фоновом режиме. Ради тестирования я проверил, работает ли служба определения местоположения в фоновом режиме, используя TLocationSensor и установив для параметра UIBackgroundModes значение местоположения, и это тоже не работает. - person DanielH; 16.01.2016
comment
@DanielH Что делает твой таймер? Как узнать, работает ли он? ОС по-прежнему управляет им в фоновом режиме. Например, режим выборки означает, что ваше приложение только время от времени просыпается для получения данных. - person Jim McKeeth; 16.01.2016
comment
@Tim Таймер должен прерывать соединение, и происходит то, что OnTimer запускается только тогда, когда приложение снова становится активным. - person DanielH; 16.01.2016
comment
@DanielH, возможно, есть другое событие, на котором вы могли бы закрыть соединение. - person Jim McKeeth; 18.01.2016
comment
@Tim Соединение должно закрыться через определенный промежуток времени с момента перехода устройства в фоновый режим. Я пытался зациклить TThread с помощью TickService.GetTick, но он также остановился. Я открыт для других идей. - person DanielH; 18.01.2016
comment
@DanielH iOS приостанавливает работу вашего приложения. Вероятно, лучший способ сделать это — использовать режим Fetch, а затем закрыть соединение, когда оно будет возобновлено. Это означает, что он, вероятно, будет оставаться открытым дольше, чем вы хотите, но он наиболее соответствует фоновым режимам работы Apple. Если вам нужно знать, когда приложение перешло в фоновый режим, попросите клиента уведомить сервер о том, что приложение перешло в фоновый режим, а затем, когда приложение просыпается для загрузки, оно может закрыть соединение. - person Jim McKeeth; 18.01.2016
comment
@Tim Я думал пойти по этому пути, но не смог найти, как реализовать событие onFetch. Если я смогу реализовать такое событие, я смогу рассчитать прошедшее время и соответственно отреагировать. - person DanielH; 18.01.2016