1. Übersicht
Willkommen im Friendly Chat-Codelab. In diesem Codelab erfahren Sie, wie Sie die Firebase-Plattform zum Erstellen von iOS-Anwendungen verwenden. Sie implementieren einen Chat-Client und überwachen dessen Leistung mithilfe von Firebase.
Was Sie lernen werden
- Benutzern erlauben, sich anzumelden.
- Synchronisieren Sie Daten mithilfe der Firebase-Echtzeitdatenbank.
- Speichern Sie Binärdateien im Firebase Storage.
Was du brauchen wirst
- Xcode
- Kakaoschoten
- Ein Testgerät mit iOS 8.0+ oder Simulator
Wie werden Sie dieses Tutorial nutzen?
Wie würden Sie Ihre Erfahrungen mit der Erstellung von iOS-Apps bewerten?
2. Holen Sie sich den Beispielcode
Klonen Sie das GitHub-Repository über die Befehlszeile.
$ git clone https://github.com/firebase/codelab-friendlychat-ios
3. Erstellen Sie die Starter-App
So erstellen Sie die Starter-App:
- Navigieren Sie in einem Terminalfenster zu
ios-starter/swift-starter
Verzeichnis aus Ihrem Beispielcode-Download - Führen Sie
pod install --repo-update
aus - Öffnen Sie die Datei FriendlyChatSwift.xcworkspace, um das Projekt in Xcode zu öffnen.
- Drücke den Schaltfläche „Ausführen“ .
Nach einigen Sekunden sollte der Startbildschirm von Friendly Chat angezeigt werden. Die Benutzeroberfläche sollte erscheinen. Allerdings können Sie sich zu diesem Zeitpunkt weder anmelden noch Nachrichten senden oder empfangen. Die App wird mit einer Ausnahme abgebrochen, bis Sie den nächsten Schritt abschließen.
4. Erstellen Sie ein Firebase-Konsolenprojekt
Projekt erstellen
Wählen Sie in der Firebase-Konsole „Projekt hinzufügen“ aus.
Rufen Sie das Projekt FriendlyChat
auf und klicken Sie dann auf Projekt erstellen .
Verbinden Sie Ihre iOS-App
- Klicken Sie im Bildschirm „Projektübersicht“ Ihres neuen Projekts auf „Firebase zu Ihrer iOS-App hinzufügen“ .
- Geben Sie die Bundle-ID als „
com.google.firebase.codelab.FriendlyChatSwift
“ ein. - Geben Sie die App Store-ID als „
123456
“ ein. - Klicken Sie auf App registrieren .
Fügen Sie Ihrer App die Datei „GoogleService-Info.plist“ hinzu
Klicken Sie im zweiten Bildschirm auf „GoogleService-Info.plist herunterladen“ , um eine Konfigurationsdatei herunterzuladen, die alle erforderlichen Firebase-Metadaten für Ihre App enthält. Kopieren Sie diese Datei in Ihre Anwendung und fügen Sie sie dem FriendlyChatSwift- Ziel hinzu.
Sie können jetzt auf das „x“ in der oberen rechten Ecke des Popups klicken, um es zu schließen – und dabei die Schritte 3 und 4 überspringen – da Sie diese Schritte hier ausführen.
Firebase-Modul importieren
Stellen Sie zunächst sicher, dass das Firebase
Modul importiert ist.
AppDelegate.swift , FCViewController.swift
import Firebase
Konfigurieren Sie Firebase in AppDelegate
Verwenden Sie die „configure“-Methode in FirebaseApp innerhalb der application:didFinishLaunchingWithOptions-Funktion, um zugrunde liegende Firebase-Dienste aus Ihrer .plist-Datei zu konfigurieren.
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GIDSignIn.sharedInstance().delegate = self
return true
}
5. Identifizieren Sie Benutzer
Verwenden Sie Regeln, um die Beschränkung auf authentifizierte Benutzer zu beschränken
Wir werden nun eine Regel hinzufügen, die eine Authentifizierung erfordert, bevor Nachrichten gelesen oder geschrieben werden. Dazu fügen wir unserem Nachrichtendatenobjekt die folgenden Regeln hinzu. Wählen Sie im Abschnitt „Datenbank“ der Firebase-Konsole „ Echtzeitdatenbank“ aus und klicken Sie dann auf die Registerkarte „Regeln“. Aktualisieren Sie dann die Regeln so, dass sie wie folgt aussehen:
{
"rules": {
"messages": {
".read": "auth != null",
".write": "auth != null"
}
}
}
Weitere Informationen zur Funktionsweise (einschließlich Dokumentation zur Variable „auth“) finden Sie in der Firebase- Sicherheitsdokumentation .
Konfigurieren Sie Authentifizierungs-APIs
Bevor Ihre Anwendung im Namen Ihrer Benutzer auf die Firebase-Authentifizierungs-APIs zugreifen kann, müssen Sie sie aktivieren
- Navigieren Sie zur Firebase-Konsole und wählen Sie Ihr Projekt aus
- Wählen Sie Authentifizierung
- Wählen Sie die Registerkarte Anmeldemethode
- Schalten Sie den Google- Schalter auf „Aktiviert“ (blau).
- Klicken Sie im daraufhin angezeigten Dialogfeld auf „Speichern“ .
Wenn Sie später in diesem Codelab Fehler mit der Meldung „CONFIGURATION_NOT_FOUND“ erhalten, kehren Sie zu diesem Schritt zurück und überprüfen Sie Ihre Arbeit noch einmal.
Bestätigen Sie die Firebase Auth-Abhängigkeit
Bestätigen Sie, dass in der Podfile
Datei Firebase Auth-Abhängigkeiten vorhanden sind.
Poddatei
pod 'Firebase/Auth'
Richten Sie Ihre Info.plist für die Google-Anmeldung ein.
Sie müssen Ihrem XCode-Projekt ein benutzerdefiniertes URL-Schema hinzufügen.
- Öffnen Sie Ihre Projektkonfiguration: Doppelklicken Sie auf den Projektnamen in der linken Baumansicht. Wählen Sie Ihre App im Abschnitt „ZIELE“ aus, wählen Sie dann die Registerkarte „Info“ aus und erweitern Sie den Abschnitt „URL-Typen“.
- Klicken Sie auf die Schaltfläche „+“ und fügen Sie ein URL-Schema für Ihre umgekehrte Client-ID hinzu. Um diesen Wert zu finden, öffnen Sie die Konfigurationsdatei GoogleService-Info.plist und suchen Sie nach dem Schlüssel REVERSED_CLIENT_ID. Kopieren Sie den Wert dieses Schlüssels und fügen Sie ihn in das Feld „URL-Schemata“ auf der Konfigurationsseite ein. Lassen Sie die anderen Felder leer.
- Nach Abschluss sollte Ihre Konfiguration etwa wie folgt aussehen (jedoch mit Ihren anwendungsspezifischen Werten):
Legen Sie die Client-ID für die Google-Anmeldung fest
Nachdem Firebase konfiguriert ist, können wir die Client-ID verwenden, um die Google-Anmeldung innerhalb der Methode „didFinishLaunchingWithOptions:“ einzurichten.
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
}
Fügen Sie den Anmeldehandler hinzu
Sobald das Ergebnis der Google-Anmeldung erfolgreich war, verwenden Sie das Konto zur Authentifizierung bei 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
}
}
}
Benutzer automatisch anmelden. Fügen Sie dann einen Listener zu Firebase Auth hinzu, um den Benutzer nach erfolgreicher Anmeldung in die App zu lassen. Und entfernen Sie den Listener bei 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)
}
}
Abmelden
Fügen Sie die Abmeldemethode hinzu
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)")
}
}
Testen Sie das Lesen von Nachrichten als angemeldeter Benutzer
- Drücke den Schaltfläche „Ausführen“ .
- Sie sollten sofort zum Anmeldebildschirm weitergeleitet werden. Tippen Sie auf die Schaltfläche „Google-Anmeldung“.
- Wenn alles gut funktioniert hat, werden Sie zum Nachrichtenbildschirm weitergeleitet.
6. Aktivieren Sie die Echtzeitdatenbank
Nachrichten importieren
Wählen Sie in Ihrem Projekt in der Firebase-Konsole das Datenbankelement in der linken Navigationsleiste aus. Wählen Sie im Überlaufmenü der Datenbank JSON importieren aus. Navigieren Sie zur Datei initial_messages.json
im Friendlychat-Verzeichnis, wählen Sie sie aus und klicken Sie dann auf die Schaltfläche „Importieren“ . Dadurch werden alle derzeit in Ihrer Datenbank vorhandenen Daten ersetzt. Sie können die Datenbank auch direkt bearbeiten, indem Sie das grüne + und das rote x verwenden, um Elemente hinzuzufügen und zu entfernen.
Nach dem Import sollte Ihre Datenbank so aussehen:
Bestätigen Sie die Abhängigkeit der Firebase-Datenbank
Bestätigen Sie im Abhängigkeitsblock der Podfile
Datei, dass Firebase/Database
enthalten ist.
Poddatei
pod 'Firebase/Database'
Vorhandene Nachrichten synchronisieren
Fügen Sie Code hinzu, der neu hinzugefügte Nachrichten mit der App-Benutzeroberfläche synchronisiert.
Der Code, den Sie in diesem Abschnitt hinzufügen, bewirkt Folgendes:
- Initialisieren Sie die Firebase-Datenbank und fügen Sie einen Listener hinzu, um an der Datenbank vorgenommene Änderungen zu verarbeiten.
- Aktualisieren Sie den
DataSnapshot
, damit neue Nachrichten angezeigt werden.
Ändern Sie die Methoden „deinit“, „configureDatabase“ und „tableView:cellForRow indexPath:“ Ihres FCViewControllers; durch den unten definierten Code ersetzen:
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
}
Testen Sie die Nachrichtensynchronisierung
- Drücke den Schaltfläche „Ausführen“ .
- Klicken Sie auf die Schaltfläche „Anmelden, um zu beginnen“ , um zum Nachrichtenfenster zu gelangen.
- Fügen Sie neue Nachrichten direkt in der Firebase-Konsole hinzu, indem Sie auf das grüne +-Symbol neben dem Eintrag „Nachrichten“ klicken und ein Objekt wie das folgende hinzufügen:
- Bestätigen Sie, dass sie in der Friendly-Chat-Benutzeroberfläche angezeigt werden.
7. Nachrichten senden
Implementieren Sie „Nachricht senden“.
Werte in die Datenbank übertragen. Wenn Sie die Push-Methode verwenden, um Daten zur Firebase Realtime Database hinzuzufügen, wird eine automatische ID hinzugefügt. Diese automatisch generierten IDs sind sequentiell, wodurch sichergestellt wird, dass neue Nachrichten in der richtigen Reihenfolge hinzugefügt werden.
Ändern Sie die Methode „sendMessage:“ Ihres FCViewControllers. durch den unten definierten Code ersetzen:
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)
}
Testen Sie das Senden von Nachrichten
- Drücke den Schaltfläche „Ausführen“ .
- Klicken Sie auf „Anmelden“ , um zum Nachrichtenfenster zu gelangen.
- Geben Sie eine Nachricht ein und klicken Sie auf Senden. Die neue Nachricht sollte in der App-Benutzeroberfläche und in der Firebase-Konsole sichtbar sein.
8. Bilder speichern und empfangen
Bestätigen Sie die Firebase-Speicherabhängigkeit
Bestätigen Sie im Abhängigkeitsblock der Podfile
, Firebase/Storage
enthalten ist.
Poddatei
pod 'Firebase/Storage'
Aktivieren Sie Firebase Storage im Dashboard
Gehen Sie zur Firebase-Konsole und bestätigen Sie, dass Storage mit der Domäne „gs://PROJECTID.appspot.com“ aktiviert ist
Wenn Sie stattdessen das Aktivierungsfenster sehen, klicken Sie auf „Erste Schritte“, um es mit Standardregeln zu aktivieren.
Konfigurieren Sie FirebaseStorage
FCViewController.swift
func configureStorage() {
storageRef = Storage.storage().reference()
}
Bilder in vorhandenen Nachrichten empfangen
Fügen Sie Code hinzu, der Bilder aus Firebase Storage herunterlädt.
Ändern Sie die Methode „tableView: cellForRowAt indexPath:“ Ihres FCViewControllers. durch den unten definierten Code ersetzen:
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. Bildnachrichten senden
Implementieren Sie das Speichern und Senden von Bildern
Laden Sie ein Bild vom Benutzer hoch und synchronisieren Sie dann die Speicher-URL dieses Bildes mit der Datenbank, damit dieses Bild in der Nachricht gesendet wird.
Ändern Sie die Methode „imagePickerController: didFinishPickingMediaWithInfo:“ Ihres FCViewControllers. durch den unten definierten Code ersetzen:
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])
}
}
}
Testen Sie das Senden und Empfangen von Bildnachrichten
- Drücke den Schaltfläche „Ausführen“ .
- Klicken Sie auf „Anmelden“ , um zum Nachrichtenfenster zu gelangen.
- Klicken Sie auf das Symbol „Foto hinzufügen“, um ein Foto auszuwählen. Die neue Nachricht mit dem Foto sollte in der App-Benutzeroberfläche und in der Firebase-Konsole sichtbar sein.
10. Herzlichen Glückwunsch!
Sie haben Firebase verwendet, um ganz einfach eine Echtzeit-Chat-Anwendung zu erstellen.
Was wir abgedeckt haben
- Echtzeitdatenbank
- Verbundanmeldung
- Lagerung