Firebase iOS Codelab Swift

2efe6805ef369641.png

Benvenuto nel codelab della chat amichevole. In questo codelab imparerai come utilizzare la piattaforma Firebase per creare applicazioni iOS. Implementerai un client di chat e monitorerai le sue prestazioni utilizzando Firebase.

Questo codelab è disponibile anche in Objective-C.

Cosa imparerai

  • Consenti agli utenti di accedere.
  • Sincronizza i dati utilizzando il database Firebase Realtime.
  • Archivia i file binari in Firebase Storage.

Di cosa avrai bisogno

  • Xcode
  • baccelli di cacao
  • Un dispositivo di prova con iOS 8.0+ o simulatore

Come utilizzerai questo tutorial?

Leggilo solo attraverso Leggilo e completa gli esercizi

Come valuteresti la tua esperienza con la creazione di app iOS?

Novizio Intermedio Esperto

Clona il repository GitHub dalla riga di comando.

$ git clone https://github.com/firebase/codelab-friendlychat-ios

2f4c98d858c453fe.png

Per creare l'app iniziale:

  1. In una finestra di terminale, vai a android_studio_folder.png ios-starter/swift-starter directory dal codice di esempio scaricare
  2. Esegui pod install --repo-update
  3. Apri il file FriendlyChatSwift.xcworkspace per aprire il progetto in Xcode.
  4. Clicca il 98205811bbed9d74.png Pulsante Esegui.

Dopo alcuni secondi dovresti vedere la schermata iniziale della chat amichevole. Dovrebbe apparire l'interfaccia utente. Tuttavia, a questo punto non è possibile accedere, inviare o ricevere messaggi. L'app si interromperà con un'eccezione fino al completamento del passaggio successivo.

Crea progetto

Dalla console Firebase selezionare Aggiungi progetto.

Chiamare il progetto FriendlyChat , quindi fare clic su Crea progetto.

Schermata del 06-11-2015 14:13:39.png

Collega la tua app iOS

  1. Dalla schermata di Anteprima progetto del nuovo progetto, fare clic su Aggiungi Firebase alla tua app iOS.
  2. Inserisci l'ID bundle, come " com.google.firebase.codelab.FriendlyChatSwift ".
  3. Immettere l'ID App Store come " 123456 ".
  4. Fare clic su Registra App.

Aggiungi il file GoogleService-Info.plist alla tua app

Nella seconda schermata fare clic su Download GoogleService-Info.plist per scaricare un file di configurazione che contiene tutti i metadati Firebase necessario per la vostra applicazione. Copiare il file per l'applicazione e aggiungerlo al bersaglio FriendlyChatSwift.

Ora puoi fare clic sulla "x" nell'angolo in alto a destra del popup per chiuderlo, saltando i passaggi 3 e 4, mentre eseguirai questi passaggi qui.

19d59efb213ddbdc.png

Importa modulo Firebase

Iniziare facendo in modo che la Firebase modulo viene importato.

AppDelegate.swift , FCViewController.swift

import Firebase

Configura Firebase in AppDelegate

Utilizzare il metodo "configure" in FirebaseApp all'interno della funzione application:didFinishLaunchingWithOptions per configurare i servizi Firebase sottostanti dal file .plist.

AppDelegate.swift

  func application(_ application: UIApplication, didFinishLaunchingWithOptions
      launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  FirebaseApp.configure()
  GIDSignIn.sharedInstance().delegate = self
  return true
}

Usa regole per limitare agli utenti autenticati

Aggiungeremo ora una regola per richiedere l'autenticazione prima di leggere o scrivere qualsiasi messaggio. Per fare ciò aggiungiamo le seguenti regole al nostro oggetto dati dei messaggi. Dall'interno della sezione Database di console Firebase selezionare in tempo reale del database, quindi fare clic sulla scheda Regole. Quindi aggiorna le regole in modo che assomiglino a questo:

{
  "rules": {
    "messages": {
      ".read": "auth != null",
      ".write": "auth != null"
    }
  }
}

Per ulteriori informazioni su come funziona questo (compresa la documentazione sulla variabile "auth") Vedere la Firebase documentazione di sicurezza .

Configura le API di autenticazione

Prima che la tua applicazione possa accedere alle API di autenticazione Firebase per conto dei tuoi utenti, dovrai abilitarla

  1. Accedere alla console Firebase e selezionare il vostro progetto
  2. Selezionare autenticazione
  3. Selezionare la scheda nel metodo Sign
  4. Alterna l'interruttore Google per abilitato (blu)
  5. Premere Salva nella finestra di dialogo risultante

