Background Task: concetti chiave, registrazione di attività ed esecuzione in background

Autore: IT Sectr Pubblicato: 2026-03-27 Tempo di lettura: 10 min

Background Task è un meccanismo iOS che consente a un'applicazione di completare un'operazione dopo il passaggio in background. Il sistema alloca un tempo limitato (fino a 30 secondi) per eseguire l'attività, dopodiché l'applicazione viene sospesa forzatamente. Secondo Apple, 2026, l'uso di un expiration handler è un requisito obbligatorio per completare correttamente un'attività in background.

Punti chiave

  • Background Task — un meccanismo iOS per completare operazioni dopo che l'app va in background.
  • beginBackgroundTask — il metodo chiave di UIApplication per registrare un'attività in background.
  • Expiration handler — un blocco di codice chiamato dal sistema quando il tempo allocato scade.
  • Limite di 30 secondi — tempo di esecuzione standard, estendibile tramite Background Modes.
  • UIApplication.shared.endBackgroundTask — una chiamata obbligatoria per completare correttamente l'attività.

Cos'è Background Task in iOS?

Background Task è un meccanismo programmatico iOS che consente a un'applicazione di estendere il tempo di esecuzione dopo il passaggio in background. Quando l'utente minimizza l'app, il sistema chiama UIApplicationDelegate.applicationDidEnterBackground. Se in quel momento è in esecuzione un'operazione critica (salvataggio dati, invio di una richiesta), l'applicazione può richiedere tempo aggiuntivo tramite beginBackgroundTask.

Perché sono necessarie le Background Tasks

Senza utilizzare Background Task, l'applicazione viene sospesa forzatamente entro 3–5 secondi dal passaggio in background. Tutte le operazioni incomplete vengono interrotte: i dati non vengono salvati, le richieste di rete vengono abortite, gli stati vengono persi. Background Task concede all'applicazione fino a 30 secondi per completare correttamente queste operazioni.

  • Salvataggio dello stato — scrittura di dati in CoreData, UserDefaults o file system.
  • Completare richieste di rete — attendere la risposta del server ed elaborare il risultato.
  • Invio di analisi — trasmettere eventi al server di analisi prima della sospensione.
  • Pulizia delle risorse — chiudere descrittori di file, liberare memoria.
  • Caching — scrivere risultati intermedi per il ripristino all'avvio successivo.

Storia ed evoluzione

beginBackgroundTask è apparso in iOS 4.0 — la prima versione con supporto multitasking. Prima di iOS 4, l'applicazione veniva terminata completamente premendo il pulsante Home. iOS 7 ha introdotto Background Fetch e la configurazione in background di URLSession. A partire da iOS 13, Apple raccomanda BGTaskScheduler per i nuovi progetti, ma beginBackgroundTask rimane rilevante per le operazioni a breve termine.

Come funziona beginBackgroundTask: ciclo di vita

beginBackgroundTask è un metodo di UIApplication che registra un'attività e restituisce un identificatore univoco UIBackgroundTaskIdentifier. Il sistema aumenta il timer di esecuzione in background. Quando il tempo scade, viene chiamato l'expiration handler, dopodiché l'applicazione deve chiamare endBackgroundTask(identifier:) per completare correttamente l'attività.

Processo di esecuzione passo dopo passo

Passo 1 — l'applicazione riceve la notifica didEnterBackground. Passo 2 — viene chiamato beginBackgroundTask(expirationHandler:). Passo 3 — viene eseguita l'operazione critica (salvataggio, richiesta di rete). Passo 4 — al completamento, viene chiamato endBackgroundTask(identifier:). Se l'operazione non viene completata entro 30 secondi — il sistema chiama l'expiration handler e l'applicazione deve terminare immediatamente l'attività.

swift
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
}

UIApplication.shared.backgroundTimeRemaining

