![](/img/trans.png)
[英]Calling an asynchronous method (getNotificationSettings) in the onAppear() method becomes nil - SwiftUI MVVM
[英]Firestore method in view model not invoking in SwiftUI onAppear method
我想实现一个文本字段来显示当前用户在数据库(Firestore)中的现有分数。 由于 Firebase 查询中异步的性质,我还需要对我的代码进行一些调整。 但是, completion()
处理程序似乎无法正常工作:
// ViewModel.swift
import Foundation
import Firebase
import FirebaseFirestore
class UserViewModel: ObservableObject {
let current_user_id = Auth.auth().currentUser!.uid
private var db = Firestore.firestore()
@Published var xp:Int?
func fetchData(completion: @escaping () -> Void) {
let docRef = db.collection("users").document(current_user_id)
docRef.getDocument { snapshot, error in
print(error ?? "No error.")
self.xp = 0
guard let snapshot = snapshot else {
completion()
return
}
self.xp = (snapshot.data()!["xp"] as! Int)
completion()
}
}
}
// View.swift
import SwiftUI
import CoreData
import Firebase
{
@ObservedObject private var users = UserViewModel()
var body: some View {
VStack {
HStack {
// ...
Text("xp: \(users.xp ?? 0)")
// Text("xp: 1500")
.fontWeight(.bold)
.padding(.horizontal)
.foregroundColor(Color.white)
.background(Color("Black"))
.clipShape(CustomCorner(corners: [.bottomLeft, .bottomRight, .topRight, .topLeft], size: 3))
.padding(.trailing)
}
.padding(.top)
.onAppear() {
self.users.fetchData()
}
// ...
}
}
我的结果在Text("xp: \(users.xp?? 0)")
中一直显示 0,这表示该步骤尚未异步。 那么我能做些什么来解决它呢?
在进一步调试之前,我会首先检查以确保 Firestore 控制台中的数据有效。 也就是说,如果您使用可观察对象,则可以取消完成处理程序,并且应该安全地解包数据。 错误总是可以通过网络调用发生,所以总是安全地解开遇到的任何东西。 此外,利用 Firestore API 中惯用的get()
方法,它使代码更易于阅读。
也就是说,问题在于您调用水平堆栈的onAppear
方法手动获取数据。 这种模式可能会在 SwiftUI 中产生令人讨厌的结果,因此只需删除在视图中手动获取数据的调用并在视图模型的初始化程序中自动执行它。
class UserViewModel: ObservableObject {
@Published var xp: Int?
init() {
guard let uid = Auth.auth().currentUser?.uid else {
return
}
let docRef = Firestore.firestore().collection("users").document(uid)
docRef.getDocument { (snapshot, error) in
if let doc = snapshot,
let xp = doc.get("xp") as? Int {
self.xp = xp
} else if let error = error {
print(error)
}
}
}
}
struct ContentView: View {
@ObservedObject var users = UserViewModel()
var body: some View {
VStack {
HStack {
Text("xp: \(users.xp ?? 0)")
}
}
}
}
SwiftUI 查看 - viewDidLoad()? 是你最终想要解决的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.