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
}
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)
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. ..
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()
}
}
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
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!
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