[Swift 5] Implémentation de l'enregistrement des membres dans Firebase

introduction

Je crée une application de clonage LINE pour apprendre Firebase et la fonction de chat, et je publierai la mise en œuvre de l'inscription des membres en utilisant Firebase sous forme de mémorandum. Je suis un débutant, donc si vous avez des corrections, veuillez les signaler.

Aperçu

Cette fois, dans la mise en œuvre de la fonction d'enregistrement des membres, l'ordre est le suivant.

    1. Enregistrement de l'utilisateur sur FirebaseAuth
  1. Enregistrer l'image de profil dans Firebase Storage
    1. Enregistrer les informations utilisateur dans Firebase Firestore

Environnement d'exécution

【Xcode】Version 12.0.1 【Swift】Version 5.3 【CocoaPods】version 1.9.3 【Firebase】version 6.29.0

Écran après montage

sample.gif

Code d'implémentation

SignUpModel.swift


import Foundation
import Firebase

//Puisque le délégué veut faire référence à faible, hériter de la classe
protocol SignUpModelDelegate: class {
    func createImageToFirestorageAction()
    func createUserToFirestoreAction(fileName: String?)
    func completedRegisterUserInfoAction()
}

class SignUpModel {
    
    //déléguer des références faibles pour éviter les fuites de mémoire
    weak var delegate: SignUpModelDelegate?
    
    func createUser(email: String, password: String) {
        //Enregistrer dans Firebase Auth
        Auth.auth().createUser(withEmail: email, password: password) { (res, err) in
            if let err = err {
                print("Échec de l'enregistrement dans Firebase Auth.\(err)")
                //Traitement lorsque l'enregistrement des informations utilisateur échoue
                return
            }
            print("Enregistrement réussi dans Firebase Auth.")
            //Enregistrement terminé dans Firebase Auth->Enregistrer dans Firebase Storage
            self.delegate?.createImageToFirestorageAction()
        }
    }
    
    func creatrImage(fileName: String, uploadImage: Data) {
        //Enregistrer dans Firebase Storage
        let storageRef = Storage.storage().reference().child("profile_image").child(fileName)
        storageRef.putData(uploadImage, metadata: nil) { (metadate, err) in
            if let err = err {
                print("Échec de l'enregistrement dans Firestorage.\(err)")
                //Traitement lorsque l'enregistrement des informations utilisateur échoue
                return
            }
            print("Enregistré avec succès dans Firestorage.")
            //Enregistrement terminé dans Firebase Storage->Enregistrer dans Firebase Firestore
            self.delegate?.createUserToFirestoreAction(fileName: fileName)
        }
    }
    
    func createUserInfo(uid: String, docDate: [String : Any]) {
        //Enregistrer dans Firebase Firestore
        Firestore.firestore().collection("users").document(uid).setData(docDate as [String : Any]) { (err) in
            if let err = err {
                print("Échec de l'enregistrement dans Firestore.\(err)")
                //Traitement lorsque l'enregistrement des informations utilisateur échoue
                return
            }
            print("Vous avez enregistré avec succès dans le Firestore.")
            //Traitement lorsque l'enregistrement des informations utilisateur est terminé
            self.delegate?.completedRegisterUserInfoAction()
        }
    }

}

SignUpViewController.swift


import UIKit
import Firebase
import FirebaseStorage
import IQKeyboardManagerSwift

class SignUpViewController: UIViewController {
    
    @IBOutlet weak var profileImageButton: UIButton!
    @IBOutlet weak var emailTextField: UITextField!
    @IBOutlet weak var passwordTextField: UITextField!
    @IBOutlet weak var userNameTextField: UITextField!
    @IBOutlet weak var signUpButton: UIButton!
    
    let signUpModel = SignUpModel()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        IQKeyboardManager.shared.enable = true
        
        emailTextField.delegate = self
        passwordTextField.delegate = self
        userNameTextField.delegate = self
        signUpModel.delegate = self
        
        //Traitement de l'interface utilisateur d'écran
        setupUI()
        
    }
    
    //Traitement de l'interface utilisateur d'écran
    func setupUI() {
        signUpButton.layer.cornerRadius = 3
        signUpButton.isEnabled = false
        profileImageButton.layer.masksToBounds = true
        profileImageButton.layer.cornerRadius = 75
        profileImageButton.layer.borderColor = UIColor.lightGray.cgColor
        profileImageButton.layer.borderWidth  = 0.1
    }
    
    //Sélectionnez l'image de profil (transition vers la photothèque)
    @IBAction func profileImageButtonAction(_ sender: Any) {
        let imagePickerController = UIImagePickerController()
        imagePickerController.allowsEditing = true
        imagePickerController.delegate = self
        self.present(imagePickerController, animated: true, completion: nil)
    }
    
    //Nouveau processus d'inscription
    @IBAction func signUpButtonAction(_ sender: Any) {
        
        guard let email = emailTextField.text,
              let password = passwordTextField.text
        else { return }
        
        //Enregistrer dans Firebase Auth
        signUpModel.createUser(email: email, password: password)      
    }
    
    #···réduction···
    
    //Traitement pour enregistrer l'image de profil sur Firebase Storage
    private func createImageToFirestorage() {
        //Traitement lorsque l'image de profil est définie
        if let image = self.profileImageButton.imageView?.image {
            let uploadImage = image.jpegData(compressionQuality: 0.5)
            let fileName = NSUUID().uuidString
            //Enregistrer dans Firebase Storage
            signUpModel.creatrImage(fileName: fileName, uploadImage: uploadImage!) 
        } else {
            print("Étant donné que l'image de profil n'est pas définie, ce sera l'image par défaut.")
            //Enregistrer les informations utilisateur dans Firebase Firestore
            self.createUserToFirestore(profileImageName: nil)
        } 
    }
    
    //Traitement pour enregistrer les informations utilisateur dans Firebase Firestore
    private func createUserToFirestore(profileImageName: String?) {
        
        guard let email = Auth.auth().currentUser?.email,
              let uid = Auth.auth().currentUser?.uid,
              let userName = self.userNameTextField.text
        else { return }
        
        //Définir le contenu enregistré (type dictionnaire)
        let docData = ["email": email,
                       "userName": userName,
                       "profileImageName": profileImageName,
                       "createdAt": Timestamp()] as [String : Any?]
        
        //Enregistrer dans Firebase Firestore
        signUpModel.createUserInfo(uid: uid, docDate: docData as [String : Any])
    }
    
}

extension SignUpViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    //Méthode appelée lorsqu'une photo est sélectionnée
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let editedImage = info[.editedImage] as? UIImage {
            profileImageButton.setImage(editedImage.withRenderingMode(.alwaysOriginal), for: .normal)
        } else if let originalImage = info[.originalImage] as? UIImage {
            profileImageButton.setImage(originalImage.withRenderingMode(.alwaysOriginal), for: .normal)
        }
        dismiss(animated: true, completion: nil)
    }
    
}

extension SignUpViewController: UITextFieldDelegate {
    //Une méthode appelée lorsque la sélection de texte est modifiée dans textField
    func textFieldDidChangeSelection(_ textField: UITextField) {
        //Variable pour déterminer si textField est vide(Type booléen)Défini dans
        let emailIsEmpty = emailTextField.text?.isEmpty ?? true
        let passwordIsEmpty = passwordTextField.text?.isEmpty ?? true
        let userNameIsEmpty = userNameTextField.text?.isEmpty ?? true
        //Traitement lorsque tous les textFields ont été remplis
        if emailIsEmpty || passwordIsEmpty || userNameIsEmpty {
            signUpButton.isEnabled = false
            signUpButton.backgroundColor = UIColor.systemGray2
        } else {
            signUpButton.isEnabled = true
            signUpButton.backgroundColor = UIColor(named: "lineGreen")
        }
    }
    
    //Le clavier se ferme lorsque vous appuyez sur autre chose que textField
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }
}

extension SignUpViewController: SignUpModelDelegate {
            
