繁体   English   中英

SwiftUI 和 MVVM:如何在 View 中显示来自 Firebase/Firestore 的数据?

[英]SwiftUI and MVVM: How to display data from Firebase/Firestore in View?

我正在从 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)
        ...
    }
}

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

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
       }
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM