Firebase iOS Codelab Swift

1. Przegląd

2efe6805ef369641.png

Witamy w laboratorium programowania Friendly Chat. Podczas tych zajęć z programowania dowiesz się, jak używać platformy Firebase do tworzenia aplikacji na iOS. Zaimplementujesz klienta czatu i będziesz monitorować jego wydajność za pomocą Firebase.

Czego się dowiesz

  • Zezwalaj użytkownikom na logowanie się.
  • Synchronizuj dane za pomocą bazy danych Firebase Realtime.
  • Przechowuj pliki binarne w Firebase Storage.

Co będziesz potrzebował

  • Xkod
  • CocoaPods
  • Urządzenie testowe z iOS 8.0+ lub symulator

Jak będziesz korzystać z tego samouczka?

Przeczytaj tylko i wyłącznie Przeczytaj i wykonaj ćwiczenia

Jak oceniasz swoje doświadczenia z tworzeniem aplikacji na iOS?

Nowicjusz Mediator Biegły

2. Pobierz przykładowy kod

Sklonuj repozytorium GitHub z wiersza poleceń.

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

3. Zbuduj aplikację startową

2f4c98d858c453fe.png

Aby zbudować aplikację startową:

  1. W oknie terminala przejdź do folder_studio_android.png ios-starter/swift-starter z pobranego przykładowego kodu
  2. Uruchom pod install --repo-update
  3. Otwórz plik FriendlyChatSwift.xcworkspace, aby otworzyć projekt w Xcode.
  4. Kliknij 98205811bed9d74.png Przycisk Uruchom .

Po kilku sekundach powinieneś zobaczyć ekran główny Przyjaznego Czatu. Powinien pojawić się interfejs użytkownika. Jednak w tym momencie nie możesz się logować, wysyłać ani odbierać wiadomości. Aplikacja zakończy działanie z wyjątkiem przypadku, dopóki nie wykonasz następnego kroku.

4. Utwórz projekt konsoli Firebase

Utwórz projekt

W konsoli Firebase wybierz opcję Dodaj projekt .

Nazwij projekt FriendlyChat , a następnie kliknij opcję Utwórz projekt .

Zrzut ekranu z 2015-11-06 14:13:39.png

Połącz swoją aplikację na iOS

  1. Na ekranie Przegląd nowego projektu kliknij Dodaj Firebase do swojej aplikacji na iOS .
  2. Wprowadź identyfikator pakietu jako „ com.google.firebase.codelab.FriendlyChatSwift ”.
  3. Wprowadź identyfikator App Store jako „ 123456 ”.
  4. Kliknij opcję Zarejestruj aplikację .

Dodaj plik GoogleService-Info.plist do swojej aplikacji

Na drugim ekranie kliknij Pobierz GoogleService-Info.plist , aby pobrać plik konfiguracyjny zawierający wszystkie niezbędne metadane Firebase dla Twojej aplikacji. Skopiuj ten plik do swojej aplikacji i dodaj go do celu FriendlyChatSwift .

Możesz teraz kliknąć „x” w prawym górnym rogu wyskakującego okienka, aby je zamknąć – pomijając kroki 3 i 4 – ponieważ kroki te wykonasz tutaj.

19d59efb213ddbdc.png

Importuj moduł Firebase

Zacznij od upewnienia się, że moduł Firebase został zaimportowany.

AppDelegate.swift , FCViewController.swift

import Firebase

Skonfiguruj Firebase w AppDelegate

Użyj metody „configure” w FirebaseApp wewnątrz funkcji application:didFinishLaunchingWithOptions, aby skonfigurować podstawowe usługi Firebase z pliku .plist.

AppDelegate.swift

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

5. Zidentyfikuj użytkowników

Użyj reguł, aby ograniczyć dostęp do uwierzytelnionych użytkowników

Dodamy teraz regułę wymagającą uwierzytelnienia przed przeczytaniem lub zapisaniem jakichkolwiek wiadomości. W tym celu dodajemy następujące reguły do ​​naszego obiektu danych wiadomości. W sekcji Baza danych konsoli Firebase wybierz Baza danych czasu rzeczywistego, a następnie kliknij kartę Reguły. Następnie zaktualizuj reguły, aby wyglądały tak:

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

