MXStat
MXStat
Введите текст для поиска
Расширенный поиск каналов
  • Вход на сайт
  • Каталог
    Каталог каналов Региональные подборки Поиск каналов
    Добавить канал
  • Рейтинги
    Рейтинг каналов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Max
Мобильный трудоголик

29 Sep, 12:36

Открыть в Max Поделиться

Как добиться стабильного выполнения фоновых задач в 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 <= desiredEarliest.addingTimeInterval(5)
}


Важно вычислять время от фиксированной точки, а не от текущего момента.

let desiredEarliest = max(
now.addingTimeInterval(60),
lastRun.addingTimeInterval(interval)
)


earliestBeginDate - это нижняя граница, а не расписание. iOS не гарантирует запуск в указанное время.


🔗 Читать подробнее


Вывод:

BGTaskScheduler не надежен как cron. Но добиться стабильного расписания можно. Планируйте задачи с фиксированной точки отсчета. Не пытайтесь бороться с iOS - она сама решает, когда запускать задачи. Используйте несколько типов фоновых задач, чтобы увеличить шансы на запуск. И помните: поведение пользователя и состояние устройства влияют на выполнение сильнее, чем ваш код.

45
Каталог
Каталог каналов Подборки каналов Поиск каналов Добавить канал
Рейтинги
Рейтинг каналов Max
Контакты
Написать в Max Написать в Telegram Написать на почту
Всякая всячина
Пользовательское соглашение Политика конфиденциальности
Наши каналы
MXStat в Telegram MXStat в Max
Наши боты
MXAuthBot MXAnalyticsBot
Made by TGStat