SwiftUI:如何在第二个视图中从 Firestore 检索数据?
SwiftUI: How to retrieve data from Firestore in second view?
这是我的第一个 SwiftUI 项目,对编程非常陌生。
我有一个视图模型和一个用于我的内容视图的选择器,设法将 $selection 发送到详细信息视图,但不确定如何让它再次从 Firestore 读取。我有点觉得缺少某些东西,就像我需要使用 if-else,但无法准确指出问题所在。在此处的论坛中搜索但似乎找不到解决方案。
这是虚拟机
import Foundation
import Firebase
class FoodViewModel: ObservableObject {
@Published var datas = [Food]()
private var db = Firestore.firestore()
func fetchData(){
db.collection("meals").addSnapshotListener { (snap, err) in
DispatchQueue.main.async {
if err != nil {
print((err?.localizedDescription)!)
return
} else {
for i in snap!.documentChanges{
let id = i.document.documentID
let name = i.document.get("name") as? String ?? ""
let weight = i.document.get("weight") as? Int ?? 0
let temp = i.document.get("temp") as? Int ?? 0
let time = i.document.get("time") as? Int ?? 0
self.datas.append(Food(id: id, name: name, weight: weight, temp: temp, time: time))
}
}
}
}
}
}
struct ContentView: View {
@ObservedObject var foodDatas = FoodViewModel()
@State private var id = ""
@State public var selection: Int = 0
var body: some View {
NavigationView{
let allFood = self.foodDatas.datas
ZStack {
Color("brandBlue")
.edgesIgnoringSafeArea(.all)
VStack {
Picker(selection: $selection, label: Text("Select your food")) {
ForEach(allFood.indices, id:\.self) { index in
Text(allFood[index].name.capitalized).tag(index)
}
}
.onAppear() {
self.foodDatas.fetchData()
}
Spacer()
NavigationLink(
destination: DetailView(selection: self.$selection),
label: {
Text("Let's make this!")
.font(.system(size: 20))
.fontWeight(.bold)
.foregroundColor(Color.black)
.padding(12)
})
}
而且在拣货员选择了一个食物类型之后,我希望它能显示其余的细节,比如烹饪时间和温度。现在文本部分显示 'index out of range'。
import SwiftUI
import Firebase
struct DetailView: View {
@ObservedObject var foodDatas = FoodViewModel()
@Binding var selection: Int
var body: some View {
NavigationView{
let allFood = self.foodDatas.datas
ZStack {
Color("brandBlue")
.edgesIgnoringSafeArea(.all)
VStack {
Text("Cooking Time: \(allFood[selection].time) mins")
}
}
}
}
感谢我能得到的所有帮助。
在您的 DetailView
中,您正在创建 FoodViewModel
的新实例:
@ObservedObject var foodDatas = FoodViewModel()
那个新实例没有获取任何数据,因此选择的索引越界,因为它的数组是空的。
您可以将原始 ContentView
的 FoodDataModel
副本作为参数传递。
因此,我引用的上一行将变为:
@ObservedObject var foodDatas : FoodViewModel
然后您的 NavigationLink
将如下所示:
NavigationLink(destination: DetailView(foodDatas: foodDatas, selection: self.$selection) //... etc
这是我的第一个 SwiftUI 项目,对编程非常陌生。
我有一个视图模型和一个用于我的内容视图的选择器,设法将 $selection 发送到详细信息视图,但不确定如何让它再次从 Firestore 读取。我有点觉得缺少某些东西,就像我需要使用 if-else,但无法准确指出问题所在。在此处的论坛中搜索但似乎找不到解决方案。
这是虚拟机
import Foundation
import Firebase
class FoodViewModel: ObservableObject {
@Published var datas = [Food]()
private var db = Firestore.firestore()
func fetchData(){
db.collection("meals").addSnapshotListener { (snap, err) in
DispatchQueue.main.async {
if err != nil {
print((err?.localizedDescription)!)
return
} else {
for i in snap!.documentChanges{
let id = i.document.documentID
let name = i.document.get("name") as? String ?? ""
let weight = i.document.get("weight") as? Int ?? 0
let temp = i.document.get("temp") as? Int ?? 0
let time = i.document.get("time") as? Int ?? 0
self.datas.append(Food(id: id, name: name, weight: weight, temp: temp, time: time))
}
}
}
}
}
}
struct ContentView: View {
@ObservedObject var foodDatas = FoodViewModel()
@State private var id = ""
@State public var selection: Int = 0
var body: some View {
NavigationView{
let allFood = self.foodDatas.datas
ZStack {
Color("brandBlue")
.edgesIgnoringSafeArea(.all)
VStack {
Picker(selection: $selection, label: Text("Select your food")) {
ForEach(allFood.indices, id:\.self) { index in
Text(allFood[index].name.capitalized).tag(index)
}
}
.onAppear() {
self.foodDatas.fetchData()
}
Spacer()
NavigationLink(
destination: DetailView(selection: self.$selection),
label: {
Text("Let's make this!")
.font(.system(size: 20))
.fontWeight(.bold)
.foregroundColor(Color.black)
.padding(12)
})
}
而且在拣货员选择了一个食物类型之后,我希望它能显示其余的细节,比如烹饪时间和温度。现在文本部分显示 'index out of range'。
import SwiftUI
import Firebase
struct DetailView: View {
@ObservedObject var foodDatas = FoodViewModel()
@Binding var selection: Int
var body: some View {
NavigationView{
let allFood = self.foodDatas.datas
ZStack {
Color("brandBlue")
.edgesIgnoringSafeArea(.all)
VStack {
Text("Cooking Time: \(allFood[selection].time) mins")
}
}
}
}
感谢我能得到的所有帮助。
在您的 DetailView
中,您正在创建 FoodViewModel
的新实例:
@ObservedObject var foodDatas = FoodViewModel()
那个新实例没有获取任何数据,因此选择的索引越界,因为它的数组是空的。
您可以将原始 ContentView
的 FoodDataModel
副本作为参数传递。
因此,我引用的上一行将变为:
@ObservedObject var foodDatas : FoodViewModel
然后您的 NavigationLink
将如下所示:
NavigationLink(destination: DetailView(foodDatas: foodDatas, selection: self.$selection) //... etc