BGTaskScheduler — este framework-ul Apple pentru planificarea și executarea sarcinilor de fundal în aplicațiile iOS 13 și mai noi. A înlocuit Background Fetch și performFetch învechite, oferind o API unificată pentru lucrul cu operațiile de fundal. Conform Apple Developer Documentation, 2026, framework-ul include două tipuri de sarcini: BGProcessingTask pentru operații lungi și BGAppRefreshTask pentru actualizări scurte de conținut.
Principalele puncte
BGTaskScheduler — este framework-ul de sistem Apple, introdus în iOS 13, care gestionează centralizat executarea sarcinilor de fundal. Înainte de apariția sa, dezvoltatorii foloseau UIApplication backgroundTasks, performFetch și gestionarea evenimentelor în appDelegate, ceea ce ducea la fragmentarea codului și comportament imprevizibil.
Framework-ul funcționează pe principiul planificării întârziate: aplicația înregistrează sarcini cu identificatori unici, iar iOS determină singur momentul optim pentru executarea lor. Sistemul ia în considerare nivelul bateriei, activitatea utilizatorului, starea rețelei și alți factori.
Capabilitățile principale includ lucrul atât cu operații scurte, cât și cu cele lungi de fundal. Spre deosebire de AlarmManager din Android, BGTaskScheduler nu garantează un timp exact de execuție — sistemul își rezervă dreptul de a amâna sarcina dacă condițiile sunt nefavorabile.
BGTaskScheduler utilizează o arhitectură bazată pe handlere. Aplicația înregistrează un handler pentru fiecare tip de sarcină, iar sistemul îl apelează când sosește momentul potrivit. Framework-ul nu execută sarcina direct — doar notifică aplicația că a sosit timpul să o pornească.
Înregistrarea începe cu declararea identificatorului sarcinii în Info.plist prin tabloul BGTaskSchedulerPermittedIdentifiers. Apoi, în codul aplicației, se apelează metoda registerHandler(forTaskWithIdentifier:) cu un closure-handler.
import BackgroundTasks
let taskID = "com.example.app.refresh"
BGTaskScheduler.shared.registerHandler(
forTaskWithIdentifier: taskID,
using: DispatchQueue.global()
) { task in
task.expirationHandler = {
// apelat la forțarea încheierii
}
processBackgroundTask(task as! BGAppRefreshTask)
}
După înregistrare, aplicația trebuie să solicite explicit executarea sarcinii prin submitTaskRequest. Cererea conține identificatorul sarcinii și data celei mai devreme posibile porniri. Sistemul salvează cererea și o procesează când consideră condițiile potrivite.
let request = BGAppRefreshTaskRequest(
identifier: taskID
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 3600)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Eroare de planificare: \(error)")
}
BGTaskScheduler oferă două tipuri principale de sarcini, fiecare destinat propriului scenariu de utilizare. Alegerea tipului corect influențează direct probabilitatea executării cu succes a sarcinii de către sistem.
BGAppRefreshTask este destinată actualizărilor scurte de conținut în fundal: încărcarea datelor noi, sincronizarea cu serverul, actualizarea widget-urilor. Timpul de execuție este limitat la 30 de secunde, după care sistemul forțează încheierea sarcinii. Acest tip de sarcini este executat mai frecvent decât BGProcessingTask și are o prioritate mai mare.
BGProcessingTask este destinată operațiilor mai lungi: procesarea fișierelor media, indexarea datelor Core Data, crearea copiilor de rezervă. Sarcina poate dura până la câteva minute, dar sistemul o pornește mai rar și doar în condiții favorabile — conectare la alimentare, Wi-Fi stabil și sarcină redusă a dispozitivului.
| Parametru | BGAppRefreshTask | BGProcessingTask |
|---|---|---|
| Limită de timp | 30 de secunde | câteva minute |
| Frecvența pornirii | ridicată | scăzută |
| Condiții | orice | alimentare + Wi-Fi |
| Necesită alimentare | nu | recomandat |
| Exemplu | actualizare flux | procesare video |
Înregistrarea corectă — este o condiție obligatorie pentru funcționarea BGTaskScheduler. Dacă sarcina nu este înregistrată în Info.plist, sistemul va ignora orice cerere de executare a acesteia.
În fișierul Info.plist se adaugă un tablou BGTaskSchedulerPermittedIdentifiers cu o listă de identificatori text. Fiecare identificator trebuie să fie unic în cadrul aplicației. Apple recomandă utilizarea notației inverse de domeniu.
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.example.app.refresh</string>
<string>com.example.app.processing</string>
</array>
Pentru planificare se folosește metoda submitTaskRequest. Dacă sarcina nu mai este necesară, poate fi anulată prin cancelTaskRequest sau cancelAllTaskRequests. Sistemul anulează automat sarcinile la ștergerea aplicației sau resetarea datelor.
BGTaskScheduler oferă posibilitatea de a urmări starea sarcinilor planificate prin getPendingTaskRequests. Această metodă returnează o listă a tuturor cererilor active cu informații despre tipul, identificatorul și earliestBeginDate. Pentru fiecare cerere se poate verifica dacă a fost deja executată sau anulată și se poate lua o decizie de replanificare.
Este important de reținut că sistemul nu oferă un Callback direct despre succesul executării sarcinii de fundal — handler-ul însuși trebuie să raporteze rezultatul prin proprietățile task. setTaskCompleted permite marcarea sarcinii ca finalizată cu succes, după care sistemul poate porni următoarea sarcină planificată de acest tip. Dacă sarcina nu a apelat setTaskCompleted, sistemul o consideră finalizată la expirarea timpului sau la forțarea încheierii.
Pentru diagnosticarea problemelor se recomandă utilizarea OSLog în handler și vizualizarea logurilor prin Console.app pe Mac. Apple oferă și instrumentul MetricKit pentru analiza performanței sarcinilor de fundal — acesta colectează date despre timpul de execuție, consumul de energie și frecvența pornirilor, care pot fi folosite pentru optimizare.
// Anularea sarcinii specifice
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: taskID)
// Anularea tuturor sarcinilor
BGTaskScheduler.shared.cancelAllTaskRequests()
// Verificarea sarcinilor planificate
BGTaskScheduler.shared.getPendingTaskRequests { requests in
print("Planificate \(requests.count) sarcini")
}
BGTaskScheduler impune restricții stricte asupra muncii în fundal. Sistemul poate amâna sarcina pe o perioadă nedeterminată dacă condițiile sunt nefavorabile. Dezvoltatorul trebuie să înțeleagă că framework-ul nu este destinat sarcinilor în timp real.
Printre limitările cheie: sistemul nu garantează executarea sarcinii la timpul specificat, numărul maxim de sarcini simultane este limitat, iar consumul de energie este strict controlat. Pornirea mai multor sarcini consecutiv poate duce la contopirea sau anularea acestora.
Pentru a crește probabilitatea de executare, se recomandă setarea earliestBeginDate nu mai devreme de 1 oră pentru BGProcessingTask și 15 minute pentru BGAppRefreshTask. De asemenea, este important de gestionat expirationHandler — dacă sarcina nu se încadrează în limită, sistemul apelează acest handler pentru finalizarea corectă. Replanificarea ar trebui să aibă loc în interiorul handler-ului pentru a menține un ciclu continuu de lucru în fundal.
O altă limitare importantă se referă la cererile de rețea. BGTaskScheduler nu garantează existența unei conexiuni active de rețea în timpul executării sarcinii. Aplicația trebuie să verifice singură disponibilitatea rețelei prin NWPathMonitor și să amâne procesarea dacă conexiunea lipsește. Aceasta diferă de Android JobScheduler, care poate activa sarcina doar la conectarea la o rețea de un anumit tip. În practică, dezvoltatorii combină adesea BGTaskScheduler cu sesiuni URL de fundal NSURLSession pentru încărcarea fiabilă a datelor.
Începând cu macOS Catalina, BGTaskScheduler este disponibil și pe Mac. Acest lucru permite crearea de sarcini de fundal cross-platform pentru aplicațiile UIKit rulate pe Apple Silicon. Pe watchOS, framework-ul funcționează limitat — sunt disponibile doar BGAppRefreshTask scurte pentru actualizarea complication și sincronizarea datelor cu iPhone. Dezvoltatorii trebuie să țină cont de diferențele de platformă la planificarea arhitecturii de fundal.
Pentru depanarea BGTaskScheduler, Apple oferă mai multe instrumente. Comanda e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] în lldb forțează pornirea sarcinii de fundal, ignorând restricțiile sistemului. În Xcode este disponibil flag-ul Simulate Background Fetch în meniul Debug, care emulează o actualizare scurtă de fundal. Pentru analiza performanței se folosește MetricKit — acesta colectează informații despre frecvența pornirilor, durata de execuție și consumul de energie al fiecărei sarcini. Aceste date ajută la optimizarea frecvenței de planificare și alegerea tipului corect de sarcină.
În practică, BGTaskScheduler este potrivit pentru actualizarea datelor widget-urilor, sincronizarea iCloud, procesarea notificărilor push cu conținut și indexarea căutării Spotlight. Nu este potrivit pentru trimiterea de analitică în timp real, aplicații de chat sau orice sarcini care necesită executare imediată.
Pentru studiul aprofundat al BGTaskScheduler, Apple recomandă documentația oficială WWDC: sesiunea „Advances in Background Tasks” (2020) acoperă migrarea de la API-urile învechite, iar „Background Tasks in Practice” (2021) conține cazuri reale de utilizare. De asemenea, este utilă secțiunea Energy Efficiency Guide, unde este descris modul în care framework-ul se încadrează în strategia generală de economisire a energiei Apple. Exemplele de cod sunt disponibile în depozitul oficial Apple Developer pe GitHub, cu proiecte complete pentru iOS și macOS.
Întrebări frecvente
Background Fetch era limitat la o singură sarcină de fundal per aplicație și nu avea mecanism de priorități. BGTaskScheduler suportă multiple sarcini de diferite tipuri, oferă o API unificată și gestionare automată a energiei.
Apple nu stabilește o limită explicită pentru numărul de identificatori înregistrați, dar în practică se recomandă utilizarea a nu mai mult de 5–10 sarcini. Un număr mai mare reduce probabilitatea executării fiecărei sarcini din cauza concurenței pentru resursele sistemului.
Pentru depanare, utilizați comanda e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] în lldb. Aceasta forțează pornirea sarcinii, ocolind restricțiile sistemului. De asemenea, este disponibil flag-ul Xcode Simulate Background Fetch în meniul Debug.
Da, BGTaskScheduler poate porni procesul chiar dacă aplicația a fost forțat închisă de utilizator. Cu toate acestea, sistemul poate aplica întârzieri suplimentare și nu toate tipurile de sarcini garantează pornirea în acest scenariu.
Sistemul va apela expirationHandler, transmițând sarcinii un semnal de necesitate de finalizare. Dacă aplicația ignoră acest semnal și continuă lucrul, iOS forțează încheierea procesului. După aceasta, sistemul poate reduce prioritatea tuturor sarcinilor de fundal ale aplicației.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și