La proprietà backgroundTimeRemaining restituisce il numero di secondi rimanenti prima che l'attività in background venga terminata forzatamente. Il valore diminuisce in tempo reale. Se l'applicazione non è in background — restituisce DBL_MAX. Utilizza questa proprietà per adattare il comportamento: quando rimangono meno di 5 secondi, interrompi le operazioni lunghe e salva i progressi.

Attività multiple

Un'applicazione può registrare più Background Tasks contemporaneamente. Ogni attività riceve il proprio identificatore. Il tempo totale di esecuzione è cumulativo — se vengono registrate 3 attività, l'applicazione può ottenere fino a 90 secondi. Tuttavia, il sistema può terminare l'applicazione prima se le risorse sono esaurite o il limite della batteria è stato superato.

Expiration handler: gestione obbligatoria del completamento

Expiration handler è un blocco di codice che il sistema chiama quando il tempo allocato per l'attività in background scade. Avere un expiration handler è un requisito obbligatorio di Apple. Senza di esso, l'applicazione può essere terminata forzatamente dal sistema e i dati possono essere persi.

Cosa dovrebbe essere nell'expiration handler

L'expiration handler deve eseguire azioni minime per salvare lo stato dell'applicazione: salvare i dati correnti nell'archivio persistente, chiamare endBackgroundTask con l'identificatore corrispondente e impostare l'identificatore su .invalid. All'interno dell'expiration handler è vietato avviare nuove operazioni lunghe — il tempo di esecuzione è limitato a 1–2 secondi.

swift
func handleExpiration() {
    // Salvataggio dell'avanzamento dell'esecuzione
    saveProgressToUserDefaults()

    // Annullamento delle richieste di rete attive
    currentTask?.cancel()

    // Chiusura di Background Task
    UIApplication.shared.endBackgroundTask(backgroundTaskID)
    backgroundTaskID = .invalid
}

// Registrazione con expiration handler
backgroundTaskID = UIApplication.shared.beginBackgroundTask(
    withName: "SaveDocument",
    expirationHandler: handleExpiration
)

Errori comuni con expiration handler

L'errore più comune è non chiamare endBackgroundTask all'interno dell'expiration handler. In questo caso, il sistema continua a considerare l'attività attiva, l'applicazione non passa allo stato Sospeso e la batteria si scarica. Il secondo errore è avviare operazioni lunghe all'interno dell'expiration handler. Il sistema può terminare l'applicazione prima che vengano completate e i dati andranno persi.

Verifica del tempo rimanente

Nell'expiration handler, il tempo di esecuzione è criticamente limitato — tipicamente meno di 1 secondo. Pertanto, all'interno dell'handler non è possibile eseguire: calcoli complessi, richieste di rete, scrittura di grandi volumi di dati in CoreData. Solo operazioni atomiche: scrivere una singola chiave in UserDefaults, impostare un flag di stato, chiamare endBackgroundTask.

Esempi di codice Background Task in Swift

Esaminiamo un'implementazione completa di Background Task per salvare un documento quando l'app va in background. L'esempio include la registrazione dell'attività, l'esecuzione dell'operazione con verifica del tempo rimanente e il corretto completamento tramite endBackgroundTask.

Salvare un documento con progresso

Quando va in background, l'applicazione avvia il salvataggio di un documento grande. Background Task fornisce fino a 30 secondi per l'operazione. Se il tempo scade — l'expiration handler salva i risultati intermedi. Dopo il completamento del salvataggio, viene chiamato endBackgroundTask per liberare le risorse.

swift
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
    }
}

Inviare dati al server

Le richieste di rete in background richiedono attenzione speciale — l'expiration handler può interrompere la richiesta prima di ricevere una risposta. Utilizza URLSession con dataTask e verifica backgroundTimeRemaining prima di inviare. Se rimangono meno di 5 secondi — rimanda l'invio fino al prossimo ripristino dell'app.

swift
func sendCriticalData(data: Data) {
    backgroundTaskID = UIApplication.shared.beginBackgroundTask {
        // Salvataggio dei dati per il reinvio
        saveForRetry(data)
        self.endBackgroundTask()
    }

    let task = URLSession.shared.dataTask(with: request) { _, _, error in
        if error != nil {
            saveForRetry(data)
        }
        self.endBackgroundTask()
    }
    task.resume()
}

Monitoraggio del tempo rimanente

Per le operazioni lunghe, monitora UIApplication.shared.backgroundTimeRemaining. Se il valore scende al di sotto di una soglia (10 secondi), interrompi l'operazione corrente e inizia a salvare i risultati intermedi. Ciò consente un corretto completamento prima che l'expiration handler venga chiamato forzatamente.

Buone pratiche per l'uso di Background Task

Background Task è un potente meccanismo, ma il suo uso improprio porta a problemi di batteria e prestazioni. Seguire le raccomandazioni di Apple e le pratiche comprovate della comunità aiuterà a evitare errori comuni e garantire un funzionamento stabile dell'applicazione.

Minimizzare il tempo di esecuzione

Completa la Background Task il più rapidamente possibile. Ogni secondo di esecuzione in background consuma batteria. Tempo ottimale — meno di 5 secondi. Se l'operazione richiede più tempo — considera l'uso di BGTaskScheduler o Background Modes. Non prolungare artificialmente l'attività tramite chiamate beginBackgroundTask senza reale necessità.

Uso corretto degli identificatori

Archivia UIBackgroundTaskIdentifier come proprietà di una classe o struttura. Non passarlo mai come variabile globale — questo porta a conflitti con attività multiple. Imposta l'identificatore su .invalid dopo aver chiamato endBackgroundTask per prevenire il doppio completamento.

Test di Background Task

Nel Simulatore Xcode, passa l'applicazione in background tramite il pulsante Home (Comando + Shift + H). Utilizza Debug — Simulate Background Fetch per testare il risveglio in background. Per simulare la scadenza del tempo, imposta la Variabile d'ambiente BACKGROUND_TASK_SIMULATE_EXPIRATION = YES — l'expiration handler verrà chiamato entro 5 secondi.

swift
// Verifica del tempo rimanente prima di iniziare l'operazione
let remaining = UIApplication.shared.backgroundTimeRemaining
guard remaining > 10.0 else {
    // Tempo insufficiente — posticipare l'attività
    scheduleForNextLaunch()
    return
}

// Esecuzione dell'operazione con controllo del tempo
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
    saveProgress()
    self.endBackgroundTask()
}

Evitare i retain cycle

L'expiration handler cattura self — questo può creare un retain cycle se backgroundTaskID è archiviato come proprietà dello stesso oggetto. Utilizza [weak self] nella closure o archivia l'identificatore separatamente. Un retain cycle porta a una perdita di memoria — l'oggetto non verrà rilasciato fino alla terminazione dell'applicazione.

Background Task vs BGTaskScheduler: confronto degli approcci

Con il rilascio di iOS 13, Apple ha presentato BGTaskScheduler — un moderno sostituto della vecchia API Background Task. Entrambi i meccanismi risolvono attività simili, ma BGTaskScheduler offre maggiore controllo e flessibilità. Comprendere le differenze aiuterà a scegliere lo strumento giusto per uno scenario specifico.

CaratteristicaBackground TaskBGTaskScheduler
Versione iOS4.0+13.0+
Tempo massimo30 secondi30 s / 10 min (processing)
IniziazionedidEnterBackgroundPianificazione + sistema
Garanzia di esecuzioneSolo quando si va in backgroundIn qualsiasi momento conveniente per il sistema
Expiration handlerSì, obbligatorioSì, tramite task.expirationHandler
InternetRichiesto all'avvioDisponibile tramite requiresNetworkConnectivity
CaricaNon richiestoOpzionale per processing

Quando usare Background Task

beginBackgroundTask è adatto per operazioni a breve termine che devono essere eseguite immediatamente quando si va in background: salvataggio dello stato, completamento di una richiesta di rete, caching dei dati. L'API è semplice e non richiede configurazione Info.plist o registrazione di identificatori. Ideale per operazioni che richiedono meno di 10 secondi.

Quando usare BGTaskScheduler

BGTaskScheduler è adatto per attività che possono essere eseguite in qualsiasi momento conveniente: sincronizzazione periodica, pulizia della cache, aggiornamento dei widget. Il sistema stesso seleziona il momento ottimale considerando il comportamento dell'utente e lo stato della batteria. Per operazioni lunghe (fino a 10 minuti), utilizza BGProcessingTask.

Uso combinato

Entrambe le API possono essere utilizzate nella stessa applicazione. Background Task — per operazioni immediate quando si va in background (salvare una bozza). BGTaskScheduler — per aggiornamenti pianificati (sincronizzazione ogni 6 ore). La separazione delle responsabilità garantisce la corretta conservazione dei dati e una manutenzione in background efficiente dal punto di vista energetico.

Domande frequenti

Si può chiamare beginBackgroundTask al di fuori di didEnterBackground?

Sì, beginBackgroundTask può essere chiamato in qualsiasi momento durante l'esecuzione dell'applicazione. Tuttavia, l'allocazione del tempo di sistema inizierà solo dopo il passaggio in background. Se l'applicazione è in primo piano, chiamare beginBackgroundTask non ha effetto — backgroundTimeRemaining restituisce DBL_MAX e l'attività verrà attivata quando si va in background.

Cosa succede se non si chiama endBackgroundTask?

Se endBackgroundTask non viene chiamato, il sistema continua a considerare l'applicazione attiva in background. Dopo 30 secondi, l'expiration handler verrà chiamato, ma se anche questo manca di endBackgroundTask — l'applicazione rimane in memoria, scaricando la batteria. In iOS 13+, il sistema termina forzatamente tale applicazione dopo 3 minuti.

Come estendere Background Task oltre 30 secondi?

Il tempo standard è di 30 secondi. Può essere esteso solo tramite Background Modes: Audio (riproduzione), Posizione (geolocalizzazione), Bluetooth (BLE). O tramite BGProcessingTask (iOS 13+) — fino a 10 minuti con carica e Wi-Fi. beginBackgroundTask stesso non fornisce un modo per aumentare il limite.

Background Task funziona su iPad?

Sì, iPadOS supporta completamente beginBackgroundTask con le stesse limitazioni di iOS. Su iPad con Stage Manager, l'applicazione può rimanere più a lungo in memoria — il sistema sospende le applicazioni meno frequentemente a causa della maggiore RAM. Ma il limite di 30 secondi per le attività in background rimane.

Come eseguire il debug di Background Task su un dispositivo reale?

Collega il dispositivo a Xcode, avvia l'applicazione, minimizzala — i log di sistema appariranno nella console. Utilizza sysdiagnose per raccogliere log dettagliati: attiva forzatamente sysdiagnose dal dispositivo (Volume Su + Volume Giù + Accensione). Nel Debug Navigator di Xcode, monitora l'attività delle attività in background.

Riepilogo

  • Background Task — un meccanismo iOS per completare operazioni dopo il passaggio in background, disponibile da iOS 4.0.
  • beginBackgroundTask — un metodo UIApplication che registra un'attività e restituisce un identificatore per il suo completamento.
  • Expiration handler — un blocco di codice obbligatorio chiamato dal sistema quando scade il limite di 30 secondi.
  • endBackgroundTask — una chiamata obbligatoria per completare correttamente l'attività; senza di essa l'applicazione rimane in memoria.
  • BGTaskScheduler — un'alternativa moderna (iOS 13+) con pianificazione, due tipi di attività e condizioni di esecuzione.
  • backgroundTimeRemaining — una proprietà per verificare il tempo rimanente e adattare il comportamento dell'attività.
  • Utilizza Background Task per operazioni immediate a breve termine e BGTaskScheduler per aggiornamenti pianificati in background nei nuovi progetti.

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.

Discuti il progetto

Leggi anche