Background Fetch — механізм iOS, який періодично пробуджує додаток у фоні для завантаження свіжого контенту. Система аналізує поведінку користувача та обирає оптимальні вікна для оновлення. Згідно з Apple, 2026, додаток отримує від 30 до 120 секунд на виконання операції, після чого система призупиняє або завершує процес.
Головне
Background Fetch — це API iOS, який дозволяє додатку періодично отримувати нові дані у фоновому режимі. Вперше представлений в iOS 7 разом із механізмом Background App Refresh. Основна мета — щоб контент був актуальним на момент, коли користувач відкриє додаток, без необхідності чекати завантаження.
Push-повідомлення ініціюються сервером — він надсилає сигнал на пристрій, і система вирішує, чи пробуджувати додаток. Background Fetch ініціюється самою iOS на основі патернів використання пристрою. Push краще підходить для термінових повідомлень, Fetch — для планового оновлення контенту (новини, стрічка соціальної мережі).
Background Fetch — один із кількох механізмів фонового виконання в iOS. BGAppRefreshTask (iOS 13+) виконує те саме завдання, але з більш гнучким плануванням. Background Modes (аудіо, місцезнаходження) — для безперервних операцій. Silent Push — сервер-ініційоване оновлення. Fetch залишається актуальним для проектів із підтримкою iOS 12 і нижче.
iOS використовує алгоритм машинного навчання для визначення оптимального часу пробудження додатка. Система аналізує, коли користувач зазвичай відкриває додаток, як довго його використовує та як часто повертається. На основі цих даних iOS обчислює вікна для Background Fetch.
Коли система вирішує пробудити додаток, вона викликає метод application(_:performFetchWithCompletionHandler:) в AppDelegate. Додаток повинен завантажити мінімальний обсяг нових даних і викликати completion handler з одним із трьох статусів: .newData (дані завантажено), .noData (немає нових даних) або .failed (помилка). Статус впливає на частоту майбутніх пробуджень.
Статус .newData повідомляє системі, що оновлення було корисним — iOS може збільшити частоту пробуджень. .noData говорить, що даних немає — частота залишається незмінною або знижується. .failed сигналізує про проблему — система зменшує частоту, щоб не витрачати батарею. Акцент має бути на чесному статусі, а не на примусовому .newData.
| Статус | Значення | Вплив |
|---|---|---|
| .newData | Дані успішно завантажено | Частота може збільшитися |
| .noData | Перевірка не дала нових даних | Частота залишається незмінною |
| .failed | Помилка мережі або сервера | Частота знижується |
Для включення Background Fetch необхідно виконати два кроки: активувати capability в Xcode та встановити мінімальний інтервал у коді. Capability знаходиться в Target — Signing & Capabilities — Background Modes — увімкнути галочку Background Fetch. Без цього кроку система не буде пробуджувати додаток.
Метод UIApplication.shared.setMinimumBackgroundFetchInterval задає мінімальний час у секундах між викликами Fetch. Значення UIApplication.backgroundFetchIntervalMinimum (приблизно 15 хвилин) вказує системі пробуджувати додаток якомога частіше, наскільки це енергоефективно. Встановлення інтервалу в application(_:didFinishLaunchingWithOptions:) є стандартною практикою.
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey : Any]?
)-> Bool {
UIApplication.shared.setMinimumBackgroundFetchInterval(
UIApplication.backgroundFetchIntervalMinimum
)
return true
}
При включенні Background Fetch у Xcode автоматично оновлюється Info.plist — додається ключ UIBackgroundModes зі значенням fetch. Це обов'язковий крок: без нього додаток не отримає виклик performFetchWithCompletionHandler. Перевірити наявність можна через P list Source або Build Settings.
Розглянемо повну реалізацію Background Fetch для додатку новин. Реалізація включає завантаження даних, кешування та виклик completion handler. Код виконується в AppDelegate — єдиному місці, де система викликає fetch.
func application(
_ application: UIApplication,
performFetchWithCompletionHandler handler: @escaping (UIBackgroundFetchResult) -> Void
) {
let url = URL(string: "https://api.example.com/latest")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
handler(.failed)
return
}
do {
let articles = try JSONDecoder().decode([Article].self, from: data)
cacheArticles(articles)
handler(articles.isEmpty ? .noData : .newData)
} catch {
handler(.failed)
}
}.resume()
}
Після завантаження даних через Background Fetch їх необхідно зберегти в локальне сховище — CoreData, UserDefaults або File Manager. При відкритті додатку дані вже мають бути доступні. Використовуйте CoreData з фоновим контекстом для потокобезпечного запису. Після збереження оновіть UI в головному потоці.
func cacheArticles(_ articles: [Article]) {
let container = NSPersistentContainer(name: "AppModel")
container.performBackgroundTask { context in
articles.forEach { article in
let entity = ArticleEntity(context: context)
entity.id = Int64(article.id)
entity.title = article.title
entity.body = article.body
}
try? context.save()
}
}
Для тестування використовуйте Simulator — виберіть Debug — Simulate Background Fetch у Xcode. На фізичному пристрої потрібно почекати, поки система вирішить виконати fetch. Для прискорення можна встановити мінімальний інтервал на 1 хвилину, але система все одно може ігнорувати його при низькому заряді батареї.
Background Fetch має ряд обмежень, які важливо враховувати при проектуванні архітектури додатка. Головне — система повністю контролює частоту викликів, і розробник не може її гарантувати. Навіть при встановленому мінімальному інтервалі система може не викликати fetch годинами.
Система виділяє додатку обмежений час на виконання завдання — зазвичай до 30 секунд. Якщо додаток не викликав completion handler протягом цього часу, система примусово завершує процес і зменшує частоту майбутніх пробуджень. Всі мережеві запити мають бути компактними — не більше 1-2 за виклик.
iOS враховує рівень заряду батареї при плануванні Background Fetch. При заряді нижче 20% частота пробуджень знижується. При ввімкненому режимі Low Power Mode система може повністю вимкнути фонові оновлення для всіх додатків. Користувач також може вимкнути Background App Refresh для конкретного додатка в налаштуваннях.
URLSession, запущена з Background Fetch, працює в стандартному режимі — без підтримки фонових сесій. Для великих завантажень використовуйте URLSession з background configuration. Система продовжить завантаження навіть після завершення fetch, але прогрес не відстежуватиметься до наступного пробудження.
Починаючи з iOS 13, Apple рекомендує BGTaskScheduler як заміну Background Fetch. BGTaskScheduler надає більш гнучке планування, два типи завдань (refresh і processing) та реєстрацію завдань з ідентифікаторами. Міграція включає кілька кроків і рекомендується для всіх нових проектів.
Перший крок — визначити ідентифікатори завдань в Info.plist через ключ BGTaskSchedulerPermittedIdentifiers. Другий — зареєструвати завдання в AppDelegate через BGTaskScheduler.shared.register. Третій — замінити виклик performFetchWithCompletionHandler на обробник, переданий у register. Четвертий — викликати submit для планування завдання.
// Раніше (Background Fetch)
UIApplication.shared.setMinimumBackgroundFetchInterval(
UIApplication.backgroundFetchIntervalMinimum
)
// Після міграції (BGTaskScheduler)
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "com.example.refresh",
using: nil
) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
let request = BGAppRefreshTaskRequest(
identifier: "com.example.refresh"
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
try? BGTaskScheduler.shared.submit(request)
BGTaskScheduler дає більше контролю: BGProcessingTask для тривалих операцій (до 10 хвилин), умови виконання через requiresNetworkConnectivity та requiresExternalPower, expiration handler для graceful завершення. Система також аналізує використання додатка, але розробник може задати більш точні вимоги.
Якщо додаток підтримує iOS 12 і нижче, Background Fetch залишається єдиним варіантом для періодичного оновлення. BGTaskScheduler доступний тільки з iOS 13+. У цьому випадку використовуйте обгортку: перевіряйте доступність BGTaskScheduler через if #available(iOS 13, *) та викликайте відповідний API.
Часто задавані питання
Точна частота не задокументована і залежить від поведінки користувача. Система аналізує, як часто користувач відкриває додаток, і підлаштовує частоту відповідним чином. В середньому при активному використанні fetch може викликатися 1–3 рази на годину. При рідкому використанні — 1–2 рази на день.
Перевірте три умови: Background Fetch capability включена в Xcode, встановлений minimumBackgroundFetchInterval, і користувач не вимкнув Background App Refresh для додатка в налаштуваннях. Також перевірте, що пристрій не в Low Power Mode і рівень заряду батареї вище 20%.
Background Fetch — старий API (iOS 7), BGAppRefreshTask — новий API (iOS 13+). BGAppRefreshTask надає більше контролю: expiration handler, можливість перепланування та перевірки статусу. Background Fetch простіший у реалізації, але менш гнучкий. Apple рекомендує використовувати BGAppRefreshTask для нових проектів.
Не рекомендується. Background Fetch обмежений за часом (до 30 секунд). Для великих завантажень використовуйте URLSession з background configuration — система продовжить завантаження навіть після завершення fetch. Альтернатива — BGProcessingTask (iOS 13+), де доступно до 10 хвилин та умови для зарядки.
Так, кожне пробудження споживає енергію на включення процесора, ініціалізацію мережевого стеку та завантаження даних. iOS оптимізує частоту, щоб мінімізувати вплив. При правильній реалізації — завантаження тільки нових даних, швидкий виклик completion handler — вплив на батарею мінімальний.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також