BGTaskScheduler — это фреймворк от Apple для планирования и выполнения фоновых задач в приложениях iOS 13 и новее. Он пришёл на смену устаревшим Background Fetch и performFetch, предоставив единый API для работы с фоновыми операциями. По данным Apple Developer Documentation, 2026, фреймворк включает два типа задач: BGProcessingTask для длительных операций и BGAppRefreshTask для коротких обновлений контента.
Главное
BGTaskScheduler — это системный фреймворк Apple, представленный в iOS 13, который централизованно управляет выполнением фоновых задач. До его появления разработчики использовали UIApplication backgroundTasks, performFetch и обработку событий в appDelegate, что приводило к фрагментации кода и непредсказуемому поведению.
Фреймворк работает по принципу отложенного планирования: приложение регистрирует задачи с уникальными идентификаторами, а iOS сама определяет оптимальный момент для их выполнения. Система учитывает уровень заряда батареи, активность пользователя, состояние сети и другие факторы.
Основные возможности включают работу как с короткими, так и с длительными фоновыми операциями. В отличие от AlarmManager в Android, BGTaskScheduler не гарантирует точное время выполнения — система оставляет за собой право отложить задачу, если условия неблагоприятны.
BGTaskScheduler использует архитектуру на основе обработчиков (handlers). Приложение регистрирует обработчик для каждого типа задачи, и система вызывает его, когда наступает подходящий момент. Сам фреймворк не выполняет задачу напрямую — он лишь уведомляет приложение, что настало время её запустить.
Регистрация начинается с объявления идентификатора задачи в Info.plist через массив BGTaskSchedulerPermittedIdentifiers. Затем в коде приложения вызывается метод registerHandler(forTaskWithIdentifier:) с замыканием-обработчиком.
import BackgroundTasks
let taskID = "com.example.app.refresh"
BGTaskScheduler.shared.registerHandler(
forTaskWithIdentifier: taskID,
using: DispatchQueue.global()
) { task in
task.expirationHandler = {
// вызывается при принудительном завершении
}
processBackgroundTask(task as! BGAppRefreshTask)
}
После регистрации приложение должно явно запросить выполнение задачи через submitTaskRequest. Запрос содержит идентификатор задачи и дату ближайшего возможного запуска. Система сохраняет запрос и обрабатывает его, когда сочтёт условия подходящими.
let request = BGAppRefreshTaskRequest(
identifier: taskID
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 3600)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Ошибка планирования: \(error)")
}
BGTaskScheduler предоставляет два основных типа задач, каждый из которых предназначен для своего сценария использования. Выбор правильного типа напрямую влияет на вероятность успешного выполнения задачи системой.
BGAppRefreshTask предназначена для коротких фоновых обновлений контента: загрузка новых данных, синхронизация с сервером, обновление виджетов. Время выполнения ограничено 30 секундами, по истечении которых система принудительно завершает задачу. Этот тип задач выполняется чаще, чем BGProcessingTask, и имеет более высокий приоритет.
BGProcessingTask рассчитана на более длительные операции: обработка медиафайлов, индексация данных Core Data, создание резервных копий. Задача может выполняться до нескольких минут, но система запускает её реже и только при благоприятных условиях — подключении к питанию, стабильном Wi-Fi и низкой нагрузке на устройство.
| Параметр | BGAppRefreshTask | BGProcessingTask |
|---|---|---|
| Лимит времени | 30 секунд | несколько минут |
| Частота запуска | высокая | низкая |
| Условия | любые | питание + Wi-Fi |
| Требует питание | нет | рекомендуется |
| Пример | обновление ленты | обработка видео |
Корректная регистрация — это обязательное условие работы BGTaskScheduler. Если задача не зарегистрирована в Info.plist, система проигнорирует любой запрос на её выполнение.
В файл Info.plist добавляется массив BGTaskSchedulerPermittedIdentifiers с перечнем строковых идентификаторов. Каждый идентификатор должен быть уникальным в пределах приложения. Apple рекомендует использовать обратную нотацию домена.
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.example.app.refresh</string>
<string>com.example.app.processing</string>
</array>
Для планирования используется метод submitTaskRequest. Если задача больше не нужна, её можно отменить через cancelTaskRequest или cancelAllTaskRequests. Система также автоматически отменяет задачи при удалении приложения или сбросе данных.
BGTaskScheduler предоставляет возможность отслеживать состояние запланированных задач через getPendingTaskRequests. Этот метод возвращает список всех активных запросов с информацией об их типе, идентификаторе и earliestBeginDate. Для каждого запроса можно проверить, был ли он уже выполнен или отменён, и принять решение о повторном планировании.
Важно учитывать, что система не предоставляет прямого Callback об успешности выполнения фоновой задачи — обработчик сам должен сообщить результат через свойства task. setTaskCompleted позволяет пометить задачу как успешно завершённую, после чего система может запустить следующую запланированную задачу этого типа. Если задача не вызвала setTaskCompleted, система считает её завершённой по истечении времени или при принудительном закрытии.
Для диагностики проблем рекомендуется использовать OSLog в обработчике и просматривать логи через Console.app на Mac. Apple также предоставляет инструмент MetricKit для анализа производительности фоновых задач — он собирает данные о времени выполнения, потреблении энергии и частоте запусков, которые можно использовать для оптимизации.
// Отмена конкретной задачи
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: taskID)
// Отмена всех задач
BGTaskScheduler.shared.cancelAllTaskRequests()
// Проверка запланированных задач
BGTaskScheduler.shared.getPendingTaskRequests { requests in
print("Запланировано \(requests.count) задач")
}
BGTaskScheduler накладывает строгие ограничения на фоновую работу. Система может отложить задачу на неопределённый срок, если условия неблагоприятны. Разработчику важно понимать, что фреймворк не предназначен для задач реального времени.
Среди ключевых ограничений: система не гарантирует выполнение задачи в указанное время, максимальное количество одновременных задач ограничено, а энергопотребление строго контролируется. Запуск нескольких задач подряд может привести к их слиянию или отмене.
Для повышения вероятности выполнения рекомендуется устанавливать earliestBeginDate не раньше чем через 1 час для BGProcessingTask и 15 минут для BGAppRefreshTask. Также важно обрабатывать expirationHandler — если задача не укладывается в лимит, система вызывает этот обработчик для корректного завершения. Повторное планирование должно выполняться внутри самого обработчика, чтобы поддерживать непрерывный цикл фоновой работы.
Ещё одно важное ограничение касается сетевых запросов. BGTaskScheduler не гарантирует наличие активного сетевого соединения во время выполнения задачи. Приложение должно самостоятельно проверять доступность сети через NWPathMonitor и откладывать обработку, если соединение отсутствует. Это отличается от Android JobScheduler, который умеет активировать задачу только при подключении к сети определённого типа. На практике разработчики часто комбинируют BGTaskScheduler с фоновыми URL-сессиями NSURLSession для надёжной загрузки данных.
Начиная с macOS Catalina BGTaskScheduler также доступен на Mac. Это позволяет создавать кроссплатформенные фоновые задачи для UIKit-приложений, запускаемых на Apple Silicon. На watchOS фреймворк работает ограниченно — доступны только короткие BGAppRefreshTask для обновления complication и синхронизации данных с iPhone. Разработчикам важно учитывать платформенные различия при планировании фоновой архитектуры.
Для отладки BGTaskScheduler Apple предоставляет несколько инструментов. Команда e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] в lldb принудительно запускает фоновую задачу, игнорируя системные ограничения. В Xcode доступен флаг Simulate Background Fetch в меню Debug, который эмулирует короткое фоновое обновление. Для анализа производительности используется MetricKit — он собирает информацию о частоте запусков, длительности выполнения и энергопотреблении каждой задачи. Эти данные помогают оптимизировать частоту планирования и выбирать правильный тип задачи.
На практике BGTaskScheduler хорошо подходит для обновления данных виджетов, синхронизации iCloud, обработки push-уведомлений с контентом и индексации поиска Spotlight. Не подходит для отправки аналитики в реальном времени, чат-приложений или любых задач, требующих немедленного выполнения.
Для углублённого изучения BGTaskScheduler Apple рекомендует официальную документацию WWDC: сессия "Advances in Background Tasks" (2020) охватывает миграцию с устаревших API, а "Background Tasks in Practice" (2021) содержит реальные кейсы использования. Также полезен раздел Energy Efficiency Guide, где описано, как фреймворк вписывается в общую стратегию энергосбережения Apple. Примеры кода доступны в официальном репозитории Apple Developer на GitHub с полными проектами для iOS и macOS.
Часто задаваемые вопросы
Background Fetch был ограничен одной фоновой задачей на приложение и не имел механизма приоритетов. BGTaskScheduler поддерживает множество задач с разными типами, предоставляет единый API и автоматическое управление энергопотреблением.
Apple не устанавливает явного ограничения на количество зарегистрированных идентификаторов, но на практике рекомендуется использовать не более 5–10 задач. Большее количество снижает вероятность выполнения каждой конкретной задачи из-за конкуренции за системные ресурсы.
Для отладки используйте команду e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] в lldb. Она принудительно запускает задачу, минуя системные ограничения. Также доступен флаг Xcode Simulate Background Fetch в меню Debug.
Да, BGTaskScheduler может запустить процесс даже если приложение было принудительно закрыто пользователем. Однако системой могут применяться дополнительные задержки, и не все типы задач гарантируют запуск в этом сценарии.
Система вызовет expirationHandler, передав задаче сигнал о необходимости завершиться. Если приложение проигнорирует этот сигнал и продолжит работу, iOS принудительно завершит процесс. После этого система может снизить приоритет всех фоновых задач приложения.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также