Google cloud firestore 存储从选择器中选择的值以在其他视图中使用-SwiftUI

Google cloud firestore 存储从选择器中选择的值以在其他视图中使用-SwiftUI,google-cloud-firestore,swiftui,picker,Google Cloud Firestore,Swiftui,Picker,我得到了非常友好的帮助,允许我的选择器从我的Firestore数据库中选择一个值。我想做的是,一旦在我的选择器中选择了该值,我希望能够在其他视图中显示该值。我已经尝试过使用UserDefaults来设置它,但我不确定这是一种方法吗?如果你能建议一个更好的方法,我将不胜感激。我目前的代码如下 下面代码中的值每次都返回Unknown School,但没有用户默认值,它在获取数据时工作正常 提前谢谢 import SwiftUI import Firebase struct SchoolDetail

我得到了非常友好的帮助,允许我的选择器从我的Firestore数据库中选择一个值。我想做的是,一旦在我的选择器中选择了该值,我希望能够在其他视图中显示该值。我已经尝试过使用UserDefaults来设置它,但我不确定这是一种方法吗?如果你能建议一个更好的方法,我将不胜感激。我目前的代码如下

下面代码中的值每次都返回Unknown School,但没有用户默认值,它在获取数据时工作正常

提前谢谢

import SwiftUI
import Firebase

struct SchoolDetailsView: View {
    @ObservedObject var schoolData = getSchoolData()
    @State private var selectedSchool = UserDefaults.standard.string(forKey: "") // `schoolName.id` is of type String

    var body: some View {
        VStack {
                Form {
                    Section {
                        Picker(selection: $selectedSchool, label: Text("School Name")) {
                            ForEach(schoolData.datas, id: \.id) {
                                Text($0.name)
                            }
                        }
                        Text("Selected School: \(selectedSchool ?? "Unknown School")")
                    }
                }.navigationBarTitle("School Selection")
            }
        }

struct SchoolPicker_Previews: PreviewProvider {
    static var previews: some View {
        SchoolDetailsView()
    }
}

class getSchoolData : ObservableObject{
    
    @Published var datas = [schoolName]()
    
    init() {
        
        let db = Firestore.firestore()
        
        db.collection("School Name").addSnapshotListener { (snap, err) in
            
            if err != nil{
                
                print((err?.localizedDescription)!)
                return
            }
            
            for i in snap!.documentChanges{
                
                let id = i.document.documentID
                let name = i.document.get("Name") as! String
                
                self.datas.append(schoolName(id: id, name: name))
            }
        }
    }
}

struct schoolName : Identifiable {
    
    var id : String
    var name : String
}
}

首先,变量的UserDefaults键不能为空:

@State private var selectedSchool: String = UserDefaults.standard.string(forKey: "selectedSchool") ?? "Unknown School"
然后可以使用onReceive更新变量:

.onReceive(Just(selectedSchool)) {
    UserDefaults.standard.set($0, forKey: "selectedSchool")
}
完整代码:

import Combine
import Firebase
import SwiftUI

struct SchoolDetailsView: View {
    @ObservedObject var schoolData = getSchoolData()
    @State private var selectedSchool = UserDefaults.standard.string(forKey: "selectedSchool")

    var body: some View {
        VStack {
            Form {
                Section {
                    Picker(selection: $selectedSchool, label: Text("School Name")) {
                        ForEach(schoolData.datas, id: \.id) {
                            Text($0.name)
                        }
                    }
                    .onReceive(Just(selectedSchool)) {
                        UserDefaults.standard.set($0, forKey: "selectedSchool")
                    }
                    Text("Selected School: \(selectedSchool)")
                }
            }.navigationBarTitle("School Selection")
        }
    }
}

请注意,在SwiftUI 2/iOS 14中,您可以改用它。

首先,变量的UserDefaults键不能为空:

@State private var selectedSchool: String = UserDefaults.standard.string(forKey: "selectedSchool") ?? "Unknown School"
然后可以使用onReceive更新变量:

.onReceive(Just(selectedSchool)) {
    UserDefaults.standard.set($0, forKey: "selectedSchool")
}
完整代码:

import Combine
import Firebase
import SwiftUI

struct SchoolDetailsView: View {
    @ObservedObject var schoolData = getSchoolData()
    @State private var selectedSchool = UserDefaults.standard.string(forKey: "selectedSchool")

    var body: some View {
        VStack {
            Form {
                Section {
                    Picker(selection: $selectedSchool, label: Text("School Name")) {
                        ForEach(schoolData.datas, id: \.id) {
                            Text($0.name)
                        }
                    }
                    .onReceive(Just(selectedSchool)) {
                        UserDefaults.standard.set($0, forKey: "selectedSchool")
                    }
                    Text("Selected School: \(selectedSchool)")
                }
            }.navigationBarTitle("School Selection")
        }
    }
}

请注意,在SwiftUI 2/iOS 14中,您可以改为使用。

Hi Pawello,一如既往地感谢您的更新。我试过了,很高兴我的思路是正确的。我曾经试着不用空钥匙就可以使用它,但它似乎不起作用,但现在我明白了原因,谢谢。尽管代码编译正确。它似乎不再让我选择学校了。所选学校将不会从零更改为未知School@LMA是,所选学校也必须是字符串类型,就像schoolName.id一样。我更新了我的答案。嗨,帕韦洛,一如既往地感谢你的更新。我试过了,很高兴我的思路是正确的。我曾经试着不用空钥匙就可以使用它,但它似乎不起作用,但现在我明白了原因,谢谢。尽管代码编译正确。它似乎不再让我选择学校了。所选学校将不会从零更改为未知School@LMA是,所选学校也必须是字符串类型,就像schoolName.id一样。我更新了我的答案。