Background Task — iOS mechanizmus, amely lehetővé teszi az alkalmazás számára, hogy befejezze a megkezdett műveletet a háttérmódba való átlépés után. A rendszer korlátozott időt (legfeljebb 30 másodpercet) biztosít a feladat végrehajtására, majd az alkalmazás kényszerítve felfüggesztésre kerül. A Apple, 2026 szerint az expiration handler használata kötelező követelmény a háttérfeladat helyes befejezéséhez.
Főbb pontok
A Background Task egy iOS szoftvermechanizmus, amely lehetővé teszi az alkalmazás számára, hogy meghosszabbítsa a végrehajtási időt a háttérmódba való átlépés után. Amikor a felhasználó minimalizálja az alkalmazást, a rendszer meghívja a UIApplicationDelegate.applicationDidEnterBackground metódust. Ha ebben a pillanatban egy kritikus művelet (adatmentés, kérelem küldése) fut, az alkalmazás kérhet további időt a beginBackgroundTask segítségével.
A Background Task használata nélkül az alkalmazás 3-5 másodperccel a háttérbe kerülés után kényszerítve felfüggesztésre kerül. Az összes befejezetlen művelet megszakad: az adatok nem mentődnek, a hálózati kérések megszakadnak, az állapotok elvesznek. A Background Task akár 30 másodpercet biztosít az alkalmazásnak ezen műveletek helyes befejezésére.
A beginBackgroundTask az iOS 4.0-ban jelent meg — az első kiadásban, amely támogatta a többfeladatos működést. Az iOS 4 előtt az alkalmazás teljesen bezáródott a Home gomb megnyomásakor. Az iOS 7-től megjelent a Background Fetch és az URLSession background configuration. Az iOS 13-tól kezdve az Apple a BGTaskScheduler-t ajánlja új projektekhez, de a beginBackgroundTask továbbra is releváns a rövid távú műveletekhez.
A beginBackgroundTask a UIApplication metódusa, amely regisztrál egy feladatot és visszaad egy egyedi UIBackgroundTaskIdentifier azonosítót. A rendszer meghosszabbítja a háttérvégrehajtás időzítőjét. Az idő lejártakor az expiration handler meghívásra kerül, majd az alkalmazásnak meg kell hívnia az endBackgroundTask(identifier:) metódust a helyes befejezéshez.
1. lépés — az alkalmazás megkapja a didEnterBackground értesítést. 2. lépés — a beginBackgroundTask(expirationHandler:) meghívásra kerül. 3. lépés — a kritikus művelet (mentés, hálózati kérelem) végrehajtásra kerül. 4. lépés — befejezéskor az endBackgroundTask(identifier:) meghívásra kerül. Ha a művelet nem fejeződik be 30 másodpercen belül — a rendszer meghívja az expiration handlert, és az alkalmazásnak azonnal be kell fejeznie a feladatot.
var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
func startBackgroundTask() {
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
// Expiration handler
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
}
func finishBackgroundTask() {
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
A backgroundTimeRemaining tulajdonság visszaadja a háttérfeladat kényszerített befejezéséig hátralévő másodpercek számát. Az érték valós időben csökken. Ha az alkalmazás nincs a háttérben — DBL_MAX értéket ad vissza. Használja ezt a tulajdonságot a viselkedés igazításához: amikor kevesebb mint 5 másodperc van hátra, szakítsa meg a hosszú műveleteket és mentse az előrehaladást.
Az alkalmazás egyszerre több Background Task-ot is regisztrálhat. Minden feladat saját azonosítót kap. A teljes végrehajtási idő összeadódik — ha 3 feladat van regisztrálva, az alkalmazás akár 90 másodpercet is kaphat. A rendszer azonban korábban is befejezheti az alkalmazást, ha az erőforrások kimerültek vagy az akkumulátor-határ túllépésre került.
Az Expiration handler egy kódblokk, amelyet a rendszer hív meg a háttérfeladatra kiosztott idő lejártakor. Az expiration handler megléte az Apple kötelező követelménye. Enélkül az alkalmazást a rendszer kényszerítve befejezheti, és az adatok elveszhetnek.
Az expiration handler-nek minimális műveleteket kell végrehajtania az alkalmazás állapotának mentéséhez: mentse az aktuális adatokat állandó tárhelyre, hívja meg a endBackgroundTask metódust a megfelelő azonosítóval, és állítsa az azonosítót .invalid értékre. Az expiration handler-en belül tilos új hosszú műveleteket indítani — a végrehajtási idő 1-2 másodpercre korlátozott.
func handleExpiration() {
// Előrehaladás mentése
saveProgressToUserDefaults()
// Aktív hálózati kérések megszakítása
currentTask?.cancel()
// Background Task befejezése
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
// Regisztráció expiration handler-rel
backgroundTaskID = UIApplication.shared.beginBackgroundTask(
withName: "SaveDocument",
expirationHandler: handleExpiration
)
A leggyakoribb hiba a endBackgroundTask meghívásának elmulasztása az expiration handler-en belül. Ebben az esetben a rendszer továbbra is aktívnak tekinti a feladatot, az alkalmazás nem megy Suspended állapotba, és az akkumulátor lemerül. A második hiba hosszú műveletek indítása az expiration handler-en belül. A rendszer befejezheti az alkalmazást azok befejezése előtt, és az adatok elvesznek.
Az expiration handler-ben a végrehajtási idő kritikusan rövid — általában kevesebb mint 1 másodperc. Ezért a handler-en belül nem végezhetők: összetett számítások, hálózati kérések, nagy mennyiségű adat írása CoreData-ba. Csak atomi műveletek: egy kulcs írása UserDefaults-ba, állapotjelző beállítása, endBackgroundTask meghívása.
Nézzük meg a Background Task teljes implementációját egy dokumentum mentésére, amikor az alkalmazás a háttérbe kerül. A példa tartalmazza a feladat regisztrálását, a művelet végrehajtását a hátralévő idő ellenőrzésével és a helyes befejezést az endBackgroundTask segítségével.
A háttérbe kerüléskor az alkalmazás elindítja egy nagy dokumentum mentését. A Background Task akár 30 másodpercet biztosít a műveletre. Ha az idő lejár — az expiration handler elmenti a köztes eredményeket. A mentés befejezése után az endBackgroundTask meghívásra kerül az erőforrások felszabadításához.
class DocumentManager {
private var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
func saveDocumentInBackground(document: Document) {
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
self.saveProgress(document)
self.endBackgroundTask()
}
DispatchQueue.global().async {
document.save()
self.endBackgroundTask()
}
}
private func endBackgroundTask() {
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
}
A háttérben végzett hálózati kérések különös figyelmet igényelnek — az expiration handler megszakíthatja a kérést a válasz megérkezése előtt. Használja az URLSession-t dataTask-kal, és ellenőrizze a backgroundTimeRemaining értéket küldés előtt. Ha kevesebb mint 5 másodperc van hátra — halassza el a küldést az alkalmazás következő ébredéséig.
func sendCriticalData(data: Data) {
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
// Adatok mentése újraküldéshez
saveForRetry(data)
self.endBackgroundTask()
}
let task = URLSession.shared.dataTask(with: request) { _, _, error in
if error != nil {
saveForRetry(data)
}
self.endBackgroundTask()
}
task.resume()
}
Hosszú műveletek esetén figyelje a UIApplication.shared.backgroundTimeRemaining értékét. Ha az érték a küszöb (10 másodperc) alá csökken, szakítsa meg az aktuális műveletet és indítsa el a köztes eredmények mentését. Ez lehetővé teszi a munka helyes befejezését az expiration handler kényszerített meghívása előtt.
A Background Task egy hatékony mechanizmus, de helytelen használata akkumulátor- és teljesítményproblémákhoz vezet. Az Apple ajánlásainak és a közösség által bevált gyakorlatoknak a követése segít elkerülni a tipikus hibákat és biztosítani az alkalmazás stabil működését.
Fejezze be a Background Task-ot a lehető leggyorsabban. A háttérvégrehajtás minden másodperce akkumulátor-energiát fogyaszt. Optimális idő — kevesebb mint 5 másodperc. Ha a művelet tovább tart — fontolja meg a BGTaskScheduler vagy a Background Modes használatát. Ne hosszabbítsa meg mesterségesen a feladatot beginBackgroundTask hívásokkal valós szükség nélkül.
Tárolja a UIBackgroundTaskIdentifier értéket egy osztály vagy struktúra tulajdonságaként. Soha ne adja át globális változóként — ez konfliktusokhoz vezet több feladat esetén. Állítsa az azonosítót .invalid értékre az endBackgroundTask meghívása után a kettős befejezés megelőzésére.
A Xcode Simulator-ban kapcsolja az alkalmazást háttérbe a Home gombbal (Command + Shift + H). Használja a Debug — Simulate Background Fetch funkciót a háttér-ébredés teszteléséhez. Az idő lejártának szimulálásához állítsa be a BACKGROUND_TASK_SIMULATE_EXPIRATION = YES környezeti változót — az expiration handler 5 másodperc után kerül meghívásra.
// Hátralévő idő ellenőrzése a művelet megkezdése előtt
let remaining = UIApplication.shared.backgroundTimeRemaining
guard remaining > 10.0 else {
// Nincs elég idő — feladat elhalasztása
scheduleForNextLaunch()
return
}
// Művelet végrehajtása időellenőrzéssel
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
saveProgress()
self.endBackgroundTask()
}
Az expiration handler elkapja a self értéket — ez retain cycle-t hozhat létre, ha a backgroundTaskID ugyanazon objektum tulajdonságaként van tárolva. Használjon [weak self]-et a lezárásban, vagy tárolja az azonosítót külön. A retain cycle memóriaszivárgáshoz vezet — az objektum nem szabadul fel az alkalmazás befejezéséig.
Az iOS 13 megjelenésével az Apple bemutatta a BGTaskScheduler-t — a régi Background Task API modern helyettesítőjét. Mindkét mechanizmus hasonló feladatokat old meg, de a BGTaskScheduler nagyobb kontrollt és rugalmasságot biztosít. A különbségek megértése segít kiválasztani a megfelelő eszközt az adott forgatókönyvhöz.
| Jellemző | Background Task | BGTaskScheduler |
|---|---|---|
| iOS verzió | 4.0+ | 13.0+ |
| Max. idő | 30 másodperc | 30 mp / 10 perc (processing) |
| Indítás | didEnterBackground | Ütemezés + rendszer |
| Végrehajtás garanciája | Csak háttérbe kerüléskor | A rendszer számára alkalmas időben |
| Expiration handler | Igen, kötelező | Igen, a task.expirationHandler segítségével |
| Internet | Indításkor szükséges | Elérhető a requiresNetworkConnectivity-n keresztül |
| Töltés | Nem szükséges | Opcionális processing esetén |
A beginBackgroundTask olyan rövid távú műveletekhez alkalmas, amelyeket azonnal végre kell hajtani a háttérbe kerüléskor: állapot mentése, hálózati kérelem befejezése, adatok gyorsítótárazása. Az API egyszerű, és nem igényel Info.plist konfigurációt vagy azonosítók regisztrálását. Ideális a 10 másodpercnél rövidebb műveletekhez.
A BGTaskScheduler olyan feladatokhoz alkalmas, amelyek bármikor végrehajthatók: időszakos szinkronizáció, gyorsítótár-tisztítás, widgetek frissítése. A rendszer maga választja ki az optimális időpontot, figyelembe véve a felhasználó viselkedését és az akkumulátor állapotát. Hosszú műveletekhez (akár 10 percig) használja a BGProcessingTask-ot.
Mindkét API használható egy alkalmazásban. Background Task — azonnali műveletekhez a háttérbe kerüléskor (piszkozat mentése). BGTaskScheduler — ütemezett frissítésekhez (szinkronizáció 6 óránként). A felelősségek szétválasztása lehetővé teszi az adatok helyes mentésének és az energiahatékony háttérszolgáltatásnak a garantálását.
Gyakran ismételt kérdések
Igen, a beginBackgroundTask az alkalmazás működése során bármikor meghívható. Azonban a rendszer általi idő kiosztása csak a háttérbe kerülés után kezdődik. Ha az alkalmazás az előtérben van, a beginBackgroundTask hívásának nincs hatása — a backgroundTimeRemaining DBL_MAX értéket ad vissza, és a feladat a háttérbe kerüléskor aktiválódik.
Ha az endBackgroundTask nem kerül meghívásra, a rendszer továbbra is aktívnak tekinti az alkalmazást a háttérben. 30 másodperc után az expiration handler meghívásra kerül, de ha abban sincs endBackgroundTask — az alkalmazás a memóriában marad, fogyasztva az akkumulátort. iOS 13+ esetén a rendszer 3 perc után kényszerítve befejezi az ilyen alkalmazást.
A szabványos idő 30 másodperc. Növelése csak Background Modes segítségével lehetséges: Audio (lejátszás), Location (helymeghatározás), Bluetooth (BLE). Vagy a BGProcessingTask (iOS 13+) segítségével — akár 10 perc töltés és Wi-Fi mellett. A beginBackgroundTask önmagában nem biztosít módot a korlát növelésére.
Igen, az iPadOS teljes mértékben támogatja a beginBackgroundTask-ot az iOS-szel azonos korlátozásokkal. Stage Manager-rel rendelkező iPad-en az alkalmazás tovább maradhat a memóriában — a rendszer ritkábban függeszti fel az alkalmazásokat a nagyobb RAM-mennyiség miatt. De a 30 másodperces korlát a háttérfeladatra továbbra is érvényben marad.
Csatlakoztassa az eszközt a Xcode-hoz, indítsa el az alkalmazást, minimalizálja — a konzolban megjelennek a rendszernaplók. Használja a sysdiagnose funkciót részletes naplók gyűjtéséhez: kényszerítse a sysdiagnose-t az eszközről (Volume Up + Down + Power). A Xcode Debug Navigator-ban kövesse nyomon a háttérfeladatok aktivitását.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is