Background Fetch — mechanizm iOS, który okresowo wybudza aplikację w tle w celu pobrania świeżych treści. System analizuje zachowanie użytkownika i wybiera optymalne okna do aktualizacji. Według danych Apple, 2026, aplikacja otrzymuje od 30 do 120 sekund na wykonanie operacji, po czym system wstrzymuje lub kończy proces.
Najważniejsze
Background Fetch — to API iOS, które pozwala aplikacji okresowo pobierać świeże dane w tle. Po raz pierwszy wprowadzone w iOS 7 wraz z mechanizmem Background App Refresh. Głównym celem jest, aby treść była aktualna w momencie, gdy użytkownik otworzy aplikację, bez konieczności czekania na ładowanie.
Powiadomienia Push są inicjowane przez serwer — wysyła on sygnał na urządzenie, a system decyduje, czy obudzić aplikację, czy nie. Background Fetch jest inicjowany przez samo iOS na podstawie wzorców użytkowania urządzenia. Push lepiej nadaje się do pilnych wiadomości, Fetch — do planowej aktualizacji treści (newsy, kanał mediów społecznościowych).
Background Fetch — jeden z kilku mechanizmów wykonywania w tle w iOS. BGAppRefreshTask (iOS 13+) wykonuje to samo zadanie, ale z bardziej elastycznym planowaniem. Background Modes (audio, lokalizacja) — do operacji ciągłych. Silent Push — aktualizacja inicjowana przez serwer. Fetch pozostaje aktualny dla projektów obsługujących iOS 12 i starsze.
iOS używa algorytmu uczenia maszynowego do określenia optymalnego czasu wybudzenia aplikacji. System analizuje, kiedy użytkownik zazwyczaj otwiera aplikację, jak długo jej używa i jak często wraca. Na podstawie tych danych iOS oblicza okna dla Background Fetch.
Gdy system zdecyduje się obudzić aplikację, wywołuje metodę application(_:performFetchWithCompletionHandler:) w AppDelegate. Aplikacja powinna pobrać minimalną ilość nowych danych i wywołać completion handler z jednym z trzech statusów: .newData (dane pobrane), .noData (brak nowych danych) lub .failed (błąd). Status wpływa na częstotliwość przyszłych wybudzeń.
Status .newData informuje system, że aktualizacja była przydatna — iOS może zwiększyć częstotliwość wybudzeń. .noData mówi, że danych nie ma — częstotliwość pozostaje taka sama lub maleje. .failed sygnalizuje problem — system zmniejsza częstotliwość, aby nie marnować baterii. Należy kłaść nacisk na uczciwy status, a nie na wymuszone .newData.
| Status | Znaczenie | Wpływ |
|---|---|---|
| .newData | Dane pobrane pomyślnie | Częstotliwość może wzrosnąć |
| .noData | Sprawdzenie nie dało nowych danych | Częstotliwość pozostaje taka sama |
| .failed | Błąd sieci lub serwera | Częstotliwość maleje |
Aby włączyć Background Fetch, należy wykonać dwa kroki: aktywować capability w Xcode i ustawić minimalny interwał w kodzie. Capability znajduje się w Target — Signing & Capabilities — Background Modes — zaznaczyć checkbox Background Fetch. Bez tego kroku system nie będzie wybudzać aplikacji.
Metoda UIApplication.shared.setMinimumBackgroundFetchInterval ustawia minimalny czas w sekundach między wywołaniami Fetch. Wartość UIApplication.backgroundFetchIntervalMinimum (około 15 minut) informuje system, aby wybudzał aplikację tak często, jak jest to energooszczędne. Ustawienie interwału w application(_:didFinishLaunchingWithOptions:) to standardowa praktyka.
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey : Any]?
)-> Bool {
UIApplication.shared.setMinimumBackgroundFetchInterval(
UIApplication.backgroundFetchIntervalMinimum
)
return true
}
Po włączeniu Background Fetch w Xcode automatycznie aktualizuje Info.plist — dodaje klucz UIBackgroundModes z wartością fetch. To obowiązkowy krok: bez niego aplikacja nie otrzyma wywołania performFetchWithCompletionHandler. Można sprawdzić obecność przez P list Source lub Build Settings.
Rozważmy pełną implementację Background Fetch dla aplikacji informacyjnej. Implementacja obejmuje pobieranie danych, buforowanie i wywołanie completion handler. Kod wykonuje się w AppDelegate — jedynym miejscu, w którym system wywołuje 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()
}
Po pobraniu danych przez Background Fetch należy je zapisać w lokalnym magazynie — CoreData, UserDefaults lub File Manager. Po otwarciu aplikacji dane powinny być już dostępne. Użyj CoreData z kontekstem tła do bezpiecznego zapisu wątków. Po zapisaniu zaktualizuj interfejs użytkownika w głównym wątku.
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()
}
}
Do testowania użyj Simulator — wybierz Debug — Simulate Background Fetch w Xcode. Na fizycznym urządzeniu trzeba poczekać, aż system zdecyduje się wykonać fetch. Aby przyspieszyć, można ustawić minimalny interwał na 1 minutę, ale system nadal może go ignorować przy niskim poziomie baterii.
Background Fetch ma szereg ograniczeń, które należy uwzględnić przy projektowaniu architektury aplikacji. Najważniejsze — system całkowicie kontroluje częstotliwość wywołań i programista nie może jej zagwarantować. Nawet przy ustawionym minimalnym interwale system może nie wywoływać fetch przez godziny.
System przydziela aplikacji ograniczony czas na wykonanie zadania — zazwyczaj do 30 sekund. Jeśli aplikacja nie wywoła completion handler w tym czasie, system przymusowo kończy proces i zmniejsza częstotliwość przyszłych wybudzeń. Wszystkie zapytania sieciowe powinny być kompaktowe — nie więcej niż 1–2 na wywołanie.
iOS uwzględnia poziom naładowania baterii przy planowaniu Background Fetch. Przy poziomie poniżej 20% częstotliwość wybudzeń maleje. Po włączeniu trybu Low Power Mode system może całkowicie wyłączyć aktualizacje w tle dla wszystkich aplikacji. Użytkownik może również wyłączyć Background App Refresh dla konkretnej aplikacji w ustawieniach.
URLSession uruchomiona z Background Fetch działa w standardowym trybie — bez obsługi sesji tła. Do dużych pobierań użyj URLSession z background configuration. System będzie kontynuować pobieranie nawet po zakończeniu fetch, ale postęp nie będzie śledzony aż do następnego wybudzenia.
Począwszy od iOS 13, Apple zaleca BGTaskScheduler jako zamiennik Background Fetch. BGTaskScheduler zapewnia bardziej elastyczne planowanie, dwa typy zadań (refresh i processing) oraz rejestrację zadań z identyfikatorami. Migracja obejmuje kilka kroków i jest zalecana dla wszystkich nowych projektów.
Pierwszy krok — określić identyfikatory zadań w Info.plist przez klucz BGTaskSchedulerPermittedIdentifiers. Drugi — zarejestrować zadania w AppDelegate przez BGTaskScheduler.shared.register. Trzeci — zastąpić wywołanie performFetchWithCompletionHandler na handler przekazany do register. Czwarty — wywołać submit, aby zaplanować zadanie.
// Wcześniej (Background Fetch)
UIApplication.shared.setMinimumBackgroundFetchInterval(
UIApplication.backgroundFetchIntervalMinimum
)
// Po migracji (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 daje więcej kontroli: BGProcessingTask do długotrwałych operacji (do 10 minut), warunki wykonania przez requiresNetworkConnectivity i requiresExternalPower, expiration handler do łagodnego zakończenia. System również analizuje użycie aplikacji, ale programista może ustawić bardziej precyzyjne wymagania.
Jeśli aplikacja obsługuje iOS 12 i starsze, Background Fetch pozostaje jedyną opcją do okresowej aktualizacji. BGTaskScheduler jest dostępny tylko od iOS 13+. W tym przypadku użyj opakowania: sprawdzaj dostępność BGTaskScheduler przez if #available(iOS 13, *) i wywołuj odpowiednie API.
Często zadawane pytania
Dokładna częstotliwość nie jest udokumentowana i zależy od zachowania użytkownika. System analizuje, jak często użytkownik otwiera aplikację, i dostosowuje częstotliwość odpowiednio. Średnio przy aktywnym użytkowaniu fetch może być wywoływany 1–3 razy na godzinę. Przy rzadkim użytkowaniu — 1–2 razy dziennie.
Sprawdź trzy warunki: Background Fetch capability włączona w Xcode, ustawiony minimumBackgroundFetchInterval, a użytkownik nie wyłączył Background App Refresh dla aplikacji w ustawieniach. Sprawdź również, czy urządzenie nie jest w Low Power Mode i poziom naładowania baterii powyżej 20%.
Background Fetch — stare API (iOS 7), BGAppRefreshTask — nowe API (iOS 13+). BGAppRefreshTask zapewnia większą kontrolę: expiration handler, możliwość przeplanowania i sprawdzania statusu. Background Fetch jest prostszy w implementacji, ale mniej elastyczny. Apple zaleca używanie BGAppRefreshTask dla nowych projektów.
Nie jest zalecane. Background Fetch jest ograniczony czasowo (do 30 sekund). Do dużych pobierań użyj URLSession z background configuration — system będzie kontynuować pobieranie nawet po zakończeniu fetch. Alternatywą jest BGProcessingTask (iOS 13+), gdzie dostępne jest do 10 minut i warunki ładowania.
Tak, każde wybudzenie zużywa energię na włączenie procesora, inicjalizację stosu sieciowego i pobranie danych. iOS optymalizuje częstotliwość, aby zminimalizować wpływ. Przy prawidłowej implementacji — pobieranie tylko nowych danych, szybkie wywołanie completion handler — wpływ na baterię jest minimalny.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również