微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Firebase中使用DispatchQueue更新UI-SwiftUI

如何解决在Firebase中使用DispatchQueue更新UI-SwiftUI

我正在尝试使用dispatchQueue更新我的UI,因此当Firebase对用户进行身份验证时,我可以将新创建​​的数据传递到下一个屏幕。

我有一个SignUpView注册一个用户,然后在成功后转到ProfileViewProfileView允许用户为应用程序添加更多具体细节。

我有一个userSession对象,该对象已成功登录用户,但没有立即在下一个屏幕上更新UI。这可能是因为我没有正确使用dispatchQueue.main.async,我无法在SwiftUI的View构建器的主体中使用它。

这里是一个View,我用来填充从ProfileView获得的SignUpView中的用户名

注意:当我传递到HomeView时,将显示用户名和其他重要信息。我认为这是因为此时数据库已更新并且可以开始读取值。


struct VitalsHeaderView: View {
    @EnvironmentObject var session: SessionStore
    
    var body: some View {
        vstack {
            if session.isLoggedIn {
                Text(session.userSession!.username)
                    .font(.system(size: 20,weight: .bold))
                    .frame(maxWidth: .infinity,alignment: .leading)
                    .foregroundColor(Color(#colorLiteral(red: 0.501960814,green: 0.501960814,blue: 0.501960814,alpha: 1)))
            }
        }
        .padding(.top,30)
        .padding(.leading,30)
    }
}

在下面,您会看到一个无效的hack,它不起作用,但这就像我想做的一样。如何使用调度队列更新UI?

struct VitalsHeaderView: View {
    @EnvironmentObject var session: SessionStore
    @Observedobject var signUpviewmodel = SignUpviewmodel()

    func updateUI() {
        dispatchQueue.main.asyncAfter(deadline: .Now() + 2) {
            self.session.isLoggedIn = true
        }
    }
    
    var body: some View {
        vstack {
            if session.isLoggedIn {
                Button(action: updateUI) {
                    Text(session.userSession!.username)
                        .font(.system(size: 20,weight: .bold))
                        .frame(maxWidth: .infinity,alignment: .leading)
                        .foregroundColor(Color(#colorLiteral(red: 0.501960814,alpha: 1)))
                }
            }
        }
        .padding(.top,30)
    }
}

已更新

这是我的SessionStore代码


import Foundation
import Combine
import Firebase

class SessionStore: ObservableObject {
    
    @Published var isLoggedIn: Bool = UserDefaults.standard.bool(forKey: "isLoggedIn") {
        didSet {
            UserDefaults.standard.set(self.isLoggedIn,forKey: "isLoggedIn")
        }
    }
    
    var userSession: User?
    
    var handle: AuthStateDidchangelistenerHandle?
    
    func listenAuthenticationState() {
        handle = Auth.auth().addStateDidchangelistener({ (auth,user) in
            if let user = user {
                print(user.email as Any)
                let firestoreUserId = Ref.FIRESTORE_DOCUMENT_USERID(userId: user.uid)
                firestoreUserId.getDocument { (document,error) in
                    if let dict = document?.data() {
                        guard let decodeUser = try? User.init(fromDictionary: dict) else { return }
                        dispatchQueue.main.async {
                           self.userSession = decodeUser
                           self.isLoggedIn = true
                        }
                    }
                }
            } else {
                self.isLoggedIn = false
                self.userSession = nil
            }
        })
    }
    
    func logout() {
        do {
            try Auth.auth().signOut()
        } catch  {
        }
    }
    
    func unbind() {
        if let handle = handle {
            Auth.auth().removeStateDidchangelistener(handle)
        }
    }
    
    deinit {
        unbind()
    }
}

我在VitalsHeaderView中初始化ProfileView,它是VitalsHeaderView之上的结构。


struct ProfileView: View {
    @EnvironmentObject var session: SessionStore
    
    @Observedobject var profileviewmodel = Profileviewmodel()
    @Observedobject var signUpviewmodel = SignUpviewmodel()
    
    var body: some View {
        ZStack {
            Color(#colorLiteral(red: 0.9058823529,green: 0.9254901961,blue: 0.968627451,alpha: 1)).edgesIgnoringSafeArea(.all)
            ZStack(alignment: .top) {
                Color(#colorLiteral(red: 0.9058823529,alpha: 1))
                    .clipShape(RoundedRectangle(cornerRadius: 30,style: .continuous))
                    .edgesIgnoringSafeArea(.bottom)
                
                ScrollView(.vertical,showsIndicators: false) {
                    
                    vstack {
                        ProfileHeaderView(signUpviewmodel: signUpviewmodel)
                        
                        VitalsHeaderView(signUpviewmodel: signUpviewmodel)
      
                        ShareProfileView(profileviewmodel: profileviewmodel)
                    }
                    .padding(.top,30)
                }
            }
        }
        .navigationBarHidden(true)
        .navigationBarTitle("")
    }
}

注意:我刚刚添加(并测试了)将signUpviewmodel属性添加到Vitals Header View中,仍然没有任何作用

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。