使用 SwiftUI 和 FireStore 更新文本

Updating Text Using SwiftUI and FireStore

我在我的应用程序中存储了一个名为月小时的值,用于跟踪一个人使用应用程序的时间并将其显示在一行文本中。文本如果是 Swift UI 中堆栈的一部分,但是一旦从中查询了信息,我就无法弄清楚如何更新文本 我已经尝试了很多方法来制作这个从结构到 类 再到使用 @State。

这只是我尝试过的最新方法,但没有用,如果有人能提供帮助,我们将不胜感激。

let db = Firestore.firestore()


class Month {
    var monthHours = "0"

    func getMonthHours() {
        db.addSnapshotListener(.  //Im removing the actual query part to keep that private but the print statement below confirms the query is not the issue. 
            { (docSnapShot, err) in
                if let e = err {
                    print("There was an error retrieving the monthly hours:\n\(e.localizedDescription)")
                } else {
                    let data = docSnapShot?.data()
                    if let h = data?[K.FStore.monthHoursField] as? Double {
                        self.monthHours = String(h.rounded())
                        print("These are the hours:\n\(self.monthHours)")
                    }
                }
        })
    }
    func getMonth() -> String {
            let date = Date()
            let formatter = DateFormatter()
            formatter.dateFormat = "MMMM yyyy"
            let result = formatter.string(from: date)
            return result
    }
    init() {
        getMonthHours()
    }
}

struct ChartView : View {
    @State private var month = Month()
    //Struct variables
    var body  : some View {
        ZStack {
            Color(UIColor(named: K.BrandColors.grey)!).edgesIgnoringSafeArea(.all)
            VStack {
                Text("HOURS THIS MONTH \(month.monthHours)")
                    .font(.system(size: 18))
                    .fontWeight(.heavy)
            }
        } 
} 

这概述了一种可能的方法。症结在于处理异步函数"getMonthHours"。您需要等到它完成提取后才能使用结果。

class Month {
    var monthHours = "0"

    // async fetch the month hours from Firestore, ... error handling todo
    static func getMonthHours(handler: @escaping (String) -> Void) {
        db.addSnapshotListener{ (docSnapShot, err) in
            if let e = err {
                print("There was an error retrieving the monthly hours:\n\(e.localizedDescription)")
                return handler("") // should return some error here .... todo
            } else {
                if let data = docSnapShot?.data(),
                    let h = data?[K.FStore.monthHoursField] as? Double {
                    // return the result
                    return handler(String(h.rounded()))
                } else {
                    return handler("") // should return some error here .... todo
                }
            }
        }
    }

    func getMonth() -> String {
        let date = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "MMMM yyyy"
        let result = formatter.string(from: date)
        return result
    }

    init() { }
}

struct ChartView : View {
@State private var monthHours = ""
var body  : some View {
    ZStack {
        Color(UIColor(named: K.BrandColors.grey)!).edgesIgnoringSafeArea(.all)
        VStack {
            Text("HOURS THIS MONTH \(monthHours)")
                .font(.system(size: 18))
                .fontWeight(.heavy)
        }
    }.onAppear(perform: loadData)
    }
}

func loadData() {
    // when the fetching is done it will update the view
    Month.getMonthHours() { hours in
        self.monthHours = hours
    }
}