Reputation: 51
I am learning SwiftUI and I am trying to retrieve information after retrieving data from my database with Firebase.
I retrieve the data once to display it in a summary way then with a Link Navigation I try to retrieve the rest of the information for a more accurate display but I have an error. I want to retrieve accurate data without using 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()
}
}
Print summary data
//
// 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)
}
}
}
}
This may be a silly question but I don't really understand how to get only the phone number for example in the PrintSpecificData.swift
Thank you for your precious help
Upvotes: 0
Views: 241
Reputation: 52397
Instead of recreating your view model on the detail view, you can instead pass just a single instance of delivResnum
as a parameter. You'll have to change the structure of your ContentView
slightly so that it has a different NavigationLink for each row, rather than wrapping the entire list.
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)
}
}
Note: in Swift, it's common practice to capitalize type names. You'd want to rename to DelivResum
and DelivViewModel
if you were to follow this convention.
Upvotes: 1