Se ricevi errori più avanti in questo codelab con il messaggio "CONFIGURATION_NOT_FOUND", torna a questo passaggio e ricontrolla il tuo lavoro.

Conferma la dipendenza da Firebase Auth

Dipendenze Conferma Firebase Auth esistono nel Podfile file.

Podfile

pod 'Firebase/Auth'

Imposta il tuo Info.plist per l'accesso a Google.

Dovrai aggiungere uno schema URL personalizzato al tuo progetto XCode.

  1. Apri la configurazione del tuo progetto: fai doppio clic sul nome del progetto nella vista ad albero a sinistra. Seleziona la tua app dalla sezione TARGET, quindi seleziona la scheda Informazioni ed espandi la sezione Tipi di URL.
  2. Fai clic sul pulsante + e aggiungi uno schema URL per il tuo ID cliente invertito. Per trovare questo valore, apri il file di configurazione GoogleService-Info.plist e cerca la chiave REVERSED_CLIENT_ID. Copia il valore di quella chiave e incollalo nella casella Schemi URL nella pagina di configurazione. Lascia vuoti gli altri campi.
  3. Una volta completata, la configurazione dovrebbe essere simile alla seguente (ma con i valori specifici dell'applicazione):

1b54d5bd2f4f1448.png

Imposta l'ID client per l'accesso a Google

Dopo che Firebase è stato configurato, possiamo utilizzare il clientID per impostare l'accesso di Google all'interno del metodo "didFinishLaunchingWithOptions:".

AppDelegate.swift

  func application(_ application: UIApplication, didFinishLaunchingWithOptions
      launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  FirebaseApp.configure()
  GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
  GIDSignIn.sharedInstance().delegate = self
  return true
}

Aggiungi il gestore di accesso

Una volta che il risultato dell'accesso a Google ha avuto esito positivo, utilizza l'account per autenticarti con Firebase.

AppDelegate.swift

  func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
    if let error = error {
      print("Error \(error)")
      return
    }

    guard let authentication = user.authentication else { return }
    let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
                                                      accessToken: authentication.accessToken)
    Auth.auth().signIn(with: credential) { (user, error) in
      if let error = error {
        print("Error \(error)")
        return
      }
    }
  }

Accedi automaticamente all'utente. Quindi aggiungi un listener a Firebase Auth, per consentire all'utente di accedere all'app, dopo aver eseguito l'accesso. E rimuovi l'ascoltatore su deinit.

SignInViewController.swift

  override func viewDidLoad() {
    super.viewDidLoad()
    GIDSignIn.sharedInstance().uiDelegate = self
    GIDSignIn.sharedInstance().signInSilently()
    handle = Auth.auth().addStateDidChangeListener() { (auth, user) in
      if user != nil {
        MeasurementHelper.sendLoginEvent()
        self.performSegue(withIdentifier: Constants.Segues.SignInToFp, sender: nil)
      }
    }
  }

  deinit {
    if let handle = handle {
      Auth.auth().removeStateDidChangeListener(handle)
    }
  }

Disconnessione

Aggiungi il metodo di disconnessione

FCViewController.swift

  @IBAction func signOut(_ sender: UIButton) {
    let firebaseAuth = Auth.auth()
    do {
      try firebaseAuth.signOut()
      dismiss(animated: true, completion: nil)
    } catch let signOutError as NSError {
      print ("Error signing out: \(signOutError.localizedDescription)")
    }
  }

Prova a leggere i messaggi come utente che ha effettuato l'accesso

  1. Clicca il 98205811bbed9d74.png Pulsante Esegui.
  2. Dovresti essere immediatamente indirizzato alla schermata di accesso. Tocca il pulsante Accedi con Google.
  3. Dovresti quindi essere inviato alla schermata dei messaggi se tutto ha funzionato bene.

2efe6805ef369641.png

Importa messaggi

Nel progetto in console Firebase selezionare la voce del database sulla barra di navigazione a sinistra. Nel menu di overflow del Database selezionare Importa JSON. Individuare initial_messages.json file nella directory friendlychat, selezionarlo quindi fare clic sul pulsante Importa. Questo sostituirà tutti i dati attualmente nel tuo database. Puoi anche modificare direttamente il database, usando la x verde + e rossa per aggiungere e rimuovere elementi.

20ccf4856b715b4c.png

Dopo aver importato il tuo database dovrebbe apparire così:

f3e0367f1c9cd187.png

Conferma la dipendenza del database Firebase

Nel blocco dipendenze del Podfile di file, confermano che Firebase/Database è incluso.

