[英]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.