コチラに記載されているサンプルコードの、処理の流れの認識を確認/指摘していただくとともに、
疑問点の解決をしていただければ幸いです。
ーーー処理の流れの認識ーーー
Firebaseの初期化後〜
【1】
ContentViewが開かれると同時に、onAppearメソッド→getUserメソッドの順で呼ばれる。
【2】
getUserメソッド内の、session.listen()により、
SessionStore内の、listenメソッド→addStateDidChangeListenerメソッドの順で呼ばれ、
if let user = userの条件分岐で、userがnilなので、
else節に飛び、変数sessionにnilが格納される。
【3】
ContentViewの、**if (session.session != nil)**の条件分岐で、
else節に飛び、SignInViewが開かれる。
【4】
SignInViewにて、email/passwordを入力後、Buttonを押すと、
SignInView内のsignInメソッド→SessionStore内のsignInメソッドの順で呼ばれ、
completion: handlerによって、addStateDidChangeListenerメソッドが再度呼ばれ、
変数sessionに、User型のインスタンスが格納される。
【5】
ContentViewを開くと、変数sessionがnilでは無いため、
**Hello user!**が表示される。
ーーー疑問点ーーー
removeStateDidChangeListenerメソッドを使用するタイミングは、サインアウトの際でしょうか?
このメソッドを呼び出すことで、どのような効果があるのか等、基本的な使い方が分かりません。
以下、サンプルコード
【SessionStore】
Swift
1import SwiftUI 2import Firebase 3import Combine 4 5class SessionStore : ObservableObject { 6 var didChange = PassthroughSubject<SessionStore, Never>() 7 var session: User? { didSet { self.didChange.send(self) }} 8 var handle: AuthStateDidChangeListenerHandle? 9 10 func listen () { 11 // monitor authentication changes using firebase 12 handle = Auth.auth().addStateDidChangeListener { (auth, user) in 13 if let user = user { 14 // if we have a user, create a new user model 15 print("Got user: (user)") 16 self.session = User( 17 uid: user.uid, 18 displayName: user.displayName, 19 email: user.email 20 ) 21 } else { 22 // if we don't have a user, set our session to nil 23 self.session = nil 24 } 25 } 26 } 27 28 // additional methods (sign up, sign in) will go here 29 func signUp(email: String, 30 password: String, 31 handler: @escaping AuthDataResultCallback) { 32 Auth.auth().createUser(withEmail: email, password: password, completion: handler) 33 } 34 35 func signIn(email: String, 36 password: String, 37 handler: @escaping AuthDataResultCallback) { 38 Auth.auth().signIn(withEmail: email, password: password, completion: handler) 39 } 40 41 func signOut () -> Bool { 42 do { 43 try Auth.auth().signOut() 44 self.session = nil 45 return true 46 } catch { 47 return false 48 } 49 } 50 51 func unbind () { 52 if let handle = handle { 53 Auth.auth().removeStateDidChangeListener(handle) 54 } 55 } 56} 57 58class User { 59 var uid: String 60 var email: String? 61 var displayName: String? 62 63 init(uid: String, displayName: String?, email: String?) { 64 self.uid = uid 65 self.email = email 66 self.displayName = displayName 67 } 68 69}
【ContentView】=【SessionStoreView】
Swift
1import SwiftUI 2 3struct SessionStoreView: View { 4 @EnvironmentObject var session: SessionStore 5 6 func getUser () { 7 session.listen() 8 } 9 10 var body: some View { 11 Group { 12 if (session.session != nil) { 13 Text("Hello user!") 14 } else { 15 SignInView() 16 } 17 } 18 .onAppear(perform: getUser) 19 } 20}
【SignInView】
Swift
1import SwiftUI 2 3struct SignInView : View { 4 @State var email: String = "" 5 @State var password: String = "" 6 @State var loading = false 7 @State var error = false 8 9 @EnvironmentObject var session: SessionStore 10 11 func signIn () { 12 loading = true 13 error = false 14 session.signIn(email: email, password: password) { (result, error) in 15 self.loading = false 16 if error != nil { 17 self.error = true 18 } else { 19 self.email = "" 20 self.password = "" 21 } 22 } 23 } 24 25 var body: some View { 26 VStack { 27 TextField("email address", text: $email) 28 SecureField("Password", text: $password) 29 if (error) { 30 Text("ahhh crap") 31 } 32 Button(action: signIn) { 33 Text("Sign in") 34 } 35 } 36 } 37}
あなたの回答
tips
プレビュー