SwiftUI, как получить данные Firebase из @ObservedObject ViewModel без использования списка

# #ios #swift #database #firebase #swiftui

Вопрос:

Я изучаю SwiftUI и пытаюсь получить информацию после извлечения данных из моей базы данных с помощью Firebase.

Я извлекаю данные один раз, чтобы отобразить их в кратком виде, затем с помощью навигации по ссылкам я пытаюсь получить остальную информацию для более точного отображения, но у меня ошибка. Я хочу получать точные данные без использования списка.

Данные для печати.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 немного изменить структуру вашего списка, чтобы для каждой строки в нем была своя навигационная ссылка, а не весь список.

 
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 общепринятой практикой является заглавная буква имен типов. Вы бы хотели переименовать в DelivResum и DelivViewModel , если бы вы следовали этому соглашению.