Застосунок майже готовий, але користувачі скаржаться на застарілі дані при перемиканні між застосунками. 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 — одна постановка завдання в чергу. Розробники на SwiftUI також можуть використовувати BGTaskScheduler, плануючи завдання в AppDelegate або через Combine.
Як правильно обробляти завдання та 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:). Це працює навіть якщо застосунок був вивантажений з пам'яті.
Що входить у впровадження?
- Налаштування provisioning profile та code signing для підтримки фонових режимів
- Реєстрація Permitted Identifiers в Info.plist
- Реалізація обробників BGAppRefreshTask та BGProcessingTask з коректним expirationHandler
- Інтеграція з URLSession background configuration для завантаження файлів
- Планування завдань відповідно до життєвого циклу застосунку
- Налагодження на реальних пристроях, налаштування APNs при необхідності
- Документація та код-рев'ю
- Навчання розробників (опціонально)
- Технічна підтримка протягом 1 місяця після впровадження
Орієнтовні терміни та вартість
| Завдання | Термін |
|---|---|
| Реалізація BGAppRefreshTask (синхронізація даних) | 1 день |
| Реалізація BGProcessingTask (важкі операції) | 1–2 дні |
| URLSession background transfer | +0.5–1 день |
| Повна фонова інфраструктура | 2–3 дні |
Вартість впровадження базової фонової інфраструктури починається від $800. Економія бюджету до 30% при замовленні комплексного рішення. Точна вартість розраховується індивідуально залежно від складності та обсягу робіт. Ми гарантуємо, що ваш застосунок пройде App Store Review і коректно працюватиме у фоні. Наша компанія має 5+ років досвіду в iOS-розробці та виконала понад 50 проєктів із впровадження фонових завдань. Отримайте консультацію з впровадження фонових завдань — ми оцінимо ваш проєкт і запропонуємо оптимальне рішення. Зв'яжіться з нами, і ми відповімо протягом дня. Замовте реалізацію фонових завдань у наших експертів для суттєвої економії бюджету та гнучкого ціноутворення.







