Oltre a consentire agli sviluppatori iOS di archiviare facilmente i dati sul cloud, oltre a autenticare gli utenti attraverso i loro robusti SDK, Firebase offre anche una soluzione di archiviazione conveniente per i media. Firebase Storage consente agli sviluppatori di archiviare e recuperare file audio, immagini e video sul cloud. Cioè, Firebase Storage espone un set di SDK per dare agli sviluppatori la possibilità di gestire le risorse di contenuto generate dagli utenti insieme al prodotto di pari livello, il database in tempo reale di Firebase, che memorizza il contenuto del testo dell'utente.
Tuttavia, Firebase Storage è molto più di un semplice contenitore di archiviazione per risorse Rich Media. Assiste gli sviluppatori offrendo la sincronizzazione offline per gli utenti e i loro dispositivi, accodamento e ripresa di immagini e video quando l'utente si spegne e torna online. Funziona in modo simile a come Firebase Realtime Database orchestra la sincronizzazione dei dati dell'utente sul back-end.
Questo tutorial continua dal nostro precedente tutorial su Guida introduttiva all'autenticazione Firebase per iOS, in cui abbiamo esaminato come gestire, archiviare e lavorare con gli utenti in Firebase.
Questo tutorial ti esporrà agli SDK Storage di Firebase, per aiutarti a gestire le risorse multimediali della tua app, ad esempio immagini, file audio e video, archiviandole in remoto sul cloud e recuperandole nell'app. In questo tutorial, imparerai come:
Questo tutorial presume che tu abbia avuto una certa esposizione a Firebase e uno sfondo in via di sviluppo con Swift e Xcode. È anche importante che tu abbia seguito la nostra Guida introduttiva all'autenticazione di Firebase per iOS, poiché dovrai autenticare i tuoi utenti prima di accedere a gran parte della funzionalità di Storage di Firebase, compresi i percorsi degli asset.
Come sviluppatore, puoi utilizzare il database in tempo reale di Firebase per accedere e interagire con il bucket Firebase Storage in modo serverless, senza la necessità di creare e ospitare i tuoi server. Firebase Storage sfrutta il caching locale sul dispositivo per archiviare le risorse quando è offline e serve le risorse quando l'utente torna online, con i dati locali sincronizzati automaticamente.
Gli sviluppatori non devono più fare i conti con la complessità della sincronizzazione di dati e contenuti tramite le librerie di rete iOS standard di Apple e devono affrontare diversi scenari che possono causare interruzioni del trasferimento.
In effetti, i prodotti Firebase riconoscono che gli utenti mobili reali devono affrontare la prospettiva di situazioni interrotte o con segnale basso. Essere in grado di sincronizzare i dati sul dispositivo per il successivo trasferimento rende l'esperienza utente molto migliore, mentre gli sviluppatori risparmiano molto lavoro.
La sicurezza è inoltre fondamentale per Firebase Storage, così come lo è per il resto della suite di prodotti Firebase. Ciò significa che gli sviluppatori possono limitare l'accesso agli elementi di archiviazione autenticando gli utenti tramite l'autenticazione Firebase, che si basa su un modello di sicurezza imperativo che consente il controllo dell'accesso a percorsi, file e metadati in base al ruolo per ruolo..
Infine, le app ospitate su Firebase Storage beneficiano di un'infrastruttura di Google che si ridimensiona man mano che cresce la base di utenti. Esploreremo alcuni di questi concetti più avanti nel tutorial, ma per iniziare, configuriamo la tua app per lavorare con Firebase. Quindi daremo un'occhiata ai puntatori di riferimento di archiviazione.
Se hai già lavorato con Firebase, molto di questo dovrebbe esserti familiare. Altrimenti, dovrai creare un account in Firebase e seguire le istruzioni in Imposta il progetto sezione dell'articolo Inizia con l'autenticazione Firebase per iOS.
Puoi scaricare il codice sorgente completo per questo progetto inserendo il seguente nel terminale:
$ git clone [email protected]: tutsplus / get-started-with-firebase-storage-for-ios.git
Per l'archiviazione, dovremo aggiungere Firebase / Stoccaggio
al nostro Podfile, come mostrato di seguito:
pod 'Firebase / Core' pod 'Firebase / Storage'
Salva e quindi inserisci quanto segue nel tuo terminale per creare i pod:
installazione pod
All'interno di AppDelegate applicazione: didFinishLaunchingWithOptions:
metodo, è presente la seguente riga:
FirebaseApp.configure ()
Assicurati di aver configurato correttamente il tuo progetto tramite la Console Firebase, come descritto nella Imposta il progetto sezione dell'autenticazione Get Startbase Firebase per iOS.
Una volta che l'ambiente è pronto, possiamo passare a dare un'occhiata ai riferimenti di archiviazione, iniziando con la creazione di un puntatore di riferimento.
Usando Firebase Storage, puoi interagire con il tuo cloud bucket, che rappresenta un filesystem delle tue immagini e video memorizzati. Si utilizza quello che viene chiamato riferimento di archiviazione per un particolare percorso o file all'interno di un percorso, all'interno del filesystem a cui si accede alla propria app, in modo da poter interagire con esso trasferendo i dati.
Avere un puntatore a un percorso o un file all'interno del percorso consente di caricare, scaricare, aggiornare o eliminare quel percorso. Per creare un riferimento, devi semplicemente creare un'istanza di Storage.storage ()
, come segue:
lasciare store = Storage.storage () lasciare storeRef = store.reference ()
Ora hai un riferimento alla radice della gerarchia del filesystem, ed è possibile impostare la struttura per il bucket come si desidera, ad esempio creando una struttura di cartelle.
Per accedere a file e percorsi nel tuo bucket, chiama il bambino()
metodo, come segue:
let userProfilesRef = storeRef.child ("images / profiles") ... lascia logoRef = storeRef.child ("images / logo.png")
I riferimenti sono una scorciatoia per il percorso Firebase completo del tuo file tramite il bucket, invece di inserire l'intero percorso URL bucket di Firebase. oltre al bambino()
metodo, puoi anche navigare nella tua gerarchia usando il radice()
e genitore()
metodi, e puoi collegare questi metodi, come vedrai di seguito:
let userProfilesRef = logoRef.parent () ?. child ("profiles")
Come puoi vedere, otterremmo gli stessi risultati per userProfilesRef
come avevamo nel precedente blocco di codice. Il bello dei riferimenti è che sono estremamente leggeri, quindi puoi avere quanti riferimenti all'interno della tua istanza di app vuoi, senza influire sul rendimento della tua app.
Ora che hai compreso gli aspetti fondamentali del lavoro con i riferimenti di Firebase Storage, passiamo al caricamento e al download di file dal tuo bucket.
Il modo più semplice per caricare un file è quello di passare in un NSData
rappresentazione dei suoi contenuti in memoria:
let uploadUserProfileTask = userProfilesRef.child ("\ (userID) .png"). putData (data, metadata: nil) (metadati, errore) in guardia let metadata = metadata else print ("Errore: \ (errore)" ) return print ("url download per profilo è \ (metadata.downloadURL)")
Puoi gestire i tuoi caricamenti in corso controllando quando iniziare, sospendere, riprendere e annullare i tuoi caricamenti. Puoi anche ascoltare gli eventi successivi che vengono attivati, che sono:
Riferimento al uploadUserProfileTask
abbiamo usato prima, puoi controllare i tuoi upload usando i seguenti metodi:
uploadUserProfileTask.pause () uploadUserProfileTask.resume () uploadUserProfileTask.cancel ()
È inoltre possibile monitorare un trasferimento in corso semplicemente impostando un osservatore sull'oggetto istanza dell'attività:
let advanceObserver = uploadUserProfileTask.observe (.progress) snapshot in let percentComplete = 100.0 * Double (snapshot.progress! .completedUnitCount) / Double (snapshot.progress! .totalUnitCount) print (percentComplete)
Vediamo come ti avvicineresti al download di immagini o video dal bucket di archiviazione.
Per poter scaricare e presentare le tue immagini, inizi come hai fatto con il caricamento e dichiara un puntatore di riferimento sul percorso designato. Quindi iniziare il download utilizzando la funzione di chiusura dataWithMaxSize: esecuzione:
:
logoRef.getData (maxSize: 1 * 1024 * 1024) dati, errore in se let error = error print ("Errore \ (errore)") else let logoImage = UIImage (data: data!)
Se utilizzi FirebaseUI, puoi semplicemente avere FirebaseUI gestire il download, la memorizzazione nella cache e la visualizzazione delle immagini per te in un modo ancora più semplice:
... self.imageView.sd_setImage (con: logoRef, placeholderImage: placeholderImage)
Per informazioni sull'implementazione di FirebaseUI, consultare la documentazione di FirebaseUI.
La gestione dei download funziona in modo simile alla gestione e al controllo degli upload. Ecco un esempio:
let downloadTask = storageRef.child ("images / logo.jpg"). write (toFile: localFile) // Sospendi il download downloadTask.pause () // Ripristina download downloadTask.resume () // Annulla download downloadTask.cancel ()
Puoi anche designare un osservatore come abbiamo fatto per i caricamenti, per tenere traccia dell'avanzamento del trasferimento del download in tempo reale:
let advanceObserverDownload = downloadTask.observe (.progress) snapshot in let percentComplete = 100.0 * Double (snapshot.progress! .completedUnitCount) / Double (snapshot.progress! .totalUnitCount) print (percentComplete)
Dotati di una panoramica su come lavorare con i riferimenti e su come caricare e scaricare risorse dal tuo bucket, sei pronto per dare un'occhiata a come implementare Firebase Storage per il nostro progetto di esempio: FirebaseDo.
A questo punto dovresti aver clonato l'app FirebaseDo, quindi vai avanti e costruisci ed esegui il progetto. Vedrai che tutto ciò che fa è autenticare gli utenti, usando il telefono o l'email:
Il nostro obiettivo è migliorare in modo incrementale le funzionalità dell'app, in modo tale che una volta che i nostri utenti si autenticano correttamente, potranno caricare una foto del profilo. La maggior parte del nostro lavoro sarà nel HomeViewController
e il suo Storyboard associato. Affrontiamo il HomeViewController
prima il file.
Prima di entrare nei metodi di questo controller, dovremo aggiungere il UIImagePickerControllerDelegate
protocollo alla nostra classe in modo che possiamo lavorare con i suoi metodi delegati. Dovremo inoltre aggiungere un'istanza di selezione in modo che i nostri utenti possano scegliere una foto dalla loro libreria.
class HomeViewController: UIViewController, FUIAuthDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate @IBOutlet weak var myImageView: UIImageView! let picker = UIImagePickerController () ... fileprivate (set) var auth: Auth? fileprivate (set) var authUI: FUIAuth? // solo impostato internamente ma esternamente fileprivate (set) var authStateListenerHandle: AuthStateDidChangeListenerHandle?
Aggiungi il seguente verso la fine del viewDidLoad ()
metodo:
self.picker.delegate = self self.refreshProfileImage ()
Stiamo andando a implementare il refreshProfileImage ()
metodo, che verrà chiamato per scaricare l'immagine che abbiamo visualizzato nel nostro ViewController. In primo luogo affermiamo che l'utente è autenticato, prima di creare un riferimento che recupera l'immagine del profilo dell'utente dal /images/user_id/profile_photo.jpg percorso nel nostro secchio. Infine, aggiorneremo la nostra vista dell'immagine con l'immagine recuperata.
func refreshProfileImage () if let user = Auth.auth (). currentUser let store = Storage.storage () lascia storeRef = store.reference (). child ("images / \ (user.uid) /profile_photo.jpg" ) storeRef.getData (maxSize: 1 * 1024 * 1024) dati, errore in if let error = error print ("error: \ (error.localizedDescription)") else let image = UIImage (data: data!) self.myImageView.image = image else print ("Devi essere loggato") self.loginAction (sender: self) return
Successivamente, creiamo un @IBAction
metodo per il pulsante della libreria fotografica a cui ci collegheremo a breve dal nostro storyboard:
@IBAction func libraryAction (_ sender: Any) self.picker.allowsEditing = false self.picker.sourceType = .photoLibrary self.picker.mediaTypes = UIImagePickerController.availableMediaTypes (per: .photoLibrary)! self.present (picker, animato: true, completion: print ("handle saving"))
Infine, aggiungiamo due metodi delegati per il nostro UIImagePickerController
, da gestire quando l'utente annulla il UIImagePicker
, oltre a gestire l'immagine selezionata:
func imagePickerControllerDidCancel (_ picker: UIImagePickerController) dismiss (animato: true, completion: nil) func imagePickerController (_ picker: UIImagePickerController, didFinishPickingMediaWithInfo informazioni: [String: Any]) self.dismiss (animato: true, completion: nil) let profileImageFromPicker = info [UIImagePickerControllerOriginalImage] as! UIImage let metadata = StorageMetadata () metadata.contentType = "image / jpeg" let imageData: Data = UIImageJPEGRepresentation (profileImageFromPicker, 0.5)! let store = Storage.storage () let user = Auth.auth (). currentUser se let utente = user let storeRef = store.reference (). child ("images / \ (user.uid) /profile_photo.jpg") ASProgressHud.showHUDAddedTo (self.view, animated: true, type: .default) let _ = storeRef.putData (imageData, metadata: metadata) (metadati, errore) in ASProgressHud.hideHUDForView (self.view, animated: true) guard let _ = metadata else print ("errore si è verificato: \ (error.debugDescription)") return self.myImageView.image = profileImageFromPicker
Una volta che l'utente seleziona un'immagine, ignoriamo il selettore ma conserviamo un riferimento all'immagine selezionata. Successivamente, creiamo a StorageMetadata ()
istanza in modo che possiamo dire a Firebase che stiamo per caricare un file JPEG.
Come abbiamo fatto nel refreshProfileImage ()
metodo, affermeremo che l'utente è autenticato e quindi creare un riferimento al percorso delle immagini in cui vogliamo archiviare il profilo dell'utente. Usando il PutData ()
metodo, quindi carichiamo in modo asincrono la nostra immagine nella posizione del bucket designata, prima di impostare la nostra vista dell'immagine sull'immagine appena selezionata.
Prima di poter creare ed eseguire la nostra app, sarà necessario aggiungere i controlli appropriati al nostro storyboard.
All'interno del nostro storyboard principale, aggiungi una vista immagine con un'immagine segnaposto che rappresenterà il profilo corrente dell'utente, quindi trascina per associare la vista dell'immagine a quella che abbiamo dichiarato come @IBOutlet
nel nostro HomeViewController
classe. Quindi, aggiungi una barra degli strumenti con un pulsante che utilizzerai come @IBAction
chiamare il libraryAction ()
metodo che abbiamo creato in precedenza nel HomeViewController
.
Lo storyboard dovrebbe essere simile al seguente:
In assenza di errori, puoi continuare a creare ed eseguire nuovamente l'app e autenticarti creando un nuovo utente o utilizzando un set di credenziali di un utente esistente.
Ti verrà quindi presentato il HomeViewController
, dove selezioni il + per aggiungere un'immagine dal tuo dispositivo o dalla libreria di foto del simulatore. Una volta scelta una foto, la caricherà nel bucket Firebase. Puoi confermare che è stato caricato con successo andando al Conservazione scheda della tua Firebase Console, come mostrato di seguito:
Se interrompi e riesegui l'app in Xcode, dovresti vedere anche l'immagine che hai caricato l'ultima volta, confermando ulteriormente che abbiamo caricato e scaricato con successo usando Firebase Storage.
Questo tutorial ha dimostrato come sia facile aggiungere storage e gestione delle risorse asincrona a un'app Firebase esistente con solo poche righe di codice. Questo ti offre un modo conveniente per gestire le risorse dell'app, mentre ti consente di gestire la sincronizzazione offline in modo elegante e conveniente.
Firebase Storage è una scelta ovvia per gli sviluppatori iOS che si trovano già all'interno dell'ecosistema Firebase. Fornisce agli sviluppatori la sicurezza di un modello di sicurezza imperativo fornito da Firebase Authentication, così come la capacità fornita dal database Realtime di Firebase.
Mentre sei qui, dai uno sguardo ad alcuni dei nostri altri post sullo sviluppo di app per iOS!