    //Enregistrement terminé dans Firebase Auth->Enregistrer dans Firebase Storage
    func createImageToFirestorageAction() {
        print("Enregistrement réussi dans Firebase Auth.")
        self.createImageToFirestorage()
    }
    
    //Enregistrement terminé dans Firebase Storage->Enregistrer dans Firebase Firestore
    func createUserToFirestoreAction(fileName: String?) {
        print("Enregistré avec succès dans Firestorage.")
        self.createUserToFirestore(profileImageName: fileName)
    }
    
    //Traitement lorsque l'enregistrement des informations utilisateur est terminé
    func completedRegisterUserInfoAction() {
        //Transition d'écran vers ChatListViewController
        let storyboard = UIStoryboard(name: "ChatList", bundle: nil)
        let chatListVC = storyboard.instantiateViewController(withIdentifier: "ChatListVC") as! ChatListViewController
        let nav = UINavigationController(rootViewController: chatListVC)
        nav.modalPresentationStyle = .fullScreen
        nav.modalTransitionStyle = .crossDissolve
        self.present(nav, animated: true, completion: nil)
    }
    
}

Puisque nous nous concentrons sur le traitement lié à Firebase, nous omettons l'explication des éléments suivants.

--À propos de la gestion des erreurs --À propos de ʻUIActivityIndicatorView --À propos de ʻUIImagePickerController ――À propos d'IQKeyboardManagerSwift` (Pour plus de détails, reportez-vous à ici.)

Préparation

① Prérequis

Nous procéderons en supposant que les éléments suivants ont été complétés.

--Création d'un projet Firebase

Si vous n'en avez pas encore entendu parler, veuillez consulter la Documentation.

② Préparation côté Xcode

Ajoutez ce qui suit au «Podfile» et effectuez une «installation du pod» dans le terminal.

  pod 'Firebase/Analytics'
  pod 'Firebase/Auth'
  pod 'Firebase/Core'
  pod 'Firebase/Firestore'
  pod 'Firebase/Storage'
  pod 'FirebaseUI/Storage'

③ Préparation côté Firebase

スクリーンショット 2020-10-12 20.15.13.png Sélectionnez "Mail / Mot de passe" dans l'onglet "Méthode de connexion" comme indiqué ci-dessus. Ouvrez l'écran d'édition avec l'icône en forme de crayon.

スクリーンショット 2020-10-12 20.15.21.png Enregistrez-le une fois activé. C'est la fin de la préparation.

Détails d'implémentation ① (édition Firebase Auth)

SignUpViewController.swift


//Nouveau processus d'inscription
@IBAction func signUpButtonAction(_ sender: Any) {
        
    guard let email = emailTextField.text,
          let password = passwordTextField.text
    else { return }
        
    //Enregistrer dans Firebase Auth
    signUpModel.createUser(email: email, password: password)      
}

SignUpModel.swift


func createUser(email: String, password: String) {
    //Enregistrer dans Firebase Auth
    Auth.auth().createUser(withEmail: email, password: password) { (res, err) in
        if let err = err {
            print("Échec de l'enregistrement dans Firebase Auth.\(err)")
            //Traitement lorsque l'enregistrement des informations utilisateur échoue
            return
        }
        print("Enregistrement réussi dans Firebase Auth.")
        //Enregistrement terminé dans Firebase Auth->Enregistrer dans Firebase Storage
        self.delegate?.createImageToFirestorageAction()
    }
}

Détails d'implémentation (2) (Firebase Storage)

SignUpViewController.swift


//Enregistrement terminé dans Firebase Auth->Enregistrer dans Firebase Storage
func createImageToFirestorageAction() {
    print("Enregistrement réussi dans Firebase Auth.")
    self.createImageToFirestorage()
}

SignUpViewController.swift


