Приложение почти готово, но пользователи жалуются на устаревшие данные при переключении между приложениями. Apple строго ограничивает фоновую работу, чтобы сберечь батарею. Мы поможем вам легально и эффективно организовать background-задачи с помощью BGTaskScheduler — единственного официального способа запуска регулярных фоновых задач в iOS 13+. Разберёмся, как избежать типичных ошибок, блокирующих выполнение.
Почему iOS ограничивает фоновые задачи?
iOS агрессивно оптимизирует энергопотребление: приложение, ушедшее в background, получает 30 секунд для завершения текущей работы, затем приостанавливается. BGTaskScheduler предоставляет два типа задач, которые система запускает в подходящие моменты (например, при зарядке или подключении к Wi-Fi). Это в 10 раз надёжнее старых методов вроде UIApplication backgroundTasks, так как система сама балансирует нагрузку и батарею. Около 90% современных iOS-приложений для обновления данных используют именно BGTaskScheduler.
Какие типы задач предлагает BGTaskScheduler?
BGAppRefreshTask — короткая задача (до 30 секунд). Система запускает её при подходящем условии: устройство заряжается или подключено к Wi-Fi, пользователь активен. Подходит для обновления данных интерфейса.
BGProcessingTask — длинная задача (несколько минут). Запускается только при зарядке и Wi-Fi. Подходит для тяжёлых операций: миграция базы данных, загрузка большого контента, переобучение CoreML-модели.
| Параметр | BGAppRefreshTask | BGProcessingTask |
|---|---|---|
| Максимальное время | 30 секунд | Несколько минут |
| Условия запуска | Зарядка или Wi-Fi (необязательно) | Зарядка + Wi-Fi |
| Типичные сценарии | Обновление данных интерфейса | Миграция БД, загрузка контента, ML |
| Частота запуска | До нескольких раз в час | Реже |
Как реализовать регистрацию и планирование?
В Info.plist добавляем идентификаторы задач в BGTaskSchedulerPermittedIdentifiers:
<key>BGTaskSchedulerPermittedIdentifiers</key> <array> <string>com.yourapp.refresh</string> <string>com.yourapp.processing</string> </array> Регистрация в AppDelegate до applicationDidFinishLaunching:
import BackgroundTasks func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { BGTaskScheduler.shared.register( forTaskWithIdentifier: "com.yourapp.refresh", using: nil ) { task in self.handleRefresh(task: task as! BGAppRefreshTask) } BGTaskScheduler.shared.register( forTaskWithIdentifier: "com.yourapp.processing", using: nil ) { task in self.handleProcessing(task: task as! BGProcessingTask) } return true } Планирование — при переходе приложения в background:
func scheduleAppRefresh() { let request = BGAppRefreshTaskRequest(identifier: "com.yourapp.refresh") request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60) try? BGTaskScheduler.shared.submit(request) } func scheduleProcessing() { let request = BGProcessingTaskRequest(identifier: "com.yourapp.processing") request.requiresNetworkConnectivity = true request.requiresExternalPower = true request.earliestBeginDate = Date(timeIntervalSinceNow: 3600) try? BGTaskScheduler.shared.submit(request) } Планировать нужно каждый раз при уходе в background через sceneDidEnterBackground или applicationDidEnterBackground. Один вызов submit — одна постановка задачи в очередь.
Как правильно обрабатывать задачу и expirationHandler?
func handleRefresh(task: BGAppRefreshTask) { scheduleAppRefresh() let syncTask = Task { do { try await DataSyncService.shared.sync() task.setTaskCompleted(success: true) } catch { task.setTaskCompleted(success: false) } } task.expirationHandler = { syncTask.cancel() task.setTaskCompleted(success: false) } } expirationHandler — самая частая ошибка, которую пропускают. Если не вызвать setTaskCompleted до истечения времени, система убивает процесс и помечает приложение как злоупотребляющее background execution. После нескольких таких случаев iOS перестаёт запускать задачи приложения. Около 80% проблем с фоновыми задачами связано с неправильной обработкой этого замыкания. Всегда устанавливайте expirationHandler внутри обработчика, отменяйте все асинхронные операции и вызывайте setTaskCompleted с false. Не забудьте перепланировать задачу на будущее.
Когда система запускает задачи и как их отладить?
Нельзя гарантировать конкретное время запуска — iOS решает сама на основе паттернов использования, заряда батареи, сети. Приложения, которыми пользователь пользуется часто, получают больше фонового времени. Новое приложение или редко используемое — меньше.
Отладка в Xcode: задачи можно принудительно запустить через Debug Menu во время отладки на реальном устройстве:
Xcode → Debug → Simulate Background Fetch Или через lldb:
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.yourapp.refresh"] Симулятор не поддерживает BackgroundTasks — требуется реальное устройство.
Как использовать URLSession для фоновой загрузки?
Для фоновой загрузки и выгрузки файлов BackgroundTasks не нужен — используем URLSessionConfiguration.background(withIdentifier:). Система сама управляет передачей, приложение получает колбэк при завершении через AppDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:). Это работает даже если приложение было выгружено из памяти.
Пошаговая инструкция внедрения:
- Добавьте фоновые режимы в Capabilities.
- Пропишите идентификаторы в Info.plist.
- Зарегистрируйте обработчики в AppDelegate.
- Реализуйте планирование при уходе в фон.
- Напишите логику задачи с expirationHandler.
- Протестируйте на реальном устройстве через Debug.
- Загрузите в App Store Connect и пройдите ревью.
Процесс работы по внедрению фоновых задач
- Настройка provisioning profile и code signing для поддержки фоновых режимов
- Регистрация Permitted Identifiers в Info.plist
- Реализация обработчиков BGAppRefreshTask и BGProcessingTask с корректным expirationHandler
- Интеграция с URLSession background configuration для загрузки файлов
- Планирование задач в соответствии с жизненным циклом приложения
- Отладка на реальных устройствах, настройка APNs при необходимости
- Документация и код-ревью
Сроки и стоимость
| Задача | Срок |
|---|---|
| Реализация BGAppRefreshTask (синхронизация данных) | 1 день |
| Реализация BGProcessingTask (тяжёлые операции) | 1–2 дня |
| URLSession background transfer | +0.5–1 день |
| Полная фоновая инфраструктура | 2–3 дня |
Стоимость рассчитывается индивидуально в зависимости от сложности и объёма работ. Мы гарантируем, что ваше приложение пройдёт App Store Review и будет корректно работать в фоне. Получите консультацию по внедрению фоновых задач — мы оценим ваш проект и предложим оптимальное решение. Свяжитесь с нами, и мы ответим в течение дня. Закажите реализацию фоновых задач у наших экспертов для существенной экономии бюджета и гибкого ценообразования.







