简体   繁体   English

如何从协调器 class 更新 EnvironmentObject 变量?

[英]How to update EnvironmentObject variable from Coordinator class?

I'm using Coordinator (conforms to LoginButtonDelegate) object to receive user data (profile, name) when user completes authorisation via FB Login Button.当用户通过 FB 登录按钮完成授权时,我正在使用协调器(符合 LoginButtonDelegate)object 来接收用户数据(个人资料、姓名)。 Coordinator().userId property is updated with user ID but i need to pass it 1 level up to the LoginView and to update EnvironmentObject called thisSession (make thisSession.userId = Coordinator().userId somehow). Coordinator().userId 属性使用用户 ID 进行更新,但我需要将其传递到 LoginView 1 级并更新名为 thisSession 的 EnvironmentObject(以某种方式使 thisSession.userId = Coordinator().userId)。

Is there any way to do that?有没有办法做到这一点? I tried playing with ObservableObject/Published properties but i can't update parent object's properties from Coordinator.我尝试使用 ObservableObject/Published 属性,但我无法从 Coordinator 更新父对象的属性。

Another idea is to subscribe to Auth.auth() changes but it seems too complicated and a bit "old school" solution.另一个想法是订阅 Auth.auth() 更改,但它似乎太复杂而且有点“老派”的解决方案。 There show be some easy way i am missing.有一些我想念的简单方法。

Any hints/ideas?任何提示/想法?

import SwiftUI
import FirebaseCore
import FirebaseAuth
import FBSDKLoginKit
import FBSDKCoreKit

struct LoginView: View {
    @EnvironmentObject var thisSession: CurrentSession
    @ObservedObject var mainData = MainViewModel()

    var facebookView = facebook()

    var body: some View {
        VStack {
            facebookView.frame(width: 240, height: 50)
            Text("\(self.thisSession.userId ?? "none")")
        }
    }
}

struct LoginView_Previews: PreviewProvider {
    static var previews: some View {
        LoginView().environmentObject(CurrentSession())
    }
}


struct facebook: UIViewRepresentable {
    @EnvironmentObject var thisSession: CurrentSession
    @ObservedObject var coordinator = Coordinator()

    func makeCoordinator() -> facebook.Coordinator {
        return self.coordinator
        //facebook.Coordinator()
    }

    func makeUIView(context: UIViewRepresentableContext<facebook>) -> FBLoginButton {

        let button = FBLoginButton()
        button.delegate = self.coordinator
        print("UPDATED")

        return button
    }

    func updateUIView(_ uiView: FBLoginButton, context: UIViewRepresentableContext<facebook>) {
    }

    class Coordinator: NSObject, LoginButtonDelegate, ObservableObject {
        @Published var userId: String?
        func loginButton(_ loginButton: FBLoginButton, didCompleteWith result: LoginManagerLoginResult?, error: Error?) {

            if error != nil{

                print((error?.localizedDescription)!)
                return
            }
            if AccessToken.current != nil{

                let credential = FacebookAuthProvider.credential(withAccessToken: AccessToken.current!.tokenString)

                Auth.auth().signIn(with: credential) { (res,er) in

                    if er != nil{
                        print((er?.localizedDescription)!)
                        return

                    }
                    print("email: \(String(describing: res?.user.email))")
                    print("name: \(String(describing: res?.user.displayName))")
                    self.userId = String(describing: res?.user.displayName)
                }
            }
        }

        func loginButtonDidLogOut(_ loginButton: FBLoginButton) {
            print("logged out")
            try! Auth.auth().signOut()

        }
    }

}

Try the following, as coordinator is created during update the environment object should be already injected and present, so it should work尝试以下操作,因为在更新环境时会创建协调器 object 应该已经注入并存在,所以它应该可以工作

struct facebook: UIViewRepresentable {
    @EnvironmentObject var thisSession: CurrentSession

    func makeCoordinator() -> facebook.Coordinator {
        Coordinator(session: thisSession)              // << here !!
    }

    func makeUIView(context: UIViewRepresentableContext<facebook>) -> FBLoginButton {

        let button = FBLoginButton()
        button.delegate = self.coordinator
        print("UPDATED")

        return button
    }

    func updateUIView(_ uiView: FBLoginButton, context: UIViewRepresentableContext<facebook>) {
    }

    class Coordinator: NSObject, LoginButtonDelegate, ObservableObject {
        let session: CurrentSession
        init(session: CurrentSession) {
            self.session = session
        }

        func loginButton(_ loginButton: FBLoginButton, didCompleteWith result: LoginManagerLoginResult?, error: Error?) {

            if error != nil{

                print((error?.localizedDescription)!)
                return
            }
            if AccessToken.current != nil{

                let credential = FacebookAuthProvider.credential(withAccessToken: AccessToken.current!.tokenString)

                Auth.auth().signIn(with: credential) { (res,er) in

                    if er != nil{
                        print((er?.localizedDescription)!)
                        return

                    }
                    print("email: \(String(describing: res?.user.email))")
                    print("name: \(String(describing: res?.user.displayName))")

                    DispatchQueue.main.async {   // << here 
                        self.session.userId = String(describing: res?.user.displayName)
                    }
                }
            }
        }

        func loginButtonDidLogOut(_ loginButton: FBLoginButton) {
            print("logged out")
            try! Auth.auth().signOut()

        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从 NSViewRepresentable / UIViewRepresentable 的协调器 class 中访问 EnvironmentObject? - How can I access an EnvironmentObject from within a NSViewRepresentable / UIViewRepresentable 's Coordinator class? 如何从类中为 EnvironmentObject 设置值? - How to set value to EnvironmentObject from class? 如何将值从 EnvironmentObject 传递到 SwiftUI 中的类实例? - How to pass a value from an EnvironmentObject to a class instance in SwiftUI? SwiftUI:如何持久化@EnvironmentObject变量? - SwiftUI: How to persist an @EnvironmentObject variable? SwiftUI - 来自协调器的 ObservableObject 更新 - SwiftUI - ObservableObject Update from Coordinator 如何在SwiftUI中不使用按钮更新@EnvironmentObject? - How to update @EnvironmentObject without button in SwiftUI? ios:如何从协调器类 SwiftUi 重新加载 webview - ios: How to reload webview from a Coordinator class SwiftUi 如何在辅助 Class 中正确处理 @EnvironmentObject - How to correctly handle @EnvironmentObject within secondary Class 将数据从委托 Swift Class 传递到 SwiftUI 结构中的 EnvironmentObject - Passing Data from Delegate Swift Class to EnvironmentObject in SwiftUI Struct 如何使用@EnvironmentObject 在 SwiftUI 中自动填充和更新列表? - How to use @EnvironmentObject to populate and update list automatically in SwiftUI?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM