【问题标题】:SwiftUI and MVVM: How to display data from Firebase/Firestore in View?SwiftUI 和 MVVM:如何在视图中显示来自 Firebase/Firestore 的数据?
【发布时间】:2021-04-04 02:07:09
【问题描述】:

我正在从 Firebase 数据库中获取一些数据,并希望在视图中显示它们。提取部分到目前为止工作,但不显示数据。由于我是 MVVM 模式的新手,所以我有点困惑我的错误在哪里。我想我错过了关于异步调用的一些内容,但我不确定。

为了获取数据,我创建了一个 FirestoreManager

class FirebaseManager {
private let db = Firestore.firestore()

func getUploadedDecks() -> [FlashcardDeck]{
    var uploadedDecks = [FlashcardDeck]()
    
    db.collection(K.FSCollectionName).getDocuments { (querySnapshot, error) in
        guard let documents = querySnapshot?.documents else {
            fatalError("error downloading documents")
        }
        
        for document in documents{
            if let deck = try? document.data(as: FlashcardDeck.self) {
                uploadedDecks.append(deck)
                print(deck.title) // <----- prints the ID correctly
            }
        }
    }
    return uploadedDecks
}

视图模型:

class DownloadViewModel: ObservableObject {

@Published var decks = [FlashcardDeck]()
@Published var show = false

func fetchDecks(){
    self.decks = FirebaseManager().getUploadedDecks()
}

}

查看:这里只显示“正在加载...”文本字段。

struct DownloadDecksView: View {
@ObservedObject var viewModel: DownloadViewModel

var body: some View {
    VStack{
        if viewModel.decks == [] {
            Text("loading...")
        } else { 
            ForEach(viewModel.decks) { elem in 
                Flashcard(elem)
        }
    }
    .onAppear {
        viewModel.fetchDecks()
    }
}

    

主视图:

struct HomeView: View {
    @StateObject var downloadViewModel = DownloadViewModel()
    ...

    var body: some View {
        DownloadDecksView(viewModel: downloadViewModel)
        ...
    }
}

【问题讨论】:

    标签: firebase mvvm google-cloud-firestore swiftui


    【解决方案1】:

    这都是关于异步检索的,所以你需要在回调中返回结果,比如

    class FirebaseManager {
    private let db = Firestore.firestore()
    
    func getUploadedDecks(completion: @escaping ([FlashcardDeck]) -> ()) {
        
        db.collection(K.FSCollectionName).getDocuments { (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else {
                fatalError("error downloading documents")
            }
            
           var uploadedDecks = [FlashcardDeck]()
            for document in documents{
                if let deck = try? document.data(as: FlashcardDeck.self) {
                    uploadedDecks.append(deck)
                }
            }
            completion(uploadedDecks)       // << here !!
        }
        // no return !!
    }
    

    并将其用作

    class DownloadViewModel: ObservableObject {
    
    @Published var decks = [FlashcardDeck]()
    @Published var show = false
    
      func fetchDecks(){
        FirebaseManager().getUploadedDecks() { [weak self] decks in
           DispatchQueue.main.async {
              // always update UI-linked properties on main queue
              self?.decks = decks
           }
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-26
      • 1970-01-01
      • 2019-11-01
      • 2021-08-02
      • 2021-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-05
      相关资源
      最近更新 更多