1. Vue d'ensemble
Bienvenue dans l'atelier de programmation Friendly Chat. Dans cet atelier de programmation, vous apprendrez à utiliser la plate-forme Firebase pour créer des applications iOS. Vous implémenterez un client de chat et surveillerez ses performances à l'aide de Firebase.
Ce que vous apprendrez
- Autoriser les utilisateurs à se connecter.
- Synchronisez les données à l'aide de la base de données Firebase Realtime.
- Stockez les fichiers binaires dans Firebase Storage.
Ce dont vous aurez besoin
- Xcode
- Cosses de cacao
- Un appareil de test avec iOS 8.0+ ou un simulateur
Comment allez-vous utiliser ce tutoriel ?
Comment évalueriez-vous votre expérience dans la création d’applications iOS ?
2. Obtenez l'exemple de code
Clonez le référentiel GitHub à partir de la ligne de commande.
$ git clone https://github.com/firebase/codelab-friendlychat-ios
3. Créez l'application de démarrage
Pour créer l'application de démarrage :
- Dans une fenêtre de terminal, accédez au Répertoire
ios-starter/swift-starter
à partir de votre exemple de téléchargement de code - Exécutez
pod install --repo-update
- Ouvrez le fichier FriendlyChatSwift.xcworkspace pour ouvrir le projet dans Xcode.
- Clique le Bouton Exécuter .
Vous devriez voir l’écran d’accueil de Friendly Chat apparaître après quelques secondes. L'interface utilisateur devrait apparaître. Cependant, à ce stade, vous ne pouvez pas vous connecter, envoyer ou recevoir des messages. L'application s'abandonnera avec une exception jusqu'à ce que vous ayez terminé l'étape suivante.
4. Créer un projet de console Firebase
Créer un projet
Dans la console Firebase , sélectionnez Ajouter un projet .
Appelez le projet FriendlyChat
, puis cliquez sur Create Project .
Connectez votre application iOS
- Depuis l'écran Présentation du projet de votre nouveau projet, cliquez sur Ajouter Firebase à votre application iOS .
- Saisissez l'ID du bundle, sous la forme "
com.google.firebase.codelab.FriendlyChatSwift
". - Entrez l'identifiant de l'App Store comme "
123456
". - Cliquez sur Enregistrer l'application .
Ajoutez le fichier GoogleService-Info.plist à votre application
Sur le deuxième écran, cliquez sur Télécharger GoogleService-Info.plist pour télécharger un fichier de configuration contenant toutes les métadonnées Firebase nécessaires pour votre application. Copiez ce fichier dans votre application et ajoutez-le à la cible FriendlyChatSwift .
Vous pouvez maintenant cliquer sur le « x » dans le coin supérieur droit de la fenêtre contextuelle pour la fermer – en sautant les étapes 3 et 4 – car vous effectuerez ces étapes ici.
Importer le module Firebase
Commencez par vous assurer que le module Firebase
est importé.
AppDelegate.swift , FCViewController.swift
import Firebase
Configurer Firebase dans AppDelegate
Utilisez la méthode « configure » dans FirebaseApp dans la fonction application:didFinishLaunchingWithOptions pour configurer les services Firebase sous-jacents à partir de votre fichier .plist.
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GIDSignIn.sharedInstance().delegate = self
return true
}
5. Identifiez les utilisateurs
Utiliser des règles pour restreindre aux utilisateurs authentifiés
Nous allons maintenant ajouter une règle pour exiger une authentification avant de lire ou d'écrire un message. Pour ce faire, nous ajoutons les règles suivantes à notre objet de données messages. Dans la section Base de données de la console Firebase, sélectionnez Base de données en temps réel, puis cliquez sur l'onglet Règles. Mettez ensuite à jour les règles pour qu'elles ressemblent à ceci :
{
"rules": {
"messages": {
".read": "auth != null",
".write": "auth != null"
}
}
}
Pour plus d'informations sur la façon dont cela fonctionne (y compris la documentation sur la variable "auth"), consultez la documentation de sécurité Firebase.
Configurer les API d'authentification
Avant que votre application puisse accéder aux API d'authentification Firebase au nom de vos utilisateurs, vous devrez l'activer
- Accédez à la console Firebase et sélectionnez votre projet
- Sélectionnez Authentification
- Sélectionnez l'onglet Méthode de connexion
- Basculez le commutateur Google sur activé (bleu)
- Appuyez sur Enregistrer dans la boîte de dialogue résultante
Si vous obtenez des erreurs plus tard dans cet atelier de programmation avec le message "CONFIGURATION_NOT_FOUND", revenez à cette étape et vérifiez votre travail.
Confirmer la dépendance de Firebase Auth
Vérifiez que les dépendances Firebase Auth existent dans le fichier Podfile
.
Fichier de pod
pod 'Firebase/Auth'
Configurez votre Info.plist pour la connexion Google.
Vous devrez ajouter un schéma d'URL personnalisé à votre projet XCode.
- Ouvrez la configuration de votre projet : double-cliquez sur le nom du projet dans l'arborescence de gauche. Sélectionnez votre application dans la section CIBLES, puis sélectionnez l'onglet Informations et développez la section Types d'URL.
- Cliquez sur le bouton + et ajoutez un schéma d'URL pour votre ID client inversé. Pour trouver cette valeur, ouvrez le fichier de configuration GoogleService-Info.plist et recherchez la clé REVERSED_CLIENT_ID. Copiez la valeur de cette clé et collez-la dans la zone Schémas d'URL de la page de configuration. Laissez les autres champs vides.
- Une fois terminée, votre configuration devrait ressembler à ce qui suit (mais avec les valeurs spécifiques à votre application) :
Définir l'ID client pour la connexion Google
Une fois Firebase configuré, nous pouvons utiliser le clientID pour configurer la connexion Google dans la méthode "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
}
Ajouter le gestionnaire de connexion
Une fois le résultat de la connexion Google réussi, utilisez le compte pour vous authentifier auprès de 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
}
}
}
Connectez automatiquement l’utilisateur. Ajoutez ensuite un écouteur à Firebase Auth, pour permettre à l'utilisateur d'accéder à l'application, après une connexion réussie. Et supprimez l'écouteur lors de la déinit.
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)
}
}
Se déconnecter
Ajouter la méthode de déconnexion
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)")
}
}
Test de lecture des messages en tant qu'utilisateur connecté
- Clique le Bouton Exécuter .
- Vous devriez être immédiatement redirigé vers l’écran de connexion. Appuyez sur le bouton de connexion Google.
- Vous devriez alors être envoyé vers l’écran de messagerie si tout a bien fonctionné.
6. Activer la base de données en temps réel
Importer des messages
Dans votre projet dans la console Firebase , sélectionnez l'élément Base de données dans la barre de navigation de gauche. Dans le menu à débordement de la Base de données, sélectionnez Importer JSON . Accédez au fichier initial_messages.json
dans le répertoire friendlychat, sélectionnez-le puis cliquez sur le bouton Importer . Cela remplacera toutes les données actuellement dans votre base de données. Vous pouvez également modifier la base de données directement, en utilisant le + vert et le x rouge pour ajouter et supprimer des éléments.
Après importation, votre base de données devrait ressembler à ceci :
Confirmer la dépendance de la base de données Firebase
Dans le bloc de dépendances du fichier Podfile
, confirmez que Firebase/Database
est inclus.
Fichier de pod
pod 'Firebase/Database'
Synchroniser les messages existants
Ajoutez du code qui synchronise les messages nouvellement ajoutés avec l'interface utilisateur de l'application.
Le code que vous ajoutez dans cette section :
- Initialisez la base de données Firebase et ajoutez un écouteur pour gérer les modifications apportées à la base de données.
- Mettez à jour le
DataSnapshot
afin que les nouveaux messages soient affichés.
Modifiez les méthodes "deinit", "configureDatabase" et "tableView:cellForRow indexPath:" de votre FCViewController ; remplacer par le code défini ci-dessous :
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
}
Tester la synchronisation des messages
- Clique le Bouton Exécuter .
- Cliquez sur le bouton Se connecter pour commencer pour accéder à la fenêtre des messages.
- Ajoutez de nouveaux messages directement dans la console Firebase en cliquant sur le symbole vert + à côté de l'entrée "messages" et en ajoutant un objet comme celui-ci :
- Confirmez qu'ils apparaissent dans l'interface utilisateur de Friendly-Chat.
7. Envoyer des messages
Implémenter Envoyer un message
Transférez les valeurs vers la base de données. Lorsque vous utilisez la méthode push pour ajouter des données à la base de données Firebase Realtime, un identifiant automatique sera ajouté. Ces identifiants générés automatiquement sont séquentiels, ce qui garantit que les nouveaux messages seront ajoutés dans le bon ordre.
Modifiez la méthode « sendMessage: » de votre FCViewController ; remplacer par le code défini ci-dessous :
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)
}
Tester l'envoi de messages
- Clique le Bouton Exécuter .
- Cliquez sur Connexion pour accéder à la fenêtre des messages.
- Tapez un message et appuyez sur Envoyer. Le nouveau message doit être visible dans l'interface utilisateur de l'application et dans la console Firebase.
8. Stocker et recevoir des images
Confirmer la dépendance du stockage Firebase
Dans le bloc de dépendances du Podfile
, confirmez Firebase/Storage
est inclus.
Fichier de pod
pod 'Firebase/Storage'
Activer Firebase Storage dans le tableau de bord
Accédez à la console Firebase et confirmez que le stockage est activé avec le domaine "gs://PROJECTID.appspot.com".
Si vous voyez plutôt la fenêtre d'activation, cliquez sur « COMMENCER » pour l'activer avec les règles par défaut.
Configurer FirebaseStorage
FCViewController.swift
func configureStorage() {
storageRef = Storage.storage().reference()
}
Recevoir des images dans les messages existants
Ajoutez du code qui télécharge les images depuis Firebase Storage.
Modifiez la méthode "tableView: cellForRowAt indexPath:" de votre FCViewController ; remplacer par le code défini ci-dessous :
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. Envoyer des messages image
Implémenter le stockage et l'envoi d'images
Téléchargez une image de l'utilisateur, puis synchronisez l'URL de stockage de cette image avec la base de données afin que cette image soit envoyée dans le message.
Modifiez la méthode « imagePickerController: didFinishPickingMediaWithInfo: » de votre FCViewController ; remplacer par le code défini ci-dessous :
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])
}
}
}
Tester l'envoi et la réception de messages image
- Clique le Bouton Exécuter .
- Cliquez sur Connexion pour accéder à la fenêtre des messages.
- Cliquez sur l'icône « ajouter une photo » pour choisir une photo. Le nouveau message avec la photo doit être visible dans l'interface utilisateur de l'application et dans la console Firebase.
10. Félicitations !
Vous avez utilisé Firebase pour créer facilement une application de chat en temps réel.
Ce que nous avons couvert
- Base de données en temps réel
- Connexion fédérée
- Stockage