当用户通过FB登录按钮完成授权时,我正在使用协调器(符合LoginButtonDelegate)对象来接收用户数据(配置文件,名称)。 使用用户ID更新了Coordinator()。userId属性,但我需要将其传递给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()
}
}
}
答案 0 :(得分:1)
尝试以下操作,因为在更新过程中创建了协调器,所以应该已经注入并显示了环境对象,所以它应该可以工作
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()
}
}
}