//Traitement pour enregistrer l'image de profil sur Firebase Storage
private func createImageToFirestorage() {
    //Traitement lorsque l'image de profil est définie
    if let image = self.profileImageButton.imageView?.image {
        //Compresser l'image
        let uploadImage = image.jpegData(compressionQuality: 0.5)
        //Obtenez un identifiant unique
        let fileName = NSUUID().uuidString
        //Enregistrer dans Firebase Storage
        signUpModel.creatrImage(fileName: fileName, uploadImage: uploadImage!) 
    } else {
        print("Étant donné que l'image de profil n'est pas définie, ce sera l'image par défaut.")
        //Enregistrer les informations utilisateur dans Firebase Firestore
        self.createUserToFirestore(profileImageName: nil)
    } 
}

SignUpModel.swift


func creatrImage(fileName: String, uploadImage: Data) {
    //Enregistrer dans Firebase Storage
    let storageRef = Storage.storage().reference().child("profile_image").child(fileName)
    storageRef.putData(uploadImage, metadata: nil) { (metadate, err) in
        if let err = err {
            print("Échec de l'enregistrement dans Firestorage.\(err)")
            //Traitement lorsque l'enregistrement des informations utilisateur échoue
            return
        }
        print("Enregistré avec succès dans Firestorage.")
        //Enregistrement terminé dans Firebase Storage->Enregistrer dans Firebase Firestore
        self.delegate?.createUserToFirestoreAction(fileName: fileName)
    }
}

Détails d'implémentation ③ (édition Firebase Firestore)

SignUpViewController.swift


//Enregistrement terminé dans Firebase Storage->Enregistrer dans Firebase Firestore
func createUserToFirestoreAction(fileName: String?) {
    print("Enregistré avec succès dans Firestorage.")
    self.createUserToFirestore(profileImageName: fileName)
}

SignUpViewController.swift


//Traitement pour enregistrer les informations utilisateur dans Firebase Firestore
private func createUserToFirestore(profileImageName: String?) {
        
    guard let email = Auth.auth().currentUser?.email,
          let uid = Auth.auth().currentUser?.uid,
          let userName = self.userNameTextField.text
    else { return }
        
    //Définir le contenu enregistré (type dictionnaire)
    let docData = ["email": email,
                   "userName": userName,
                   "profileImageName": profileImageName,
                   "createdAt": Timestamp()] as [String : Any?]
        
    //Enregistrer dans Firebase Firestore
    signUpModel.createUserInfo(uid: uid, docDate: docData as [String : Any])
}

SignUpModel.swift


func createUserInfo(uid: String, docDate: [String : Any]) {
    //Enregistrer dans Firebase Firestore
    Firestore.firestore().collection("users").document(uid).setData(docDate as [String : Any]) { (err) in
        if let err = err {
            print("Échec de l'enregistrement dans Firestore.\(err)")
            //Traitement lorsque l'enregistrement des informations utilisateur échoue
            return
        }
        print("Vous avez enregistré avec succès dans le Firestore.")
        //Traitement lorsque l'enregistrement des informations utilisateur est terminé
        self.delegate?.completedRegisterUserInfoAction()
    }
}

SignUpViewController.swift


//Traitement lorsque l'enregistrement des informations utilisateur est terminé
func completedRegisterUserInfoAction() {
    //Transition d'écran vers ChatListViewController
    #···réduction···
}

référence

Recommended Posts

[Swift 5] Implémentation de l'enregistrement des membres dans Firebase
Implémentation de XLPagerTabStrip avec TabBarController
Comment obtenir l'ID d'un utilisateur qui s'est authentifié avec Firebase dans Swift
Mémo d'implémentation SKStoreReviewController dans l'interface utilisateur Swift d'iOS14
[Swift] C'est la solution! Illustration de la mise en œuvre du délégué
[Swift] Comment obtenir l'ID de document Firebase
Implémentation de la fonction de recherche
Implémentation appliquée de l'espace de chat
Premiers pas avec Swift
Mise en œuvre de la fonction de pagénation
Enregistrement de plusieurs WebMvcConfigurers
À partir de Swift Swift UI
Implémentation de la pagination avec gem'kaminari '
[Java] Simplifiez la mise en œuvre de la gestion de l'historique des données avec Reladomo
Implémentation d'un analyseur de syntaxe mathématique par méthode d'analyse syntaxique descendante récursive (Java)