BGTaskScheduler è un framework Apple per pianificare ed eseguire attività in background nelle applicazioni iOS 13 e successive. Ha sostituito i deprecati Background Fetch e performFetch, fornendo un'API unificata per lavorare con operazioni in background. Secondo Apple Developer Documentation, 2026, il framework include due tipi di attività: BGProcessingTask per operazioni lunghe e BGAppRefreshTask per aggiornamenti brevi di contenuto.
Punti chiave
BGTaskScheduler è un framework di sistema Apple introdotto in iOS 13 che gestisce centralmente l'esecuzione di attività in background. Prima della sua introduzione, gli sviluppatori utilizzavano UIApplication backgroundTasks, performFetch e la gestione degli eventi in appDelegate, portando a frammentazione del codice e comportamento imprevedibile.
Il framework opera secondo il principio della pianificazione differita: l'applicazione registra attività con identificatori univoci, e iOS stesso determina il momento ottimale per eseguirle. Il sistema tiene conto del livello della batteria, dell'attività dell'utente, dello stato della rete e di altri fattori.
Le capacità principali includono il lavoro sia con operazioni in background brevi che lunghe. A differenza di AlarmManager su Android, BGTaskScheduler non garantisce un orario di esecuzione preciso — il sistema si riserva il diritto di ritardare un'attività se le condizioni sono sfavorevoli.
BGTaskScheduler utilizza un'architettura basata su handler. L'applicazione registra un handler per ogni tipo di attività, e il sistema lo chiama quando arriva il momento appropriato. Il framework stesso non esegue direttamente l'attività — si limita a notificare all'applicazione che è il momento di eseguirla.
La registrazione inizia dichiarando l'identificatore dell'attività in Info.plist tramite l'array BGTaskSchedulerPermittedIdentifiers. Quindi, nel codice dell'applicazione, viene chiamato il metodo registerHandler(forTaskWithIdentifier:) con una closure come handler.
import BackgroundTasks
let taskID = "com.example.app.refresh"
BGTaskScheduler.shared.registerHandler(
forTaskWithIdentifier: taskID,
using: DispatchQueue.global()
) { task in
task.expirationHandler = {
// chiamato alla terminazione forzata
}
processBackgroundTask(task as! BGAppRefreshTask)
}
Dopo la registrazione, l'applicazione deve richiedere esplicitamente l'esecuzione dell'attività tramite submitTaskRequest. La richiesta contiene l'identificatore dell'attività e la prima data di inizio possibile. Il sistema salva la richiesta e la elabora quando ritiene le condizioni appropriate.
let request = BGAppRefreshTaskRequest(
identifier: taskID
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 3600)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Errore di pianificazione: \(error)")
}
BGTaskScheduler fornisce due tipi principali di attività, ciascuno progettato per il proprio caso d'uso. Scegliere il tipo corretto influisce direttamente sulla probabilità di esecuzione riuscita dell'attività da parte del sistema.
BGAppRefreshTask è progettata per brevi aggiornamenti di contenuto in background: caricare nuovi dati, sincronizzare con il server, aggiornare i widget. Il tempo di esecuzione è limitato a 30 secondi, dopo i quali il sistema termina forzatamente l'attività. Questo tipo di attività viene eseguito più frequentemente di BGProcessingTask e ha priorità più alta.
BGProcessingTask è progettata per operazioni più lunghe: elaborare file multimediali, indicizzare Core Data, creare backup. L'attività può essere eseguita fino a diversi minuti, ma il sistema la avvia meno frequentemente e solo in condizioni favorevoli — collegato all'alimentazione, Wi-Fi stabile e carico del dispositivo basso.
| Parametro | BGAppRefreshTask | BGProcessingTask |
|---|---|---|
| Limite di tempo | 30 secondi | diversi minuti |
| Frequenza di avvio | alta | bassa |
| Condizioni | qualsiasi | alimentazione + Wi-Fi |
| Richiede alimentazione | no | raccomandato |
| Esempio | aggiornamento feed | elaborazione video |
La registrazione corretta è un requisito obbligatorio per il funzionamento di BGTaskScheduler. Se un'attività non è registrata in Info.plist, il sistema ignorerà qualsiasi richiesta di esecuzione.
Il file Info.plist deve includere l'array BGTaskSchedulerPermittedIdentifiers con un elenco di identificatori stringa. Ogni identificatore deve essere univoco all'interno dell'applicazione. Apple raccomanda di utilizzare la notazione inversa del dominio.
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.example.app.refresh</string>
<string>com.example.app.processing</string>
</array>
Per pianificare un'attività, utilizzare il metodo submitTaskRequest. Se un'attività non è più necessaria, può essere cancellata tramite cancelTaskRequest o cancelAllTaskRequests. Il sistema cancella automaticamente anche le attività quando l'applicazione viene eliminata o i dati vengono resettati.
BGTaskScheduler fornisce la possibilità di tracciare lo stato delle attività pianificate tramite getPendingTaskRequests. Questo metodo restituisce un elenco di tutte le richieste attive con informazioni sul loro tipo, identificatore e earliestBeginDate. Per ogni richiesta, è possibile verificare se è già stata completata o cancellata e decidere se riprogrammare.
È importante notare che il sistema non fornisce un callback diretto sul successo di un'attività in background — l'handler stesso deve segnalare il risultato tramite le proprietà dell'attività. setTaskCompleted consente di contrassegnare un'attività come completata con successo, dopo di che il sistema può avviare la successiva attività pianificata di questo tipo. Se un'attività non chiama setTaskCompleted, il sistema la considera completata per timeout o terminazione forzata.
Per la diagnostica, si consiglia di utilizzare OSLog nell'handler e visualizzare i log tramite Console.app su Mac. Apple fornisce anche lo strumento MetricKit per analizzare le prestazioni delle attività in background — raccoglie dati sul tempo di esecuzione, il consumo energetico e la frequenza di avvio che possono essere utilizzati per l'ottimizzazione.
// Cancella attività specifica
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: taskID)
// Cancella tutte le attività
BGTaskScheduler.shared.cancelAllTaskRequests()
// Controlla attività pianificate
BGTaskScheduler.shared.getPendingTaskRequests { requests in
print("\(requests.count) attività pianificate")
}
BGTaskScheduler impone limitazioni rigorose al lavoro in background. Il sistema può ritardare un'attività indefinitamente se le condizioni sono sfavorevoli. Gli sviluppatori devono capire che il framework non è progettato per attività in tempo reale.
Le principali limitazioni includono: il sistema non garantisce l'esecuzione dell'attività all'ora specificata, il numero massimo di attività simultanee è limitato e il consumo energetico è strettamente controllato. Eseguire più attività in successione può portare alla loro fusione o cancellazione.
Per aumentare la probabilità di esecuzione, si consiglia di impostare earliestBeginDate non prima di 1 ora per BGProcessingTask e 15 minuti per BGAppRefreshTask. È anche importante gestire expirationHandler — se un'attività non riesce a rispettare il limite di tempo, il sistema chiama questo handler per una terminazione appropriata. La riprogrammazione deve essere effettuata all'interno dell'handler stesso per mantenere un ciclo continuo di lavoro in background.
Un'altra limitazione importante riguarda le richieste di rete. BGTaskScheduler non garantisce una connessione di rete attiva durante l'esecuzione dell'attività. L'applicazione deve verificare indipendentemente la disponibilità della rete tramite NWPathMonitor e posticipare l'elaborazione se la connessione è assente. Questo differisce da Android JobScheduler, che può attivare un'attività solo quando connesso a un tipo specifico di rete. In pratica, gli sviluppatori spesso combinano BGTaskScheduler con sessioni URL in background NSURLSession per un caricamento affidabile dei dati.
A partire da macOS Catalina, BGTaskScheduler è disponibile anche su Mac. Ciò consente di creare attività in background multipiattaforma per applicazioni UIKit eseguite su Apple Silicon. Su watchOS, il framework ha funzionalità limitate — sono disponibili solo brevi BGAppRefreshTask per aggiornare le complicazioni e sincronizzare i dati con l'iPhone. Gli sviluppatori devono tenere conto delle differenze di piattaforma quando pianificano l'architettura in background.
Apple fornisce diversi strumenti per il debug di BGTaskScheduler. Il comando e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] in lldb avvia forzatamente un'attività in background, bypassando le limitazioni del sistema. Xcode ha un flag Simulate Background Fetch nel menu Debug che simula un breve aggiornamento in background. MetricKit viene utilizzato per l'analisi delle prestazioni — raccoglie informazioni sulla frequenza di avvio, la durata dell'esecuzione e il consumo energetico di ciascuna attività. Questi dati aiutano a ottimizzare la frequenza di pianificazione e scegliere il tipo di attività corretto.
In pratica, BGTaskScheduler è adatto per aggiornare i dati dei widget, la sincronizzazione iCloud, elaborare notifiche push con contenuto e indicizzare per la ricerca Spotlight. Non è adatto per analisi in tempo reale, applicazioni di chat o qualsiasi attività che richieda esecuzione immediata.
Per uno studio approfondito di BGTaskScheduler, Apple raccomanda la documentazione ufficiale del WWDC: la sessione "Advances in Background Tasks" (2020) copre la migrazione dalle API obsolete, e "Background Tasks in Practice" (2021) contiene casi d'uso reali. La sezione Energy Efficiency Guide è anche utile, descrivendo come il framework si inserisce nella strategia complessiva di risparmio energetico di Apple. Esempi di codice sono disponibili nel repository ufficiale Apple Developer su GitHub con progetti completi per iOS e macOS.
Domande frequenti
Background Fetch era limitato a un'attività in background per applicazione e non aveva un meccanismo di priorità. BGTaskScheduler supporta più attività con diversi tipi, fornisce un'API unificata e una gestione automatica dell'energia.
Apple non impone un limite esplicito al numero di identificatori registrati, ma in pratica si raccomanda di non utilizzare più di 5–10 attività. Un numero maggiore riduce la probabilità di esecuzione di ciascuna attività specifica a causa della concorrenza per le risorse di sistema.
Per il debug, utilizzare il comando e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] in lldb. Avvia forzatamente un'attività, bypassando le limitazioni del sistema. Il flag Xcode Simulate Background Fetch nel menu Debug è anche disponibile.
Sì, BGTaskScheduler può avviare un processo anche se l'applicazione è stata chiusa forzatamente dall'utente. Tuttavia, il sistema può applicare ritardi aggiuntivi e non tutti i tipi di attività garantiscono l'esecuzione in questo scenario.
Il sistema chiama expirationHandler, segnalando all'attività che deve terminare. Se l'applicazione ignora questo segnale e continua a funzionare, iOS termina forzatamente il processo. Dopodiché, il sistema può ridurre la priorità di tutte le attività in background dell'applicazione.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche