SwiftUI 如何在不使用 List 的情况下从 @ObservedObject ViewModel 获取 Firebase 数据

Posted

技术标签:

【中文标题】SwiftUI 如何在不使用 List 的情况下从 @ObservedObject ViewModel 获取 Firebase 数据【英文标题】:SwiftUI how get Firebase data from @ObservedObject ViewModel without using List 【发布时间】:2021-03-21 16:02:13 【问题描述】:

我正在学习 SwiftUI,我正在尝试使用 Firebase 从我的数据库中检索数据后检索信息。

我检索数据一次以摘要方式显示它,然后使用链接导航我尝试检索其余信息以获得更准确的显示,但我有一个错误。 我想在不使用 List 的情况下检索准确的数据。

PrintSpecificData.swift

//
//  complete_deliv_view.swift
//  db_test
//
//  Created by admin on 21/03/2021.
//

import SwiftUI

struct complete_deliv_view: View 
    @ObservedObject private var viewModel = delivViewModel()
    var body: some View 
        Text(self.viewModel.av_deliveries.from) // ERROR IS HERE
        .onAppear() 
            self.viewModel.fetchDelivResume()
        
    


struct complete_deliv_view_Previews: PreviewProvider 
    static var previews: some View 
        complete_deliv_view()
    

打印汇总数据

//
//  ContentView.swift
//  db_test
//
//  Created by admin on 21/03/2021.
//

import SwiftUI

struct delivResum:Identifiable 
    // SUMMARY INFORMATIONS
    var id: String = UUID().uuidString
    var when: String
    var from: Int
    var to: Int
    var whath: Int
    // FULL INFORMATIONS
    var name: String
    var adress: String
    var to_adress: String
    var tel: Int


struct ContentView: View 
    @ObservedObject private var viewModel = delivViewModel()
    var body: some View 
        NavigationView 
            NavigationLink(destination:complete_deliv_view()) 
                List(viewModel.av_deliveries)  deliv in
                    HStack 
                        Text ("????")
                        Text(deliv.when)
                        Text ("????")
                        Text(String(deliv.from))
                        Text ("➡")
                        Text(String(deliv.to))
                        Text ("⏰")
                        Text("\(deliv.whath)h")
                    
                
                .navigationBarTitle("Livraisons")
                .onAppear() 
                    self.viewModel.fetchDelivResume()
                
            
        
        
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

FetchDataFromFirebase.swift

//
//  delivViewModel.swift
//  db_test
//
//  Created by admin on 21/03/2021.
//

import Foundation
import FirebaseFirestore

class delivViewModel : ObservableObject 
    @Published var av_deliveries = [delivResum]()
    
    private var db = Firestore.firestore()
    
    func fetchDelivResume() 
        db.collection("av_deliveries").addSnapshotListener  (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else 
                print("Pas de livraison disponible ????")
                return
            
            self.av_deliveries = documents.map  (QueryDocumentSnapshot) -> delivResum in
                let data = QueryDocumentSnapshot.data()

                let when = data["when"] as? String ?? ""
                let from = data["from"] as? Int ?? 0
                let to = data["to"] as? Int ?? 0
                let whath = data["whath"] as? Int ?? 0
                let name = data["name"] as? String ?? ""
                let adress = data["adress"] as? String ?? ""
                let to_adress = data["to_adress"] as? String ?? ""
                let tel = data["tel"] as? Int ?? 0
                
                return delivResum(when: when, from: from, to: to, whath: whath, name: name, adress: adress, to_adress: to_adress, tel: tel)
            
        
    

这可能是一个愚蠢的问题,但我真的不明白如何只获取电话号码,例如在 PrintSpecificData.swift 中

感谢您的宝贵帮助

【问题讨论】:

【参考方案1】:

您可以只传递delivResnum 的单个实例作为参数,而不是在详细视图上重新创建视图模型。您必须稍微更改 ContentView 的结构,以便每一行都有不同的 NavigationLink,而不是包装整个列表。


struct ContentView: View 
    @ObservedObject private var viewModel = delivViewModel()
    var body: some View 
        NavigationView 
            List(viewModel.av_deliveries)  deliv in
                NavigationLink(destination:complete_deliv_view(deliv: deliv)) 
                    HStack 
                        Text ("?")
                        Text(deliv.when)
                        Text ("?")
                        Text(String(deliv.from))
                        Text ("➡")
                        Text(String(deliv.to))
                        Text ("⏰")
                        Text("\(deliv.whath)h")
                    
                
            
            .navigationBarTitle("Livraisons")
            .onAppear() 
                self.viewModel.fetchDelivResume()
            
        
    


struct complete_deliv_view: View 
    var deliv : delivResum
    var body: some View 
        Text(deliv.from)
    



注意:在 Swift 中,通常将类型名称大写。如果要遵循此约定,您可能需要重命名为 DelivResumDelivViewModel

【讨论】:

以上是关于SwiftUI 如何在不使用 List 的情况下从 @ObservedObject ViewModel 获取 Firebase 数据的主要内容,如果未能解决你的问题,请参考以下文章

使用 CloudKit + CoreData,如何在没有 SwiftUI 的 @FetchRequest 的情况下从远程云更新中更新 UI?

如何在不使用表单的情况下从 jsp 调用 servlet

如何在不使用子进程的情况下从 python 自动化脚本中运行 python 'sdist' 命令?

如何在不使用 Xcode、iPhone 中的谷歌地图的情况下从地址获取纬度和经度

如何在不使用 foreach 循环的情况下从视图访问模型

如何在不使用提交的情况下从下拉列表中选择值