![](/img/trans.png)
[英]How can I access an EnvironmentObject from within a NSViewRepresentable / UIViewRepresentable 's Coordinator class?
[英]How to update EnvironmentObject variable from Coordinator class?
當用戶通過 FB 登錄按鈕完成授權時,我正在使用協調器(符合 LoginButtonDelegate)object 來接收用戶數據(個人資料、姓名)。 Coordinator().userId 屬性使用用戶 ID 進行更新,但我需要將其傳遞到 LoginView 1 級並更新名為 thisSession 的 EnvironmentObject(以某種方式使 thisSession.userId = Coordinator().userId)。
有沒有辦法做到這一點? 我嘗試使用 ObservableObject/Published 屬性,但我無法從 Coordinator 更新父對象的屬性。
另一個想法是訂閱 Auth.auth() 更改,但它似乎太復雜而且有點“老派”的解決方案。 有一些我想念的簡單方法。
任何提示/想法?
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()
}
}
}
嘗試以下操作,因為在更新環境時會創建協調器 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.