Créer une page de connexion :
Storyboard : embed in Navigation controller - on peut supprimer la navigation bar en se positionnant sur la racine Navigation Controller et dans inspecteur d'attributs, décocher "Shows Navigation Bar".
Ajouter textFields, segment, bouton. Remplacer viewController par nouveau fichier LogController. Créer les IBOutlets.
class LogController: ViewController {
@IBOutlet weak var mailTF: UITextField!
@IBOutlet weak var passWordTF: UITextField!
@IBOutlet weak var surnameTF: UITextField!
@IBOutlet weak var nameTF: UITextField!
@IBOutlet weak var segmented: UISegmentedControl!
Création nouveau fichier FireAuth.swift et utilisation Auth.auth() pour vérifier l'authentification
import Firebase
class FireAuth {
func isAuth() -> Bool {
return Auth.auth().currentUser?.uid != nil
}
}
Dans LogController.swift, implémentation des fonctions setupUI(), updateVisible(), pour afficher les textFields en fonction d'une connexion ou création de compte.
func setupUI() {
if FireAuth().isAuth() {
print("auth == true")
} else {
updateVisible(true, mailTF)
updateVisible(true, passWordTF)
let bool = segmented.selectedSegmentIndex != 0
updateVisible(bool, surnameTF)
updateVisible(bool, nameTF)
}
}
func updateVisible(_ bool: Bool, _ view: UIView) {
view.isHidden = !bool
}
Ajout de "override func touchesBegan" pour cacher le clavier.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)
}
Dans "func validateButton()" on gère les champs textFields. Si les champs sont vides on prévoit des alertes pour différents cas de figure (champs vide, erreur,....).
ALERTES :
Pour utiliser ces alertes dans toute l'application, on crée une fonction "Alerte" dans un controller racine = un RootController. Chaque alerte aura un titre et un message en fonction de la situation, d'où les paramètres de la fonction :
func showAlert(_ titre: String?, _ message: String?) {
let alert = UIAlertController(title: titre, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "retour", style: .destructive, handler: { (action) in
alert.removeFromParent()
}))
self.present(alert, animated: true, completion: nil)
}
On ajoute une action à l'alerte pour la fermer, dans une closure.
LogController hérite donc de RootController, pour utiliser les alertes
class LogController: RootController {
Les alertes sont gérables, on implémente les différents cas de champs vides, dans la fonction "validateButton()"
@IBAction func validateButton(_ sender: UIButton) {
if let mail = mailTF.text, mail != "" {
if let password = passWordTF.text, password != "" {
if segmented.selectedSegmentIndex == 0 {
//Authentification
} else {
if let surname = surnameTF.text, surname != "" {
if let name = nameTF.text, name != "" {
} else {
//Alert pas de name
showAlert("Champs vide", "Merci de renseigner votre nom")
}
} else {
//Alert pas de surname
showAlert("Champs vide", "Merci de renseigner votre prénom")
}
}
} else {
//alert pas de pwd
showAlert("Champs vide", "Merci de renseigner votre mot de passe")
}
} else {
// alert pas de mail
showAlert("Champs vide", "Merci de renseigner votre adresse mail")
}
}
Authentification
Dans Firebase/Authentification, choisir l'authentification par email et mot de passe.
Le Auth de Firebase va géré l'email et le mot de passe, donc peut indiquer si on est connecté ou pas.
Les informations sur l'utilisateur (nom, prénom) vont être stockées dans une base de données à part = CloudFirestore.
Donc dans Firebase/CloudFirestore, créer une base de données, en mode de production. Choisir la zone géographique de stockage.
Dans les règles de sécurité (rules), autoriser la lecture et l'écriture si on est identifié, à la place de "if false"
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
Retour dans Xcode
Dans FireAuth.swift, implémenter les fonctions signIn(), createUser(), et signOut()
var completion: ((_ uid: String?, _ error: String?) -> Void)?
func signIn(_ mail: String, _ pwd: String, completion: ((_ uid: String?, _ error: String?) -> Void)?) {
self.completion = completion
Auth.auth().signIn(withEmail: mail, password: pwd, completion: handleResult(_:_:))
}
func createUser(_ mail: String, _ pwd: String, completion: ((_ uid: String?, _ error: String?) -> Void)?) {
self.completion = completion
Auth.auth().createUser(withEmail: mail, password: pwd, completion: handleResult(_:_:))
}
func signOut() {
}
func handleResult( _ data: AuthDataResult?, _ error: Error?) {
if error != nil {
self.completion?(nil, error?.localizedDescription)
}
if let uid = data?.user.uid {
self.completion?(uid, nil)
}
}
On créé un nouveau fichier pour la base de données CloudFirestore = FireDatabase.swift
Et on implémente la "func addUser()"
import Firebase
class FireDatabase {
// chemin d'accès à la base du projet
let base = Firestore.firestore()
// chemin d'accès à la collection nommée "users", si elle n'existe pas, elle est créée
var usersCollection: CollectionReference {
return base.collection("users")
}
func addUser(_ uid: String, data: [String: Any]) {
usersCollection.document(uid).setData(data)
// dans la collection "users", on créé un document attaché à l'uid de Auth
// ce document comprendra un tableau de data, exemple : [name: wood, surname: matt]
}
}
Dans LogController.swift, on se sert des nouvelles fonctions dans "func validateButton()"
@IBAction func validateButton(_ sender: UIButton) {
if let mail = mailTF.text, mail != "" {
if let password = passWordTF.text, password != "" {
if segmented.selectedSegmentIndex == 0 {
//Authentification
FireAuth().signIn(mail, password) { (uid, error) in
if error != nil {
self.showAlert("Erreur", "erreur lors lors de l'authentification")
}
if uid != nil {
//vers le controller suivant
}
}
} else {
if let surname = surnameTF.text, surname != "" {
if let name = nameTF.text, name != "" {
//Création du compte
FireAuth().createUser(mail, password) { (uid, error) in
if error != nil {
self.showAlert("Erreur", "erreur lors de la création du compte")
}
if uid != nil {
let data: [String: Any] = ["name": name, "surname": surname, "uid": uid!]
FireDatabase().addUser(uid!, data: data)
// affichage alerte pour confirmer la connexion, à supprimer par la suite
self.showAlert("Bienvenue \(surname)", "votre compte a été créé")
}
}
} else { ...