Aby uzyskać więcej informacji na temat tego, jak to działa (w tym dokumentację dotyczącą zmiennej „auth”), zobacz dokumentację zabezpieczeń Firebase.

Skonfiguruj interfejsy API uwierzytelniania

Zanim Twoja aplikacja będzie mogła uzyskać dostęp do interfejsów API Firebase Authentication w imieniu użytkowników, musisz ją włączyć

  1. Przejdź do konsoli Firebase i wybierz swój projekt
  2. Wybierz opcję Uwierzytelnianie
  3. Wybierz zakładkę Metoda logowania
  4. Przełącz przełącznik Google na włączony (niebieski)
  5. Naciśnij Zapisz w wyświetlonym oknie dialogowym

Jeśli w dalszej części ćwiczeń z kodowania pojawią się błędy z komunikatem „CONFIGURATION_NOT_FOUND”, wróć do tego kroku i dokładnie sprawdź swoją pracę.

Potwierdź zależność uwierzytelniania Firebase

Sprawdź, czy w pliku Podfile istnieją zależności Firebase Auth.

Podplik

pod 'Firebase/Auth'

Skonfiguruj plik Info.plist do logowania się w Google.

Musisz dodać niestandardowy schemat adresu URL do swojego projektu XCode.

  1. Otwórz konfigurację projektu: kliknij dwukrotnie nazwę projektu w lewym widoku drzewa. Wybierz swoją aplikację w sekcji CELE, następnie wybierz kartę Informacje i rozwiń sekcję Typy adresów URL.
  2. Kliknij przycisk + i dodaj schemat adresu URL dla odwróconego identyfikatora klienta. Aby znaleźć tę wartość, otwórz plik konfiguracyjny GoogleService-Info.plist i poszukaj klucza REVERSED_CLIENT_ID. Skopiuj wartość tego klucza i wklej go w polu Schematy adresów URL na stronie konfiguracji. Pozostałe pola pozostaw puste.
  3. Po zakończeniu konfiguracja powinna wyglądać podobnie do poniższej (ale z wartościami specyficznymi dla aplikacji):

1b54d5bd2f4f1448.png

Ustaw identyfikator klienta dla logowania Google

Po skonfigurowaniu Firebase możemy użyć identyfikatora klienta do skonfigurowania logowania Google w metodzie „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
}

Dodaj procedurę obsługi logowania

Gdy logowanie Google zakończy się pomyślnie, użyj konta, aby uwierzytelnić się w 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
      }
    }
  }

Automatycznie zaloguj użytkownika. Następnie dodaj słuchacza do Firebase Auth, aby pozwolić użytkownikowi na dostęp do aplikacji po pomyślnym zalogowaniu się. I usuń słuchacza na 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)
    }
  }

Wyloguj się

Dodaj metodę Wyloguj

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)")
    }
  }

Przetestuj czytanie wiadomości jako zalogowany użytkownik

  1. Kliknij 98205811bed9d74.png Przycisk Uruchom .
  2. Powinieneś natychmiast zostać przekierowany do ekranu logowania. Kliknij przycisk Zaloguj się przez Google.
  3. Jeśli wszystko działało dobrze, powinieneś zostać wysłany do ekranu wiadomości.

6. Aktywuj bazę danych czasu rzeczywistego

2efe6805ef369641.png

Importuj wiadomości

W swoim projekcie w konsoli Firebase wybierz element Baza danych na lewym pasku nawigacyjnym. W rozszerzonym menu Bazy danych wybierz opcję Importuj JSON . Przejdź do pliku initial_messages.json w katalogu Friendlychat, wybierz go, a następnie kliknij przycisk Importuj . Spowoduje to zastąpienie wszelkich danych aktualnie znajdujących się w Twojej bazie danych. Możesz także edytować bazę danych bezpośrednio, używając zielonego + i czerwonego x, aby dodawać i usuwać elementy.

20ccf4856b715b4c.png

Po zaimportowaniu baza danych powinna wyglądać następująco:

f3e0367f1c9cd187.png

Potwierdź zależność od bazy danych Firebase

W bloku zależności pliku Podfile sprawdź, czy dołączono Firebase/Database .

Podplik

pod 'Firebase/Database'

Synchronizuj istniejące wiadomości

