1. Panoramica
Benvenuto nel codelab di Friendly Chat. 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 in tempo reale di Firebase.
- Archivia i file binari in Firebase Storage.
Di cosa avrai bisogno
- Xcode
- Cialde Di Cacao
- Un dispositivo di prova con iOS 8.0+ o simulatore
Come utilizzerai questo tutorial?
Come valuteresti la tua esperienza con la creazione di app iOS?
2. Ottieni il codice di esempio
Clonare il repository GitHub dalla riga di comando.
$ git clone https://github.com/firebase/codelab-friendlychat-ios
3. Crea l'app iniziale
Per creare l'app iniziale:
- In una finestra di terminale, vai al file
directory
ios-starter/swift-starter
dal download del codice di esempio - Esegui
pod install --repo-update
- Apri il file FriendlyChatSwift.xcworkspace per aprire il progetto in Xcode.
- Clicca il
Pulsante Esegui .
Dovresti vedere la schermata iniziale di Friendly Chat apparire dopo pochi secondi. Dovrebbe apparire l'interfaccia utente. Tuttavia, a questo punto non puoi accedere, inviare o ricevere messaggi. L'app si interromperà con un'eccezione fino al completamento del passaggio successivo.
4. Crea il progetto della console Firebase
Crea progetto
Dalla console Firebase seleziona Add Project .
Chiama il progetto FriendlyChat
, quindi fai clic su Crea progetto .
Connetti la tua app per iOS
- Dalla schermata Panoramica del progetto del tuo nuovo progetto, fai clic su Aggiungi Firebase alla tua app iOS .
- Inserisci l'ID pacchetto, come "
com.google.firebase.codelab.FriendlyChatSwift
". - Inserisci l'ID dell'App Store come "
123456
". - Fai clic su Registra app .
Aggiungi il file GoogleService-Info.plist alla tua app
Nella seconda schermata fai clic su Scarica GoogleService-Info.plist per scaricare un file di configurazione che contiene tutti i metadati Firebase necessari per la tua app. Copia quel file nella tua applicazione e aggiungilo al target FriendlyChatSwift .
Ora puoi fare clic sulla "x" nell'angolo in alto a destra del popup per chiuderlo, saltando i passaggi 3 e 4, poiché eseguirai questi passaggi qui.
Importa modulo Firebase
Inizia assicurandoti che il modulo Firebase
sia importato.
AppDelegate.swift , FCViewController.swift
import Firebase
Configura Firebase in AppDelegate
Usa il metodo "configure" in FirebaseApp all'interno dell'applicazione: funzione didFinishLaunchingWithOptions per configurare i servizi Firebase sottostanti dal tuo file .plist.
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GIDSignIn.sharedInstance().delegate = self
return true
}
5. Identificare gli utenti
Utilizzare le regole per limitare agli utenti autenticati
Ora aggiungeremo 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. Dalla sezione Database della console Firebase seleziona Realtime Database, quindi fai clic sulla scheda Regole. Quindi aggiorna le regole in modo che appaiano così:
{
"rules": {
"messages": {
".read": "auth != null",
".write": "auth != null"
}
}
}
Per ulteriori informazioni su come funziona (inclusa la documentazione sulla variabile "auth"), consulta la documentazione sulla sicurezza di Firebase .
Configura le API di autenticazione
Prima che la tua applicazione possa accedere alle API di autenticazione Firebase per conto dei tuoi utenti, dovrai abilitarla
- Passa alla console Firebase e seleziona il tuo progetto
- Seleziona Autenticazione
- Selezionare la scheda Metodo di accesso
- Attiva l'opzione Google su abilitato (blu)
- 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 di Firebase Auth
Verifica che le dipendenze Firebase Auth esistano nel file Podfile
.
Podfile
pod 'Firebase/Auth'
Imposta il tuo Info.plist per l'accesso con Google.
Dovrai aggiungere uno schema URL personalizzato al tuo progetto XCode.
- 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 TARGETS, quindi seleziona la scheda Informazioni ed espandi la sezione Tipi di URL.
- 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 tale chiave e incollalo nella casella Schemi URL nella pagina di configurazione. Lascia vuoti gli altri campi.
- Al termine, la configurazione dovrebbe essere simile alla seguente (ma con i valori specifici dell'applicazione):
Imposta l'ID client per l'accesso con Google
Dopo aver configurato Firebase, possiamo utilizzare il clientID per configurare l'accesso a 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 è andato a buon fine, 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 correttamente l'accesso. E rimuovi il listener 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
- Clicca il
Pulsante Esegui .
- Dovresti essere immediatamente indirizzato alla schermata di accesso. Tocca il pulsante Accedi con Google.
- Dovresti quindi essere inviato alla schermata di messaggistica se tutto ha funzionato bene.
6. Attiva il database in tempo reale
Importa messaggi
Nel tuo progetto nella console Firebase seleziona la voce Database nella barra di navigazione a sinistra. Nel menu di overflow del Database seleziona Importa JSON . Passare al file initial_messages.json
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 il verde + e il rosso x per aggiungere e rimuovere elementi.
Dopo aver importato il tuo database dovrebbe apparire così:
Conferma la dipendenza dal database Firebase
Nel blocco delle dipendenze del file Podfile
, conferma che Firebase/Database
è incluso.
Podfile
pod 'Firebase/Database'
Sincronizza i messaggi esistenti
Aggiungi il codice che sincronizza i nuovi messaggi 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.
- Aggiorna
DataSnapshot
in modo che vengano 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
}
Prova la sincronizzazione dei messaggi
- Clicca il
Pulsante Esegui .
- Fai clic sul pulsante Accedi per iniziare per andare alla finestra dei messaggi.
- Aggiungi nuovi messaggi direttamente nella console di Firebase facendo clic sul simbolo + verde accanto alla voce "messaggi" e aggiungendo un oggetto come il seguente:
- Conferma che vengano visualizzati nell'interfaccia utente della chat amichevole.
7. Invia messaggi
Implementare 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)
}
Prova l'invio di messaggi
- Clicca il
Pulsante Esegui .
- Fare clic su Accedi per andare alla finestra dei messaggi.
- Digita un messaggio e premi invio. Il nuovo messaggio dovrebbe essere visibile nell'interfaccia utente dell'app e nella console di Firebase.
8. Memorizza e ricevi immagini
Conferma la dipendenza dallo storage Firebase
Nel blocco delle dipendenze del Podfile
, conferma Firebase/Storage
è incluso.
Podfile
pod 'Firebase/Storage'
Attiva Firebase Storage nella dashboard
Vai alla console Firebase e verifica che l'archiviazione sia attivata con il dominio "gs://PROJECTID.appspot.com".
Se invece visualizzi la finestra di attivazione, fai clic su "INIZIA" per attivarla con le regole predefinite.
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
}
9. Invia messaggi immagine
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 l'invio e la ricezione di messaggi immagine
- Clicca il
Pulsante Esegui .
- Fare clic su Accedi per andare alla finestra dei messaggi.
- 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 di Firebase.
10. Congratulazioni!
Hai utilizzato Firebase per creare facilmente un'applicazione di chat in tempo reale.
Di cosa abbiamo parlato
- Database in tempo reale
- Accesso federato
- Magazzinaggio