Créez une fonction de connexion à l'aide de l'option Swift

Un examen léger de facultatif

Qu'est-ce qui est facultatif

Swift fournit un type spécial appelé type facultatif. Un type facultatif est un type qui peut être défini pour une valeur exceptionnellement nulle en dehors du type qu'il a normalement.

Par exemple, lorsque la variable ʻoptionalName, qui a normalement une chaîne, peut être affectée de zéro dans certains cas spéciaux, la variable ʻoptionalName peut être exprimée comme` String?

var optionalName: String? = "Brian"

optionalName = nil //Puisqu'il s'agit d'un type String facultatif, nil peut également être attribué.

En autorisant l'affectation de nil, même si nil est exceptionnellement inclus dans la variable, il est possible d'empêcher l'application de planter en effectuant une vérification de nil avec branchement conditionnel.

var optionalName: String? = "Brian"

optionalName = nil //Puisqu'il s'agit d'un type String facultatif, nil peut également être attribué.

if optionalName == nil {
    print("Nil est attribué au nom.")
} else {
    print( optionalName! ) //Valeur facultative si non nulle!Il est nécessaire de divulguer la valeur avec
}

Syntaxe de liaison facultative

Comme mentionné ci-dessus, il existe un moyen de déterminer si le type facultatif est nul avec l'instruction if, mais Swift fournit également la ** syntaxe de liaison facultative **.

var optionalName: String? = "Brian"

if let name = optionalName {
    print( name )
}

En écrivant de cette façon, si ʻoptionalName n'est pas nul, la valeur sera assignée à nom` et vous pouvez entrer la branche conditionnelle. De plus, à ce stade, il n'est pas nécessaire de divulguer "nom" car la valeur facultative est divulguée au moment de l'attribution de "nom".

Pour une explication plus détaillée d'Optionnel, veuillez voir ici Type optionnel extrême de Swift [Chapitre 4 détaillé de Swift 5th Edition facultatif](https://www.amazon.co.jp/%E8%A9%B3%E8%A7%A3-Swift-%E7%AC%AC5%E7%89%88- % E8% 8D% BB% E5% 8E% 9F-% E5% 89% 9B% E5% BF% 97 / dp / 48150407X)

Traitement de connexion / déconnexion à titre d'exemple

Prenons le processus de connexion / déconnexion de l'application comme exemple pour voir quand cela peut être bénéfique dans Swift.

Bien que ce soit approximatif, cette fois, je suppose une application qui combine «Affichage de connexion» pour la connexion, «Affichage du contenu» après la connexion et «État de l'application» qui contient les informations sur l'utilisateur connecté comme suit. ..

struct1.png

Exemple de code

Le premier est AppState. Il s'agit d'une classe qui contient les informations de l'utilisateur qui se connecte et qui est censée être référencée à partir de chaque vue.

La structure «Session» est définie comme un EnvironmentObject.

///Classe de référentiel qui stocke les informations utilisateur
class User: Identifiable {
    public var uid: String
    public var email: String?

    init(uid: String, email: String) {
        self.uid = uid
        self.email = email
    }
}

class AppState: ObservableObject {
    
    //Structure de gestion de l'état d'authentification
    struct Session {
        var user: User?
        var handler: AuthStateDidChangeListenerHandle? //Objet contenant les informations sur l'utilisateur connecté
    }
    
    @Published public var session = Session()
}

Vient ensuite la classe Interactor qui gère le traitement (connexion / déconnexion) lié à Session.

import Firebase

class SessionInteractor {
  
    public var appState: AppState

    ///Obtenez EnvironmentObject à partir du composant View et stockez-le dans la propriété de classe
    init(appState: AppState) {
        self.appState = appState
    }
  
    ///Processus appelé chaque fois que l'état de connexion de l'utilisateur change
  	public func listen() {
        self.appState.session.handler = Auth.auth().addStateDidChangeListener { (auth, user) in
            //Retour anticipé à l'aide de la déclaration Guard Let
            guard let user = user else {
                self.appState.session.user = nil
                return
            }            
            //Ajouté à la propriété utilisateur de type Session
            self.appState.session.user = User(
                uid: user.uid,
                email: user.email!
            )
        }
    }
  
    ///Processus de connexion
    public func signIn() {
       //Processus de connexion à l'aide de l'authentification Firebase
       //Nous attachons des objets FIRAuth, mais le traitement détaillé est omis.
        Auth.auth().signIn(/* [Omission]Connectez-vous avec l'authentification Firebase*/)
    }
  
    ///Processus de déconnexion
    public func signOut() -> Bool {
        do {
            try Auth.auth().signOut()
            self.appState.session.user = nil
            return true
        } catch {
            return false
        }
    }
}

Vient ensuite le code de chaque vue.

import SwiftUI

struct SignInView: View {
    @EnvironmentObject var appState: AppState
    
    var body: some View {
        VStack() {
            TextField("adresse mail", text: $email)
            SecureField("mot de passe", text: $password)
            Button(action: self.signIn) {
                Text("se connecter")
            }
        }
    }
    
