TGStat
TGStat
Type to search
Advanced channel search
  • flag English
    Site language
    flag Russian flag English flag Uzbek
  • Sign In
  • Catalog
    Channels and groups catalog Regional compilations Thematic compilations Платные каналы Search for channels
    Add a channel/group
  • Ratings
    Rating of channels Rating of groups Posts rating
    Ratings of brands and people
  • Analytics
  • Search by posts
  • Telegram monitoring
  • Promotion
    Advertising through Yandex Business Advertising in channels through TGStat Agency Advertising on TGStat.ru website
Чат о мобильной разработке | Подпишись на канал | Мобильный трудоголик

7 Sep, 08:47

Open in Telegram Share Report

Forward from: Мобильный трудоголик
🔢 Как добиться стабильного выполнения фоновых задач в iOS.

Казалось бы, у вас в кармане суперкомпьютер. Он точно должен уметь выполнять рутинные задачи в фоне, пока вы занимаетесь своими делами. Как cron в Unix, который отлично работает с 1970 года. Но реальность iOS оказалась сложнее.

Автор статьи делится опытом работы с BGTaskScheduler - фреймворком для запуска фоновых задач. Методом проб и ошибок, работая с собственным устройством ему удалось добиться приемлемого уровня надежности фонового выполнения.


Типы фоновых задач в iOS:

Есть три основных типа фоновых задач:

🔵BGAppRefreshTask: короткая задача для обновления. Предназначена для поддержания контента приложения в актуальном состоянии.

🔵BGProcessingTask: для более тяжелой работы, которая может занимать минуты.

🔵BGContinuedProcessingTask: появился в iOS 26. Запускается на переднем плане и может продолжать работу в фоне. Для автоматической синхронизации бесполезен.

Apple не публикует точных числовых ограничений. Реальные лимиты приходится выяснять вручную.


Как запланировать задачи:

Для этого необходимо отправить запрос и зарегистрировать обработчик:

let refresh = BGAppRefreshTaskRequest(identifier: "com.app.refresh")
refresh.earliestBeginDate = lastRun.addingTimeInterval(30 * 60)
try BGTaskScheduler.shared.submit(refresh)

let processing = BGProcessingTaskRequest(identifier: "com.app.process")
processing.earliestBeginDate = lastRun.addingTimeInterval(60 * 60)
try BGTaskScheduler.shared.submit(processing)

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

BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.app.process") { task in
task.expirationHandler = {
cancelWork()
task.setTaskCompleted(success: false)
}

Task {
let ok = await doWork()
task.setTaskCompleted(success: ok)
}
}


Точность планирования:

BGTaskScheduler не похож на cron. Задача может запуститься на несколько часов позже запрошенного времени. На устройстве автора processing задачи чаще запускались ночью на зарядке, а refresh днем, когда телефон активно использовался.

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

Ошибка: выполнение тяжелых операций в refresh задаче. После этого пробуждения стали менее надежными. Apple объясняет это энергетическим бюджетом приложения. Чем больше энергии и трафика потребляет задача, тем реже iOS ее запускает.


Подводные камни планирования:

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

static func shouldSkipSubmit(existingEarliest: Date?, desiredEarliest: Date) -> Bool {
guard let existingEarliest else { return true }
return existingEarliest
Catalog
Channels and groups catalog Channels compilations Search for channels Add a channel/group
Ratings
Rating of Telegram channels Rating of Telegram groups Posts rating Ratings of brands and people
API
API statistics Search API of posts API Callback
Our channels
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Read
Академия TGStat Telegram Research 2019 Telegram Research 2021 Telegram Research 2023
Contacts
Справочный центр Support Email Jobs
Miscellaneous
Terms and conditions Privacy policy Public offer
Our bots
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot