Table of Contents
Perché Background Tasks Matter per iOS App Responsiveness
Gli utenti si aspettano che le applicazioni iOS si sentano istantaneamente-transizioni dovrebbero essere lisce, le interazioni dovrebbero essere immediate e il contenuto dovrebbe essere fresco nel momento in cui l'applicazione è aperta. Raggiungendo questo richiede lavoro di scarico che non ha bisogno di accadere in primo piano. Le attività di sfondo permettono alla vostra applicazione di eseguire operazioni come la sincronizzazione dei dati, il pre-fetching dei contenuti, o la pulizia senza bloccare l'interfaccia utente.
iOS è progettato per dare priorità all'applicazione attuale dell'utente e per uccidere i processi di sfondo quando la memoria o i vincoli di potere richiedono. Pertanto, la comprensione del framework di attività di sfondo introdotto in iOS 13 è essenziale per la costruzione di un'app moderna e ben condotta.
Comprendere l'esecuzione di sfondo in iOS
iOS fornisce diversi meccanismi per il lavoro di sfondo, ciascuno adatto a diversi casi di utilizzo. Il []Il framework [ è l'approccio raccomandato per le attività differibili che non devono accadere in un momento preciso. Funziona avendo le attività di pianificazione del sistema in tempi ottimali, considerando fattori come connettività di rete, livello della batteria e modelli di coinvolgimento dell'utente.
Esistono altre modalità di esecuzione di sfondo per scenari specifici:
- Background fetch[[] – una breve opportunità (circa 30 secondi) per scaricare periodicamente piccole quantità di contenuti.
- I trattamenti in Background[[] – una finestra più lunga (minuti) per attività più pesanti come la manutenzione del database o la potatura degli asset.
- Notifiche di rimuovi[] – svegliando l'app per elaborare carichi di pagamento con la bandiera .
- Scopri di fondo di URLSession[[] – caricando o scaricando i dati anche se l'applicazione è sospesa o terminata.
- VoIP / audio / posizione[[[] – modalità specializzate che mantengono l'applicazione in esecuzione per periodi più lunghi.
Per lavori di sfondo generici che possono essere programmati senza urgenza di fronte all'utente, l'API [ BGTaskScheduler[[] è la scelta migliore. Consolida la pianificazione, riduce il rischio di essere ucciso dal sistema e migliora la durata della batteria rispetto agli approcci più vecchi come .
Componenti chiave del framework BackgroundTasks
- BGProcessingTask[[]] – destinato a compiti che richiedono un notevole tempo, come l'esecuzione di una sincronizzazione completa, la pulizia dei file memorizzati nella cache o l'aggiornamento di un database locale. Il sistema fornisce tali compiti un budget di tempo più grande (minuti) e li pianifica quando le condizioni sono favorevoli (ad esempio, dispositivo su Wi-Fi e ricarica).
- BGAppRefreshTask[[]] – progettato per brevi rinfreschi, tipicamente durando alcuni secondi. Utilizzalo quando l'applicazione ha bisogno di aggiornare i dati dell'interfaccia utente o di recuperare piccole quantità di contenuti in modo che la prossima volta che l'utente apre l'app, mostra informazioni fresche. Il sistema tenta di eseguire queste attività prima che l'utente lanci l'applicazione.
- BGTaskScheduler[[[] – il gestore centrale che registra identificatori, invia richieste e controllo delle mani al tuo gestore quando inizia l'attività.
Entrambi i tipi di attività condividono un ciclo di vita simile: registra, programma, maniglia e riprogramma. Il sistema decide esattamente quando eseguire l'attività; è possibile fornire solo un suggerimento via []. Questo disegno rispetta le risorse del dispositivo dell'utente e impedisce alle applicazioni di eseguire ami in background.
Attuazione delle attività di sfondo – Una guida passo-passo
Per integrare le attività di sfondo nella tua app iOS, è necessario completare diversi passaggi: abilitare la capacità, registrare gli identificatori di attività, pianificare il lavoro, gestire l'esecuzione e gestire la scadenza.
1. Abilitare la capacità delle modalità di sfondo
In XLT, passare al vostro obiettivo ]Signing & Capabilities] scheda e aggiungere il Modalità di sfondo capacità. Controllare almeno Impostazioni di sfondo e/o
2. Identificazione delle attività di registrazione
Ogni compito di sfondo deve avere una stringa identificativa unica, tipicamente in formato DNS inverso (ad esempio, []). Si registra questi identificatori all'inizio del ciclo di lancio dell'app, come in .
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.example.myapp.refresh", using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.example.myapp.cleanup", using: nil) { task in
self.handleDatabaseCleanup(task: task as! BGProcessingTask)
}
return true
}
La chiusura cattura l'oggetto compito; dentro di esso si chiama il proprio gestore. Ricorda di lanciare il compito al tipo concreto appropriato.
3. Pianificare le attività di sfondo
La sottomissione delle richieste dovrebbe accadere quando l'app va sullo sfondo o quando sorge un'esigenza ricorrente. Il [ suggerisce al più presto si desidera che il compito di eseguire, ma il sistema può ritardare ulteriormente.
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "com.example.myapp.refresh")
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60) // at least 15 minutes from now
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error.localizedDescription)")
}
}
func scheduleDatabaseCleanup() {
let request = BGProcessingTaskRequest(identifier: "com.example.myapp.cleanup")
request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 60) // at least 1 hour
request.requiresNetworkConnectivity = true // only run when network is available
request.requiresExternalPower = true // only run when device is charging
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule cleanup: \(error.localizedDescription)")
}
}
Chiamare questi metodi di pianificazione in luoghi appropriati: ad esempio, dopo un'attività di sfondo di successo (per ripristinare il prossimo run) o quando l'utente sospende l'app. Puoi anche chiamarli in risposta alle azioni degli utenti che indicano una necessità di aggiornamenti periodici.
4. Esecuzione delle attività di maniglia
Quando il sistema decide di eseguire un'attività di sfondo, invoca il gestore registrato.
- Impostare un gestore di scadenza che cancella il lavoro in corso e segna l'attività come incompleto se il tempo viene esaurito.
- Eseguire il lavoro effettivo (ad esempio, rete di ricerca, operazioni di database).
- Chiamare una volta che il lavoro termina (o dopo il fallimento).
- Pianificare il prossimo avvenimento dell'attività (a meno che l'attività non sia destinata ad essere one-off).
func handleAppRefresh(task: BGAppRefreshTask) {
// Reschedule the next refresh immediately.
scheduleAppRefresh()
// Set an expiration handler that will be called if the system needs to reclaim time.
task.expirationHandler = {
// Cancel any ongoing operations, clean up resources.
// Do NOT call setTaskCompleted here; the system will mark it as expired.
}
// Perform background work (e.g., fetch new data from server).
fetchLatestData { success in
// After the work completes (or errors), inform the scheduler.
task.setTaskCompleted(success: success)
}
}
Per un BGProcessingTask, il modello è identico ma il budget del tempo è più grande. È inoltre possibile eseguire operazioni più pesanti come la compattazione di un core Data store o le immagini di ridimensionamento.
5. Testare attività di sfondo
Le attività di sfondo sono notoriamente difficili da testare perché il sistema decide quando eseguirle.
- Usa il debugger Xcode: lancia l'app, poi ferma e usa il comando [] (tramite lldb o un menu "Simulare Background Fetch" nel simulatore).
- Per BGProcessingTask, utilizzare la chiamata [ immediatamente dopo la registrazione, quindi mettere l'app in background. Il sistema può eseguirlo in pochi minuti.
- Usa l'approccio in una costruzione di debug: chiama [ e risottomette di attivare i registri di programmazione.
- Monitorare l'esecuzione delle attività impostando i punti di rottura nel tuo gestore e controllando la console per i log.
Migliori Pratiche per l'implementazione di attività di fondo robusto
In seguito a queste linee guida aiuterà la tua app a rimanere reattivo, conservare la batteria e passare App Store recensione.
Progettazione di attività idempote
Assicurarsi che il vostro lavoro sia idempotent – l'esecuzione di più volte produce lo stesso risultato di eseguire una volta. Ad esempio, utilizzare la logica upsert invece di inserire-solo.
Rispettare il Handler di scadenza
Se il sistema costringe la terminazione, tutto il lavoro incompiuto è perso. Nel gestore, annullare qualsiasi attività di rete in corso, sbloccare le serrature e salvare il checkpoint in modo che il prossimo run possa riprendere.
Non esagerare
Richiedere compiti di sfondo solo quando si ha bisogno di aggiornamenti o manutenzione dei contenuti. Ogni presentazione consuma risorse di sistema per la contabilità. Over-scheduling può portare al sistema che frena l'applicazione o rifiuta le attività. Una buona cadenza per BGAppRefreshTask è ogni 15-30 minuti al massimo; BGProcessingTask può funzionare ogni giorno o settimana.
Utilizzare i vincoli
BGProcessingTaskRequest offre e ]. Impostare questi solo quando necessario. Se il vostro compito può funzionare offline, omettere il requisito di rete – il sistema avrà più flessibilità di programmazione e può funzionare prima. Allo stesso modo, richiedendo l'alimentazione esterna ritarda l'attività fino a quando il dispositivo è collegato, che è solo appropriato per il lavoro di CPU / IO pesante.
Mantenere la luce di lavoro in BGAppRefreshTask
Questi compiti hanno alcuni secondi di tempo a parete prima della scadenza. Ritira solo ciò che è necessario per aggiornare il tuo stato dell'interfaccia utente. Le operazioni più pesanti come la migrazione di database o grandi download appartengono a BGProcessingTask.
Prova su dispositivi reali
Il simulatore non riproduce completamente il comportamento di pianificazione delle attività di sfondo. Prova su un dispositivo fisico con batteria variabile, rete e condizioni di ricarica. Utilizzare il Log di energia nell'organizzatore di Xcode per vedere come la tua applicazione influisce sulla durata della batteria.
Errori di maniglia e ri-schedule
Se un'attività di sfondo fallisce (ad esempio, errore di rete), si dovrebbe ancora riprogrammare per un secondo tempo. Utilizzare backoff esponenziale o un intervallo di riprovazione fisso. Non continuare a chiamare senza riprogrammare, perché il sistema può smettere di concedere l'esecuzione completamente.
Pitfalls e risoluzione dei problemi
Qui ci sono problemi frequenti incontrati quando si implementano compiti di sfondo e come risolverli.
Il compito non funziona mai
Possibili ragioni:
- Capacità mancante – verificare che le modalità di sfondo siano abilitate.
- Identifier mismatch – assicurarsi che la stringa utilizzata in [] corrisponda a quella in Info.plist o in .
- Il compito non rispedito – dopo un'attività completa (o fallisce), è necessario programmare di nuovo per le future piste.
- Ritardamenti di sistema – iOS può rinviare l'esecuzione di sfondo se il dispositivo è sotto carico pesante, basso sulla batteria, o in modalità bassa potenza.
Per debug, abilitare logging: impostare ] logging attraverso in una costruzione di debug. Quindi osservare la console per i messaggi sulla pianificazione e l'esecuzione.
Scade spesso
Se il vostro compito spesso raggiunge il gestore di scadenza, significa che state cercando di fare troppo nel tempo consentito. Profiling con Strumenti (Time Profiler) può rivelare strozzature. Spostare operazioni pesanti a BGProcessingTask, o rompere il lavoro in piccoli pezzi e progressi della traccia.
Avvertenze di memoria o Crepe
Utilizzare piscine di autorelease per cappi che creano molti oggetti temporanei. Se l'applicazione si blocca, controllare i log di crash per la risoluzione di bassa memoria. Considerare come un luogo per rilasciare dati memorizzati nella cache.
Tecniche avanzate e considerazioni reali
Per le applicazioni che devono bilanciare la reattività con il lavoro di sfondo, considerare la combinazione di compiti di sfondo con altre funzionalità iOS.
Combinando le attività di sfondo con le notifiche push
Per gli aggiornamenti sensibili al tempo, utilizzare le notifiche remote con il tasto []. Questo risveglia l'applicazione in background per una breve finestra di esecuzione (simile a BGAppRefreshTask). Per gli aggiornamenti deferibili, ricorrere a compiti di sfondo programmati. Questo approccio ibrido garantisce contenuti freschi nel rispetto della durata della batteria.
Sincronizzazione con CloudKit o Dati Core
Quando si esegue la sincronizzazione di sfondo con CloudKit, utilizzare i metodi di ricerca di sfondo accanto a BGAppRefreshTask. Per Dati core, sfruttare il monitoraggio della storia persistente in modo che le importazioni di sfondo non si confliggano con le letture di primo piano.
Monitoraggio delle prestazioni
Utilizzare il Energy Log[] in Xcode (Window > Cresh & Energy > selezionare app > open Energy Log) per vedere quanto spesso le attività di sfondo funzionano, la loro durata e il loro impatto sulla batteria.
Riferimenti esterni
Per uno studio approfondito, consultare queste risorse autorevoli:
- Documentazione dell'apple: SfondoTasks[
- WWDC 2019: Avanzate nell'esecuzione dello sfondo dell'app
- Guida all'applicazione: Esecuzione del fondo (Legacy)
- Raywenderlich: Modalità di sfondo Tutorial
- Utilizzando l'esecuzione del fondo per migliorare l'efficienza energetica[]
Conclusioni
Con l’implementazione di compiti di sfondo con l’ BGTaskScheduler] e BGProcessingTask] / BGAppRefreshTask efficienza]]]] consente di costruire applicazioni iOS che si sentono veloce e reattivando il lavoro di fondo