Podfile

pod 'Firebase/Database'

Sincronizza i messaggi esistenti

Aggiungi il codice che sincronizza i messaggi appena aggiunti all'interfaccia utente dell'app.

Il codice che aggiungi in questa sezione:

  • Inizializza il database Firebase e aggiungi un listener per gestire le modifiche apportate al database.
  • Aggiornare il DataSnapshot modo verranno visualizzati i nuovi messaggi.

Modifica i metodi "deinit", "configureDatabase" e "tableView:cellForRow indexPath:" del tuo FCViewController; sostituire con il codice definito di seguito:

FCViewController.swift

  deinit {
    if let refHandle = _refHandle {
      self.ref.child("messages").removeObserver(withHandle: _refHandle)
    }
  }


  func configureDatabase() {
    ref = Database.database().reference()
    // Listen for new messages in the Firebase database
    _refHandle = self.ref.child("messages").observe(.childAdded, with: { [weak self] (snapshot) -> Void in
      guard let strongSelf = self else { return }
      strongSelf.messages.append(snapshot)
      strongSelf.clientTable.insertRows(at: [IndexPath(row: strongSelf.messages.count-1, section: 0)], with: .automatic)
    })
  }


  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Dequeue cell
    let cell = self.clientTable.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath)
    // Unpack message from Firebase DataSnapshot
    let messageSnapshot = self.messages[indexPath.row]
    guard let message = messageSnapshot.value as? [String: String] else { return cell }
    let name = message[Constants.MessageFields.name] ?? ""
    let text = message[Constants.MessageFields.text] ?? ""
    cell.textLabel?.text = name + ": " + text
    cell.imageView?.image = UIImage(named: "ic_account_circle")
    if let photoURL = message[Constants.MessageFields.photoURL], let URL = URL(string: photoURL),
        let data = try? Data(contentsOf: URL) {
      cell.imageView?.image = UIImage(data: data)
    }
    return cell
  }

Sincronizzazione messaggi di prova

  1. Clicca il 98205811bbed9d74.png Pulsante Esegui.
  2. Fare clic sul segno per ottenere il pulsante cominciato ad andare alla finestra dei messaggi.
  3. Aggiungi nuovi messaggi direttamente nella console di Firebase facendo clic sul simbolo verde + accanto alla voce "messaggi" e aggiungendo un oggetto come il seguente: f9876ffc8b316b14.png
  4. Conferma che vengano visualizzati nell'interfaccia della chat amichevole.

Implementa Invia messaggio

Invia i valori al database. Quando utilizzi il metodo push per aggiungere dati a Firebase Realtime Database, verrà aggiunto un ID automatico. Questi ID generati automaticamente sono sequenziali, il che garantisce che i nuovi messaggi vengano aggiunti nell'ordine corretto.

Modifica il metodo "sendMessage:" del tuo FCViewController; sostituire con il codice definito di seguito:

FCViewController.swift

  func sendMessage(withData data: [String: String]) {
    var mdata = data
    mdata[Constants.MessageFields.name] = Auth.auth().currentUser?.displayName
    if let photoURL = Auth.auth().currentUser?.photoURL {
      mdata[Constants.MessageFields.photoURL] = photoURL.absoluteString
    }

    // Push data to Firebase Database
    self.ref.child("messages").childByAutoId().setValue(mdata)
  }

Test di invio di messaggi

  1. Clicca il 98205811bbed9d74.png Pulsante Esegui.
  2. Clicca Registrati per andare alla finestra dei messaggi.
  3. Scrivi un messaggio e premi invio. Il nuovo messaggio dovrebbe essere visibile nell'interfaccia utente dell'app e nella console Firebase.

Conferma la dipendenza dell'archiviazione Firebase

Nel blocco dipendenze del Podfile , conferma Firebase/Storage è incluso.

Podfile

pod 'Firebase/Storage'

Attiva Firebase Storage nella dashboard

Vai alla console Firebase e conferma che lo spazio di archiviazione è attivato con il dominio "gs://PROJECTID.appspot.com"

b0438b37a588bcee.png

Se invece visualizzi la finestra di attivazione, fai clic su "INIZIA" per attivarla con le regole predefinite.

c290bbebff2cafa7.png

Configura FirebaseStorage

FCViewController.swift

  func configureStorage() {
    storageRef = Storage.storage().reference()
  }

Ricevi immagini nei messaggi esistenti

Aggiungi il codice che scarica le immagini da Firebase Storage.

Modifica il metodo "tableView: cellForRowAt indexPath:" del tuo FCViewController; sostituire con il codice definito di seguito:

