Questo tutorial ti insegnerà tutti gli ultimi miglioramenti al multitasking forniti da iOS 7 SDK. In particolare, verranno fornite informazioni sulle API Background Fetch, Remote Notifications e Background Transfer Service. Continuare a leggere!
Con iOS 7, Apple ha messo a disposizione degli sviluppatori tre nuove API multitasking:
Tutte queste API offrono ai programmatori la possibilità di sviluppare applicazioni multitasking che miglioreranno l'utilizzo dell'hardware del dispositivo fornendo agli utenti una maggiore esperienza. Questo tutorial ti insegnerà di più sui tre miglioramenti di cui sopra e quando usarli.
Al fine di rendere il Fetch di sfondo API più facilmente comprensibile, immagina di voler creare un'app di notizie. Ipoteticamente, supponiamo che il contenuto di questa app sia fornito dal web e una delle caratteristiche essenziali è ottenere aggiornamenti ogni volta che l'utente avvia l'app.
Prima di iOS 7, gli sviluppatori potevano far sì che l'app iniziasse a ricevere nuovi contenuti una volta che è stata lanciata. Funziona, ma il lato negativo è che gli utenti dovranno aspettare un po 'ogni volta che l'app inizia. Inoltre, la velocità di connessione del telefono diventa un fattore significativo. Immagina se l'utente si connette tramite una rete cellulare dopo una settimana o due di inattività! Naturalmente, questo non è ciò che gli sviluppatori vogliono, in quanto tende a degradare l'esperienza dell'utente.
Su iOS 7, le cose sono drasticamente cambiate! Con l'API Background Fetch, la nostra ipotetica applicazione può effettivamente scaricare passivamente nuovi contenuti rimanendo sempre in background. iOS 7 riattiverà l'app, fornirà il tempo di esecuzione in background e, quando l'app termina l'aggiornamento, torna a dormire nuovamente. Ovviamente, gli utenti non vengono avvisati quando ciò accade. Semplicemente trovano il nuovo contenuto pronto per l'avvio dell'applicazione.
Il processo di aggiornamento può avvenire a intervalli predefiniti impostati dal programmatore o in intervalli specificati dal sistema operativo. Se si impostano intervalli personalizzati, Apple consiglia di impostarli correttamente e di non recuperare i dati sullo sfondo molto spesso. Ciò causerebbe il consumo della batteria e le risorse di sistema sprecate. Se lasci semplicemente che il sistema operativo gestisca le cose, iOS 7 renderà le previsioni di utilizzo. Lo fa osservando quanto spesso l'app viene lanciata ea che ora. Quindi anticipa questo comportamento andando in linea e recuperando il contenuto prima di prevedere che l'utente lo vorrà. Ad esempio, se un utente della nostra app di notizie ipotetiche lancia l'app ogni pomeriggio, iOS lo osserva e decide che l'app dovrebbe recuperare i contenuti prima o poi nel solito pomeriggio. Molto bello!
Il processo di recupero descritto sopra include tre passaggi:
applicazione: performFetchWithCompletionHandler:
Esaminiamo le cose in modo più dettagliato.
Come ho appena detto, il primo passo dell'intero processo è di abilitare la funzionalità di recupero dello sfondo per l'applicazione in Xcode 5. Ciò può essere fatto in due modi. Il primo modo è usare il .plist
file, dove è necessario aggiungere il Modalità di background richieste
chiave con il andare a prendere
valore, come questo:
I seguenti passaggi sono un approccio alternativo:
Per impostazione predefinita, il valore dell'intervallo di recupero iniziale è impostato su UIApplicationBackgroundFetchIntervalNever
modalità, il che significa che il recupero dello sfondo non verrà mai eseguito. Se questo valore non viene modificato, il recupero dello sfondo non funzionerà, anche se è abilitato con uno dei due metodi sopra discussi. Per realizzare questo, è necessario andare al applicazione: didFinishLaunchingWithOptions:
e imposta il valore minimo dell'intervallo di recupero come segue:
- Applicazione (BOOL): applicazione (UIApplication *) didFinishLaunchingWithOptions: (NSDictionary *) launchOptions [application setMinimumBackgroundFetchInterval: UIApplicationBackgroundFetchIntervalMinimum]; return YES;
Il UIApplicationBackgroundFetchIntervalMinimum
è il valore minimo di intervallo consentito e gestito dal sistema. Naturalmente, puoi impostare un intervallo di tempo personalizzato semplicemente fornendo il metodo sopra con a NSTimeInterval
valore. Tuttavia, a meno che non sia necessario, in genere è meglio consentire a iOS di decidere quando consentire all'app di funzionare in background e recuperare nuovi contenuti. Se si imposta un minimo, è importante rendersi conto che il UIApplicationBackgroundFetchIntervalMinimum
non determina assolutamente i tempi. Sono più come suggerimenti. iOS cercherà di seguire la pianificazione se possibile, ma, a seconda delle risorse di sistema disponibili, il recupero potrebbe verificarsi più o meno spesso di quanto desiderato.
L'ultimo passaggio richiesto è implementare il nuovo aggiunto applicazione: performFetchWithCompletionHandler:
metodo delegato. Questo viene chiamato ogni volta che deve essere eseguito un recupero dello sfondo. Il gestore di completamento del metodo accetta uno dei seguenti tre valori per consentire a iOS di conoscere i risultati del recupero:
UIBackgroundFetchResultNewData
: Se sono stati trovati nuovi dati dal recuperoUIBackgroundFetchResultNoData
: Se non sono stati trovati nuovi datiUIBackgroundFetchResultFailed
: Se si è verificato un errore durante il processo di recuperoVediamo questo in azione:
-(void) application: (applicazione UIApplication *) performFetchWithCompletionHandler: (void (^) (UIBackgroundFetchResult)) completionHandler // Chiama o scrivi qualsiasi codice necessario per ottenere nuovi dati, elaborarli e aggiornare l'interfaccia utente. // La logica per informare iOS sui risultati del recupero in un linguaggio semplice: if (/ ** NEW DATA EXISTS AND WAS SUCCESSFULLY PROCESSED ** /) completionHandler (UIBackgroundFetchResultNewData); if (/ ** NO NEW DATA EXISTS ** /) completionHandler (UIBackgroundFetchResultNoData); if (/ ** ANY ERROR OCCURS ** /) completionHandler (UIBackgroundFetchResultFailed);
Nel caso in cui vengano trovati nuovi dati, è necessario anche apportare gli aggiornamenti dell'interfaccia utente necessari. Questi devono avvenire immediatamente per due motivi: (1) gli utenti dovrebbero vedere il contenuto quando l'app verrà avviata e (2) l'istantanea dell'app rimarrà aggiornata.
Ci sono alcuni altri fatti che dovresti sapere. Innanzitutto, quando l'app viene avviata in background, dispone di circa trenta secondi per completare tutte le attività richieste e chiamare il gestore di completamento. Se viene superato questo limite di tempo, l'app verrà nuovamente sospesa. Per app che richiedono più di 30 secondi (forse a causa di download di contenuti multimediali), è necessario pianificare un recupero in background utilizzando l'API del servizio di trasferimento in background. Discuteremo di questa opzione più tardi.
Dopo aver configurato il meccanismo di recupero e aver lavorato, Apple offre due modi per testare il recupero dello sfondo quando si utilizza il simulatore.
Il primo approccio segue questi passaggi:
In questo modo è utile provare l'API mentre l'app è in esecuzione. Il secondo modo è più coinvolto, ma ti permette di testare l'app mentre rimane sullo sfondo. Per provare questo, attenersi alla seguente procedura:
Lo scaricamento in background è pensato per essere utilizzato per gli aggiornamenti delle app non critici dal momento in cui si verifica potrebbero essere diversi. Per ulteriori aggiornamenti critici, vedere la sezione Notifiche remote in arrivo. In generale, l'API di recupero dello sfondo è adatta per le applicazioni che desiderano gestire senza problemi il contenuto. Alcune categorie di app di esempio includono notizie, social network, meteo e condivisione di foto.
Immagina di creare un'applicazione con tutorial scritti e video. Supponiamo che gli utenti possano scaricare nuovi video tutorial 2-3 volte al mese. Quindi, come renderemmo i nostri utenti consapevoli delle nuove uscite video? Non è possibile adottare una soluzione che utilizzi l'API di recupero dello sfondo o qualcosa di simile, poiché ciò comporterebbe un dispendio di risorse del dispositivo e richieste inutili al server. Inoltre, non possiamo sapere quando una nuova versione del video è pronta. Pertanto, dobbiamo utilizzare le notifiche push, quindi ogni volta che ci sono nuovi contenuti, possiamo informare i nostri utenti semplicemente avvisandoli. Ci aspettiamo che i nostri utenti lancino di conseguenza l'app e scarichino nuovi contenuti. Il problema è che questo approccio costringe l'utente ad attendere il download del video, e se il contenuto è abbastanza grande, potrebbe dover attendere molto tempo. Quindi, come possono gli utenti ottenere nuovi contenuti nella loro applicazione quando questo contenuto è disponibile ma senza aspettare?
È qui che le notifiche remote sono utili. Le notifiche remote sono in realtà notifiche push silenziose, significato di notifiche push che non informano gli utenti sulla loro esistenza. Quando arriva una nuova notifica remota, il sistema riattiva automaticamente l'app in modo che possa gestire la notifica. L'applicazione è quindi responsabile dell'avvio del processo di download per il nuovo contenuto. Al termine del download, a notifica locale viene inviato all'utente. Quando l'applicazione viene avviata, il nuovo contenuto è lì in attesa dell'utente.
Proprio come in Background Fetch, le notifiche remote mirano ad eliminare il tempo di attesa che gli utenti devono affrontare quando scaricano nuovi contenuti o caricano dati su un server. Entrambe le API funzionano all'interno del thread in background e gli utenti ricevono una notifica dopo che il lavoro è stato completato. Tuttavia, le notifiche remote sono adatte nei casi in cui il contenuto viene aggiornato di rado o è altrimenti fondamentale per l'esperienza dell'utente.
Per poter utilizzare le notifiche remote all'interno di un'applicazione, è necessario prima abilitarle. Puoi farlo con il file * .plist o il nuovo funzionalità scheda del progetto. Se si desidera utilizzare il file * .plist, è necessario aggiungere il file Sfondo richiesto chiave con il valore di notifica remota come segue:
Per utilizzare la scheda Funzionalità, attenersi alla seguente procedura:
Il prossimo passo è implementare il applicazione: didReceiveRemoteNotification: fetchCompletionHandler:
metodo delegato nel file AppDelegate. Questo viene chiamato quando arriva una nuova notifica. Utilizza il gestore di completamento per comunicare a iOS il risultato del recupero dati:
-(void) application: (applicazione UIApplication *) didReceiveRemoteNotification: (NSDictionary *) userInfo fetchCompletionHandler: (void (^) (UIBackgroundFetchResult)) completionHandler // Chiama o scrivi qualsiasi codice necessario per scaricare nuovi dati. completionHandler (UIBackgroundFetchResultNewData);
Rendere la notifica silenziosa è abbastanza facile. Nel carico utile della notifica devi solo includere il codice disponibile: 1
segnala e omette tutti i dati di avviso o audio che informerebbero l'utente.
aps content-available: 1
In generale, tutto ciò che è valido quando si lavora con Background Fetch si applica anche qui. Ad esempio, hai 30 secondi al massimo per scaricare qualsiasi nuovo contenuto e avvisare il sistema nel metodo sopra prima che l'app ritorni a dormire. Se il nuovo contenuto ha bisogno di tempo per essere scaricato, quindi prendere in considerazione l'uso del Servizio di trasferimento in background API.
Tieni presente che Apple controlla la velocità del recapito delle notifiche remote (notifiche push silenziose) inviate da un fornitore di servizi di push. Se la frequenza è normale, le notifiche sia normali che tacite vengono consegnate immediatamente. Tuttavia, quando vengono inviate notifiche silenziose abbastanza frequentemente, il servizio Apple Push li memorizza per la consegna in un secondo momento. Assicurati di inviare saggiamente eventuali notifiche remote.
Un'altra grande caratteristica di iOS 7 è il Servizio di trasferimento in background API. Tradizionalmente, ottenere o inviare grandi quantità di dati non è stato facile, principalmente a causa dei limiti di tempo in esecuzione e della gestione dei dati trasferiti. Le applicazioni dovevano completare la maggior parte del processo di caricamento o download mentre erano in primo piano. Tuttavia, con iOS 7, le cose sono completamente diverse. Le applicazioni possono godere di una maggiore libertà quando si eseguono attività in background. Prima di tutto, con il servizio di trasferimento in background, alle applicazioni viene dato tutto il tempo necessario per completare un trasferimento. Se sono in primo piano o sullo sfondo è irrilevante. I limiti di tempo non esistono più e il sistema è ora responsabile della gestione dei dati che vengono caricati o scaricati. Anche se un'applicazione non è in esecuzione, iOS lo attiva per gestire le situazioni in cui è necessario prendere decisioni. Alcuni esempi di ciò includono il completamento del download di un file o la richiesta di ulteriori informazioni al server.
Il servizio di trasferimento in background è basato sul NSURLSession
classe, che è stata appena introdotta con iOS 7. Questa classe è responsabile del trasferimento dei dati tramite HTTP o HTTPS e offre la possibilità di attività relative alla rete in background. L'intera idea alla base è semplice e si basa sull'uso di a sessioni, dove una singola sessione gestisce tutte le attività di trasferimento dati correlate. Sono disponibili vari tipi di sessione, ma il sessioni di background è quello che ci interessa qui, e funziona sempre su thread separati (processi) creati dal sistema. Le sessioni in background supportano sia il download (NSURLSessionDownloadTask
) e caricare (NSURLSesssionUploadTask
) attività, che vengono aggiunte allo sfondo NSURLSession
oggetti.
Un altro fatto degno di nota relativo ai trasferimenti in background è che un trasferimento può essere discrezionale o non discrezionale. I trasferimenti non discrezionali possono essere avviati solo quando l'applicazione è in primo piano, ma esiste un'opzione per impostare lo stato discrezionale in base alle esigenze dell'applicazione. I trasferimenti discrezionali sono per lo più preferiti, poiché consentono al sistema operativo di ottenere una gestione energetica più efficiente sul dispositivo. C'è anche una limitazione che si applica ai trasferimenti discrezionali, e cioè che dovrebbero essere eseguiti solo su reti WiFi. I trasferimenti di thread in background sono sempre avviati come trasferimenti discrezionali.
Il metodo delegato applicazione: handleEventsForBackgroundURLSession: completionHandler:
viene chiamato quando un trasferimento in background viene completato in modo che l'attività completata possa essere gestita. Ad esempio, se il nuovo contenuto è stato scaricato, è necessario implementare questo metodo di delega per archiviarlo in modo permanente e aggiornare l'interfaccia utente, se necessario. Questo metodo viene anche chiamato quando sono richieste credenziali dall'app per continuare il trasferimento. Generalmente, in questo metodo delegato si applica tutta la logica necessaria richiesta dall'applicazione quando un processo di download o caricamento è terminato e l'applicazione esiste all'interno del thread in background. Ovviamente, si utilizza il gestore di completamento per informare il sistema quando si è pronti, in modo che possa riattivare l'app.
Il servizio di trasferimento in background è ideale per l'utilizzo in combinazione con il recupero in background e le API di notifica remota. Premesso quanto sopra, diventa chiaro che la best practice consiste nell'utilizzare i metodi delegate del recupero dello sfondo e le notifiche remote a enqueue i tuoi trasferimenti e lascia che il sistema faccia il lavoro. Dopo tutto, a meno che i dati che dovrebbero essere scambiati con il server abbiano un ingombro ridotto, nella maggior parte dei casi i 30 secondi forniti solo ai due metodi delegati citati sono sufficienti per impostare il trasferimento in background e le attività correlate. Utilizzare il NSURLSession
class per definire tutti i trasferimenti che desideri e per assicurarti che la tua app recuperi qualsiasi nuovo contenuto. Inoltre, invierà tutti i dati che devono essere elaborati, indipendentemente dal tempo richiesto.
Le API Background Fetch, Remote Notifications e Background Transfer Service sono caratteristiche che gli sviluppatori vorrebbero vedere molto tempo fa. Fortunatamente, con il rilascio di iOS 7, Apple ha reso più semplice che mai l'elaborazione dei dati delle applicazioni. Da iOS 7 in poi, il contenuto delle app può essere praticamente sempre aggiornato, ma in ultima analisi spetta a ciascuno sviluppatore occuparsi di questo e utilizzare gli strumenti forniti! Buon multitasking e grazie per la lettura!