如何解决在Firebase中使用DispatchQueue更新UI-SwiftUI
我正在尝试使用dispatchQueue
更新我的UI,因此当Firebase对用户进行身份验证时,我可以将新创建的数据传递到下一个屏幕。
我有一个SignUpView
会注册一个用户,然后在成功后转到ProfileView
。 ProfileView
允许用户为应用程序添加更多具体细节。
我有一个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 举报,一经查实,本站将立刻删除。