FCViewController.swift

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Dequeue cell
    let cell = self.clientTable .dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath)
    // Unpack message from Firebase DataSnapshot
    let messageSnapshot: DataSnapshot! = self.messages[indexPath.row]
    guard let message = messageSnapshot.value as? [String:String] else { return cell }
    let name = message[Constants.MessageFields.name] ?? ""
    if let imageURL = message[Constants.MessageFields.imageURL] {
      if imageURL.hasPrefix("gs://") {
        Storage.storage().reference(forURL: imageURL).getData(maxSize: INT64_MAX) {(data, error) in
          if let error = error {
            print("Error downloading: \(error)")
            return
          }
          DispatchQueue.main.async {
            cell.imageView?.image = UIImage.init(data: data!)
            cell.setNeedsLayout()
          }
        }
      } else if let URL = URL(string: imageURL), let data = try? Data(contentsOf: URL) {
        cell.imageView?.image = UIImage.init(data: data)
      }
      cell.textLabel?.text = "sent by: \(name)"
    } else {
      let text = message[Constants.MessageFields.text] ?? ""
      cell.textLabel?.text = name + ": " + text
      cell.imageView?.image = UIImage(named: "ic_account_circle")
      if let photoURL = message[Constants.MessageFields.photoURL], let URL = URL(string: photoURL),
          let data = try? Data(contentsOf: URL) {
        cell.imageView?.image = UIImage(data: data)
      }
    }
    return cell
  }

Implementa l'archiviazione e l'invio di immagini

Carica un'immagine dall'utente, quindi sincronizza l'URL di archiviazione di questa immagine con il database in modo che questa immagine venga inviata all'interno del messaggio.

Modifica il metodo "imagePickerController: didFinishPickingMediaWithInfo:" del tuo FCViewController; sostituire con il codice definito di seguito:

FCViewController.swift

  func imagePickerController(_ picker: UIImagePickerController,
    didFinishPickingMediaWithInfo info: [String : Any]) {
      picker.dismiss(animated: true, completion:nil)
    guard let uid = Auth.auth().currentUser?.uid else { return }

    // if it's a photo from the library, not an image from the camera
    if #available(iOS 8.0, *), let referenceURL = info[UIImagePickerControllerReferenceURL] as? URL {
      let assets = PHAsset.fetchAssets(withALAssetURLs: [referenceURL], options: nil)
      let asset = assets.firstObject
      asset?.requestContentEditingInput(with: nil, completionHandler: { [weak self] (contentEditingInput, info) in
        let imageFile = contentEditingInput?.fullSizeImageURL
        let filePath = "\(uid)/\(Int(Date.timeIntervalSinceReferenceDate * 1000))/\((referenceURL as AnyObject).lastPathComponent!)"
        guard let strongSelf = self else { return }
        strongSelf.storageRef.child(filePath)
          .putFile(from: imageFile!, metadata: nil) { (metadata, error) in
            if let error = error {
              let nsError = error as NSError
              print("Error uploading: \(nsError.localizedDescription)")
              return
            }
            strongSelf.sendMessage(withData: [Constants.MessageFields.imageURL: strongSelf.storageRef.child((metadata?.path)!).description])
          }
      })
    } else {
      guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
      let imageData = UIImageJPEGRepresentation(image, 0.8)
      let imagePath = "\(uid)/\(Int(Date.timeIntervalSinceReferenceDate * 1000)).jpg"
      let metadata = StorageMetadata()
      metadata.contentType = "image/jpeg"
      self.storageRef.child(imagePath)
        .putData(imageData!, metadata: metadata) { [weak self] (metadata, error) in
          if let error = error {
            print("Error uploading: \(error)")
            return
          }
          guard let strongSelf = self else { return }
          strongSelf.sendMessage(withData: [Constants.MessageFields.imageURL: strongSelf.storageRef.child((metadata?.path)!).description])
      }
    }
  }

Prova di invio e ricezione di messaggi di immagine

  1. Clicca il 98205811bbed9d74.png Pulsante Esegui.
  2. Clicca Registrati per andare alla finestra dei messaggi.
  3. Fai clic sull'icona "aggiungi una foto" per scegliere una foto. Il nuovo messaggio con la foto dovrebbe essere visibile nell'interfaccia utente dell'app e nella console Firebase.

Hai utilizzato Firebase per creare facilmente un'applicazione di chat in tempo reale.

Cosa abbiamo coperto

  • Database in tempo reale
  • Accesso federato
  • Magazzinaggio

Per saperne di più