Dodaj kod synchronizujący nowo dodane wiadomości z interfejsem aplikacji.

Kod, który dodasz w tej sekcji:

  • Zainicjuj bazę danych Firebase i dodaj odbiornik do obsługi zmian wprowadzonych w bazie danych.
  • Zaktualizuj DataSnapshot , aby były wyświetlane nowe wiadomości.

Zmodyfikuj metody „deinit”, „configureDatabase” i „tableView:cellForRow IndexPath:” kontrolera FCViewController; zastąp kodem zdefiniowanym poniżej:

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
  }

Testuj synchronizację wiadomości

  1. Kliknij 98205811bed9d74.png Przycisk Uruchom .
  2. Kliknij przycisk Zaloguj się, aby rozpocząć, aby przejść do okna wiadomości.
  3. Dodaj nowe wiadomości bezpośrednio w konsoli Firebase, klikając zielony symbol + obok wpisu „wiadomości” i dodając obiekt podobny do poniższego: f9876ffc8b316b14.png
  4. Potwierdź, że pojawiają się w interfejsie Friendly-Chat.

7. Wysyłaj wiadomości

Zaimplementuj opcję Wyślij wiadomość

Wypchnij wartości do bazy danych. Jeśli użyjesz metody push do dodania danych do bazy danych Firebase Realtime Database, zostanie dodany automatyczny identyfikator. Te automatycznie generowane identyfikatory są sekwencyjne, co gwarantuje, że nowe wiadomości będą dodawane we właściwej kolejności.

Zmodyfikuj metodę „sendMessage:” kontrolera FCViewController; zastąp kodem zdefiniowanym poniżej:

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)
  }

Testowe wysyłanie wiadomości

  1. Kliknij 98205811bed9d74.png Przycisk Uruchom .
  2. Kliknij Zaloguj się, aby przejść do okna wiadomości.
  3. Wpisz wiadomość i naciśnij Wyślij. Nowa wiadomość powinna być widoczna w interfejsie aplikacji i konsoli Firebase.

8. Przechowuj i odbieraj obrazy

Potwierdź zależność od magazynu Firebase

W bloku zależności pliku Podfile potwierdź, że dołączono Firebase/Storage .

Podplik

pod 'Firebase/Storage'

Aktywuj Firebase Storage w panelu kontrolnym

Przejdź do konsoli Firebase i potwierdź, że pamięć masowa jest aktywowana w domenie „gs://PROJECTID.appspot.com”.

b0438b37a588bcee.png

Jeśli zamiast tego widzisz okno aktywacji, kliknij „ROZCZNIJ”, aby aktywować je przy użyciu domyślnych reguł.

c290bbebff2cafa7.png

Skonfiguruj FirebaseStorage

FCViewController.swift

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

Otrzymuj obrazy w istniejących wiadomościach

Dodaj kod pobierający obrazy z Firebase Storage.

Zmodyfikuj metodę „tableView: cellForRowAt indeksPath:” kontrolera FCViewController; zastąp kodem zdefiniowanym poniżej:

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
  }

9. Wysyłaj wiadomości obrazkowe

Wdrażaj przechowywanie i wysyłanie obrazów

Prześlij obraz od użytkownika, a następnie zsynchronizuj adres URL tego obrazu z bazą danych, aby obraz został wysłany w wiadomości.

Zmodyfikuj metodę „imagePickerController: didFinishPickingMediaWithInfo:” kontrolera FCViewController; zastąp kodem zdefiniowanym poniżej:

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])
      }
    }
  }

Testuj wysyłanie i odbieranie wiadomości graficznych

  1. Kliknij 98205811bed9d74.png Przycisk Uruchom .
  2. Kliknij Zaloguj się, aby przejść do okna wiadomości.
  3. Kliknij ikonę „dodaj zdjęcie”, aby wybrać zdjęcie. Nowa wiadomość ze zdjęciem powinna być widoczna w interfejsie aplikacji oraz w konsoli Firebase.

10. Gratulacje!

Użyłeś Firebase, aby łatwo zbudować aplikację do czatowania w czasie rzeczywistym.

Co omówiliśmy

  • Baza danych czasu rzeczywistego
  • Logowanie federacyjne
  • Składowanie

Ucz się więcej