簡體   English   中英

視圖中的 Firestore 方法 model 未在 SwiftUI onAppear 方法中調用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM