首页 > 解决方案 > 如何使用 firebase/firestore 在 SwiftUI 中将数据加载到视图中

问题描述

我正在尝试使用 Firebase/Firestore 将数据加载到 SwiftUI 视图中。数据从数据库加载,但不会传递到视图中。

我知道它会加载,因为我会在加载后打印它。

我有一个 HomeView.Swift 文件如下:

import SwiftUI
import Firebase

struct HomeView: View {
    let data = GetIphonesData()
    var body: some View {
        NavigationView {
            if (data.data.count == 0) {
                Loader()
                .navigationBarTitle("Loading", displayMode: .inline)
            } else {
                List() {
                    Section(header: Text("iPhone")) {
                        ForEach(data.data , id: \.id) { iphone in
                            ProductNavigationLinkView(model: iphone)
                        }
                    }
                }.listStyle(GroupedListStyle())
                .navigationBarTitle("Home", displayMode: .inline)
            }
        }
    }
}

我有一个 GetIphoneData.Swift 类,如下所示:

import Foundation
import Firebase
import Combine

class GetIphonesData : ObservableObject {
    @Published var data = [Iphone]()

    init() {
        let db = Firestore.firestore()

        db.collection("iphones").addSnapshotListener { (snap, err) in
            if err != nil {
                print((err?.localizedDescription)!)
                return
            } else {
                print("no errors")
                for i in snap!.documentChanges {
                    let id = i.document.documentID
                    let name = i.document.get("name") as! String

                    self.data.append(Iphone(id: id,
                                            name: name))
                }
                print(self.data)
            }
        }
    }
}

标签: swiftdatabasefirebasegoogle-cloud-firestoreswiftui

解决方案


  1. SwiftUI 在主线程上更新其视图的内容。将 addSnapshotListener 的闭包内容包装到 Dispatch.main.async 中。
db.collection("iphones").addSnapshotListener { (snap, err) in
  DispatchQueue.main.async {
    if err != nil {
        print((err?.localizedDescription)!)
        return
    } else {
        print("no errors")
        for i in snap!.documentChanges {
            let id = i.document.documentID
            let name = i.document.get("name") as! String

            self.data.append(Iphone(id: id,
                                    name: name))
        }
        print(self.data)
    }
  }
}
  1. let data = GetIphonesData()也应该有@ObservedObject属性包装器:
struct HomeView: View {
    @ObservedObject var data = GetIphonesData()
    // ...
  1. 将此答案视为使用@ObservedObject和的参考@Published

推荐阅读