Naast het inschakelen van iOS-ontwikkelaars om eenvoudig gegevens over de cloud op te slaan, en om gebruikers te authenticeren via hun robuuste SDK's, biedt Firebase ook een handige opslagoplossing voor media. Firebase-opslag stelt ontwikkelaars in staat om audio-, beeld- en videobestanden in de cloud op te slaan en op te halen. Dat wil zeggen dat Firebase Storage een set SDK's presenteert om ontwikkelaars de mogelijkheid te bieden hun door de gebruiker gegenereerde inhoudsitems te beheren naast het broer / zus-product, de Firebase Realtime-database, die de gebruikers-tekstinhoud opslaat.
Firebase-opslag is echter meer dan alleen een opslagcontainer voor rich media-items. Het helpt ontwikkelaars door offline synchronisatie aan te bieden voor gebruikers en hun apparaten, wachtrijen en hervatten van afbeeldingen en video's wanneer de gebruiker online gaat en weer online gaat. Dit werkt op dezelfde manier als hoe Firebase Realtime Database de synchronisatie van gebruikersgegevens orkestreert naar de back-end.
Deze zelfstudie gaat verder in onze vorige zelfstudie over Aan de slag met Firebase-verificatie voor iOS, waar we gekeken hebben naar hoe gebruikers met Firebase kunnen worden beheerd, opgeslagen en met gebruikers kunnen werken.
In deze zelfstudie wordt u blootgesteld aan de Firebase Storage SDK's om u te helpen bij het beheren van de mediabestanden van uw app, zoals afbeeldingen, audio- en videobestanden, om ze op afstand op te slaan in de cloud en ze op te halen in uw app. In deze tutorial leert u hoe u:
In deze zelfstudie wordt ervan uitgegaan dat je enige blootstelling hebt ondervonden aan Firebase en een achtergrond hebt ontwikkeld met Swift en Xcode. Het is ook belangrijk dat u eerst onze handleiding Aan de slag met Firebase-authenticatie voor iOS hebt doorlopen, omdat u uw gebruikers moet verifiëren voordat u toegang hebt tot een groot deel van de Firebase-opslagfunctionaliteit, inclusief activapaden.
Als ontwikkelaar kunt u de Firebase Realtime-database gebruiken voor toegang tot en interactie met uw Firebase Storage-bucket op een serverloze manier, zonder dat u uw eigen servers hoeft te maken en hosten. Firebase Storage maakt gebruik van lokale caching op apparaten om activa offline op te slaan en om items weer te geven wanneer de gebruiker weer online komt, waarbij de lokale gegevens automatisch worden gesynchroniseerd.
Ontwikkelaars hebben niet langer te maken met de complexiteit van het synchroniseren van gegevens en inhoud via standaard iOS-netwerkbibliotheken van Apple, en te maken krijgen met meerdere scenario's die overdrachtonderbrekingen kunnen veroorzaken.
In feite herkennen de Firebase-producten dat mobiele gebruikers in de echte wereld worden geconfronteerd met het vooruitzicht van onderbrekingen of situaties met een laag signaal. Gegevens op het apparaat kunnen synchroniseren voor latere overdracht, zorgt voor een veel betere gebruikerservaring en bespaart ontwikkelaars veel werk.
Beveiliging is ook van het grootste belang met Firebase Storage, net als met de rest van de Firebase-suite van producten. Dit betekent dat ontwikkelaars de toegang tot opslagitems kunnen beperken door gebruikers te authenticeren met Firebase-verificatie, die is gebouwd bovenop een imperatief beveiligingsmodel dat de toegang tot paden, bestanden en metadata op basis van rol-voor-rol mogelijk maakt.
Ten slotte profiteren apps die worden gehost op Firebase Storage van een Google-infrastructuur die schaalbaar is naarmate het aantal gebruikers groeit. We zullen een aantal van deze concepten later in de zelfstudie verkennen, maar laten we beginnen met het instellen van uw app om met Firebase te werken. Daarna zullen we kijken naar Storage Reference-pointers.
Als je al eerder met Firebase hebt gewerkt, moet dit voor veel bekend zijn. Anders moet u een account maken in Firebase en de instructies in de Stel het project in deel van het artikel Aan de slag met Firebase-verificatie voor iOS.
U kunt de volledige broncode voor dit project downloaden door het volgende in terminal in te voeren:
$ git clone [email protected]: tutsplus / get-started-with-firebase-storage-for-ios.git
Voor opslag moeten we toevoegen Firebase / Storage
naar onze Podfile, zoals hieronder getoond:
pod 'Firebase / Core' pod 'Firebase / Storage'
Sla op en voer vervolgens het volgende in uw terminal in om de pods te bouwen:
pod installeren
In AppDelegate toepassing: didFinishLaunchingWithOptions:
methode, de volgende regel is aanwezig:
FirebaseApp.configure ()
Controleer of u uw project ook correct hebt geconfigureerd via de Firebase-console, zoals beschreven in de Stel het project in deel van de handleiding Aan de slag met Firebase-authenticatie voor iOS.
Zodra uw omgeving gereed is, kunnen we verder gaan met het bekijken van opslagreferenties, te beginnen met het maken van een referentiepointer.
Met behulp van Firebase-opslag kunt u communiceren met uw eigen cloud-bucket, die een bestandssysteem vertegenwoordigt van uw opgeslagen afbeeldingen en video's. U gebruikt een opslagreferentie voor een bepaald pad of bestand binnen een pad, binnen het bestandssysteem waar u vervolgens uw app toegang tot geeft, zodat u ermee kunt communiceren door gegevens over te zetten.
Als u een pointer naar een pad of bestand in het pad plaatst, kunt u dat pad uploaden, downloaden, bijwerken of verwijderen. Om een referentie te maken, maakt u eenvoudig een instantie van Storage.storage ()
, als volgt:
let store = Storage.storage () laat storeRef = store.reference ()
U hebt nu een verwijzing naar de hoofdmap van uw bestandssysteemhiërarchie en u kunt de structuur voor uw bucket instellen zoals u dat wilt, bijvoorbeeld door een mapstructuur te maken.
Voor toegang tot bestanden en paden in uw bucket, belt u de kind()
methode, als volgt:
laat userProfilesRef = storeRef.child ("images / profiles") ... laat logoRef = storeRef.child ("images / logo.png")
Verwijzingen zijn een afkorting voor het volledige Firebase-pad naar uw bestand via uw bucket, in plaats van dat u uw volledige URL-pad voor Firebase-bucket opgeeft. naast de kind()
methode, kunt u ook navigeren door uw hiërarchie met behulp van de wortel()
en ouder()
methoden, en je kunt deze methoden ketenen, zoals je hieronder zult zien:
laat userProfilesRef = logoRef.parent () ?. child ("profiles")
Zoals je kunt zien, krijgen we dezelfde resultaten voor userProfilesRef
zoals we hadden in het vorige codeblok. Het mooie aan verwijzingen is dat ze extreem licht zijn, zodat je zoveel referenties in je app-instantie kunt hebben als je wilt, zonder de prestaties van je app te beïnvloeden..
Nu u de fundamentele aspecten van het werken met Firebase Storage-referenties begrijpt, gaan we verder met het uploaden en downloaden van bestanden vanuit uw bucket.
De eenvoudigste manier om een bestand te uploaden is door te geven in een NSData
weergave van de inhoud in het geheugen:
laat uploadUserProfileTask = userProfilesRef.child ("\ (userID) .png"). putData (data, metadata: nil) (metadata, error) in guard let metadata = metadata else print ("Fout opgetreden: \ (fout)" ) return print ("download-URL voor profiel is \ (metadata.downloadURL)")
Je kunt je lopende uploads beheren door te bepalen wanneer je uploads moet beginnen, pauzeren, hervatten en annuleren. Je kunt ook luisteren naar de volgende gebeurtenissen die worden geactiveerd, namelijk:
Verwijzen naar de uploadUserProfileTask
we eerder hebben gebruikt, kunt u uw uploads beheren met behulp van de volgende methoden:
uploadUserProfileTask.pause () uploadUserProfileTask.resume () uploadUserProfileTask.cancel ()
U kunt ook een lopende overdracht controleren door eenvoudigweg een waarnemer in te stellen voor het taakinstantieobject:
laat progressObserver = uploadUserProfileTask.observe (.progress) snapshot in let percentComplete = 100.0 * Double (snapshot.progress! .completedUnitCount) / Double (snapshot.progress! .totalUnitCount) print (percentComplete)
Laten we eens kijken hoe u het downloaden van afbeeldingen of video's uit de opslagbunker benadert.
Om uw afbeeldingen te kunnen downloaden en presenteren, begint u zoals bij het uploaden en geeft u een verwijzing naar het door u aangegeven pad. Begin vervolgens met downloaden met de sluitingsfunctie dataWithMaxSize: oplevering:
:
logoRef.getData (maxSize: 1 * 1024 * 1024) gegevens, fout in if let error = error print ("Fout \ (fout)") else let logoImage = UIImage (data: data!)
Als u gebruikmaakt van FirebaseUI, kunt u FirebaseUI eenvoudig het downloaden, cachen en weergeven van afbeeldingen voor u laten beheren op een nog eenvoudiger manier:
... self.imageView.sd_setImage (met: logoRef, placeholderImage: placeholderImage)
Voor informatie over het implementeren van FirebaseUI, raadpleegt u de FirebaseUI-documentatie.
Het beheren van downloads werkt op dezelfde manier als het beheren en beheren van uploads. Hier is een voorbeeld:
laat downloadTask = storageRef.child ("images / logo.jpg"). write (toFile: localFile) // Onderbreek de download downloadTask.pause () // Doorloop de download downloadTask.resume () // Annuleer de download downloadTask.cancel ()
Je kunt ook een observator aanwijzen zoals we die hebben gedaan voor uploads, om de voortgang van de downloadoverdracht in realtime te volgen:
laat progressObserverDownload = downloadTask.observe (.progress) snapshot in let percentComplete = 100.0 * Double (snapshot.progress! .completedUnitCount) / Double (snapshot.progress! .totalUnitCount) print (percentComplete)
Gewapend met een overzicht van hoe u met referenties werkt en hoe u items uit uw bucket kunt uploaden en downloaden, bent u nu klaar om te kijken hoe Firebase-opslag kan worden geïmplementeerd voor ons voorbeeldproject: FirebaseDo.
Je had de FirebaseDo-app nu moeten klonen, dus ga je gang en bouw en run het project. U zult zien dat alles wat het doet authenticeert gebruikers, met behulp van telefoon of e-mail:
Ons doel is om de functionaliteit van de app stapsgewijs te verbeteren, zodat zodra onze gebruikers zich hebben geverifieerd, ze een profielfoto kunnen uploaden. Het grootste deel van ons werk zal in de HomeViewController
en het bijbehorende storyboard. Laten we de HomeViewController
bestand eerst.
Voordat we ingaan op de methoden van deze controller, moeten we de UIImagePickerControllerDelegate
protocol voor onze klas, zodat we kunnen werken met zijn gedelegeerde methoden. We zullen ook een picker-instantie moeten toevoegen, zodat onze gebruikers een foto uit hun bibliotheek kunnen kiezen.
class HomeViewController: UIViewController, FUIAuthDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate @IBOutlet weak var myImageView: UIImageView! let picker = UIImagePickerController () ... fileprivate (set) var auth: Auth? fileprivate (set) var authUI: FUIAuth? // alleen intern ingesteld, maar extern opgehaald (set) var authStateListenerHandle: AuthStateDidChangeListenerHandle?
Voeg het volgende toe aan het einde van de viewDidLoad ()
methode:
self.picker.delegate = self self.refreshProfileImage ()
We gaan het refreshProfileImage ()
methode, die wordt gebruikt om de afbeelding te downloaden die we in onze ViewController hebben weergegeven. We gaan eerst stellen dat de gebruiker inderdaad is geverifieerd voordat een referentie wordt gemaakt die de profielafbeelding van de gebruiker ophaalt uit de /images/user_id/profile_photo.jpg pad in onze emmer. Ten slotte zullen we onze beeldweergave bijwerken met de opgehaalde afbeelding.
func refreshProfileImage () if let user = Auth.auth (). currentUser let store = Storage.storage () laat storeRef = store.reference (). child ("images / \ (user.uid) /profile_photo.jpg" ) storeRef.getData (maxSize: 1 * 1024 * 1024) gegevens, fout in if let error = error print ("error: \ (error.localizedDescription)") else let image = UIImage (data: data!) self.myImageView.image = afbeelding else print ("U moet ingelogd zijn") self.loginAction (afzender: zelf) retour
Vervolgens maken we een @IBAction
methode voor de fotobibliotheekknop waarmee we binnenkort verbinding maken vanuit ons storyboard:
@IBAction func libraryAction (_ sender: Any) self.picker.allowsEditing = false self.picker.sourceType = .photoLibrary self.picker.mediaTypes = UIImagePickerController.availableMediaTypes (for: .photoLibrary)! self.present (picker, geanimeerd: true, completion: print ("handle saving"))
Ten slotte voegen we twee gedelegeerde methoden toe voor onze UIImagePickerController
, om te behandelen wanneer de gebruiker de UIImagePicker
, evenals het verwerken van de geselecteerde afbeelding:
func imagePickerControllerDidCancel (_ picker: UIImagePickerController) dismiss (geanimeerd: true, completion: nil) func imagePickerController (_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) self.dismiss (geanimeerd: true, completion: nil) laat profileImageFromPicker = info [UIImagePickerControllerOriginalImage] as! UIImage laat metadata = StorageMetadata () metadata.contentType = "image / jpeg" laat imageData: Data = UIImageJPEGRepresentation (profileImageFromPicker, 0.5)! let store = Storage.storage () laat user = Auth.auth (). currentUser if let user = user let storeRef = store.reference (). child ("images / \ (user.uid) /profile_photo.jpg") ASProgressHud.showHUDAddedTo (self.view, geanimeerd: true, type: .default) laat _ = storeRef.putData (imageData, metadata: metadata) (metadata, error) in ASProgressHud.hideHUDForView (self.view, geanimeerde: true) bewaker laat _ = metadata else print ("error occurred: \ (error.debugDescription)") return self.myImageView.image = profileImageFromPicker
Zodra de gebruiker een afbeelding selecteert, sluiten we de selectie af, maar houden we een verwijzing naar de geselecteerde afbeelding. Vervolgens maken we een StorageMetadata ()
zodat we Firebase kunnen vertellen dat we een JPEG-bestand gaan uploaden.
Zoals we deden in de refreshProfileImage ()
methode, gaan we beweren dat de gebruiker is geverifieerd en vervolgens een verwijzing maken naar het pad naar de afbeeldingen waar we het profiel van onze gebruiker willen opslaan. De ... gebruiken putData ()
methode, dan uploaden we asynchroon onze afbeelding naar de aangewezen bucketlocatie, voordat we onze beeldweergave instellen op de nieuw geselecteerde afbeelding.
Voordat we onze app kunnen bouwen en uitvoeren, moeten we de juiste besturingselementen aan ons storyboard toevoegen.
Voeg in ons hoofdvernieuwingsbord een afbeeldingsweergave toe met een afbeelding voor tijdelijke aanduidingen die het huidige profiel van de gebruiker vertegenwoordigt en sleep vervolgens om de afbeeldingsweergave te koppelen aan de afbeeldingsweergave die we hebben gedeclareerd als een @IBOutlet
in onze HomeViewController
klasse. Voeg vervolgens een werkbalk toe met een knop die u wilt gebruiken als een @IBAction
om de. te bellen libraryAction ()
methode die we eerder in de HomeViewController
.
Je Storyboard moet nu op het volgende lijken:
Zonder fouten kunt u doorgaan en uw app opnieuw bouwen en uitvoeren, en verifiëren door een nieuwe gebruiker te maken of door de reeks inloggegevens van een bestaande gebruiker te gebruiken.
Je krijgt dan de HomeViewController
, waar je de + om een afbeelding toe te voegen vanaf uw apparaat of de fotobibliotheek van de simulator. Nadat u een foto heeft gekozen, wordt deze geüpload naar de Firebase-bucket. U kunt bevestigen dat het succesvol is geüpload door naar de opslagruimte tab van je Firebase-console, zoals hieronder te zien:
Als u de app stopzet en opnieuw in Xcode uitvoert, moet u ook de afbeelding zien die u voor het laatst hebt geüpload en opnieuw bevestigen dat we met succes zijn geüpload en gedownload met behulp van Firebase Storage.
In deze zelfstudie is aangetoond hoe eenvoudig het is om asynchrone opslag en beheer van items toe te voegen aan een bestaande Firebase-app met slechts een paar regels code. Dit biedt u een handige manier om de activa van uw app te beheren, terwijl u offline en gemakkelijk kunt omgaan met offline synchronisatie.
Firebase-opslag is een voor de hand liggende keuze voor iOS-ontwikkelaars die zich al in het Firebase-ecosysteem bevinden. Het biedt ontwikkelaars de beveiliging van een imperatief beveiligingsmodel dat wordt geleverd door Firebase-verificatie, evenals de mogelijkheid geboden door de Firebase Realtime-database.
Kijk terwijl je hier bent naar enkele van onze andere berichten over de ontwikkeling van iOS-apps!