    ///Méthode pour se connecter
    private func signIn() {
       let sessionInteractor = SessionInteractor(appState: self.appState)
        let result = sessionInteractor.signIn()
    }
}

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var appState: AppState
    
    var body: some View {
        VStack() {
            if let user = self.appState.session.user {
                Text("Bonjour,\(user.email!)")
                Button(action: self.signOut) {
                  Text("Déconnexion")
                }
            }
        }.onAppear(perform: self.loadUserInfo)
    }
    
  	//Appelez le processus de déconnexion
    private func signOut() {
        let sessionInteractor = SessionInteractor(appState: self.appState)
        let result = sessionInteractor.signOut()
    }
}

Définition et divulgation de facultatif

L'objet ʻUser` que possède AppState est au cœur de cette période.

//Structure de gestion de l'état d'authentification
struct Session {
    var user: User? //Une structure qui a des informations utilisateur comme propriété, bien que la description soit omise.
    var handler: AuthStateDidChangeListenerHandle? //Objet contenant les informations sur l'utilisateur connecté
}

Ceux-ci sont définis comme facultatifs car l'objet de l'utilisateur connecté est nil avant la connexion, après la déconnexion, etc. Après la connexion et la saisie des informations utilisateur dans l'objet Utilisateur, nous divulguons ces informations dans la vue.

var body: some View {
    VStack() {
        if let user = self.appState.session.user {
            Text("Bonjour,\(user.email!)") // !Divulguer et afficher dans
            Button(action: self.signOut) {
              Text("Déconnexion")
            }
        }
    }.onAppear(perform: self.loadUserInfo)
}

Ce à quoi je voudrais faire attention ici, c'est la partie qui se branche en utilisant la ** syntaxe de liaison facultative **.

if let user = self.appState.session.user {

En écrivant ceci, peu importe si l'objet ʻUser devient nil` après que l'utilisateur se soit déconnecté. Au contraire, si cela n'est pas décrit, le côté Vue recevra le «nil» attribué au moment de la déconnexion, et l'application plantera.

Fatal error: Unexpectedly found nil while unwrapping an Optional value
try Auth.auth().signOut()
self.appState.session.user = nil //Les informations utilisateur sont supprimées lors de la déconnexion

struct2.png

Sommaire

Cette fois, j'ai pris comme exemple la connexion / déconnexion, mais je pense qu'il existe de nombreux cas où plusieurs vues font référence à la même valeur lors de la création d'une application mobile. Plus vous référencez de vues, plus vous avez de chances de recevoir ** nil inattendu **, ce qui peut entraîner le blocage de votre application, mais vous pouvez les empêcher en utilisant le type facultatif. .. Tout ne doit pas être facultatif, mais pour les propriétés et les variables ** qui sont censées être affectées à ** nil, utilisez Optional!

référence

Essayez l'authentification Firebase sur iOS Type optionnel extrême de Swift [Chapitre 4 détaillé de Swift 5th Edition facultatif](https://www.amazon.co.jp/%E8%A9%B3%E8%A7%A3-Swift-%E7%AC%AC5%E7%89%88- % E8% 8D% BB% E5% 8E% 9F-% E5% 89% 9B% E5% BF% 97 / dp / 48150407X)

Recommended Posts

Créez une fonction de connexion à l'aide de l'option Swift
Créer une fonction de filtrage en utilisant actes-as-taggable-on
Créer une loterie avec Ruby
[Android] Créer un calendrier à l'aide de GridView
Créer un projet Jetty à l'aide d'Eclipse
Créer un projet Tomcat à l'aide d'Eclipse
Créer un projet Java à l'aide d'Eclipse
[Procédure d'implémentation] Créer une fonction d'authentification utilisateur à l'aide de sorcellerie dans Rails
Fonction de connexion
Créez rapidement un environnement Web à l'aide de Docker
[Retrait des rails] Créez une fonction de retrait simple avec des rails
Créer un service d'API RESTful à l'aide de Grape
Créez quand même une fonction de connexion avec Rails
Créer une fonction d'authentification dans l'application Rails à l'aide de devise
[Android] Créer un menu coulissant sans utiliser la vue de navigation
Créez instantanément un environnement Privoxy + Tor à l'aide de Docker
Créons une API REST à l'aide de WildFly Swarm.
[Rails] Comment créer un graphique à l'aide de lazy_high_charts
Créez un environnement de développement Java à l'aide de jenv sur votre Mac
Créer un site EC avec Rails 5 ⑨ ~ Créer une fonction de panier ~
Un mémorandum lors de la tentative de création d'une interface graphique à l'aide de JavaFX
J'ai essayé de créer une fonction de connexion avec Java
[Java] Créer un filtre
[Rails DM] Créons une fonction de notification lorsque DM est envoyé!
Créer un projet Tomcat en utilisant Eclipse Pleiades All in One
Création d'un MOB à l'aide du plug-in Minecraft Java Mythicmobs | Préparation 1