I was very kindly helped to allow my picker to select a value from my Firestore database. What I would like to do is once that value is selected in my picker I would like to be able to show that value in other views. I have tried setting this up using UserDefaults but I'm not sure that's the way to go? If you could suggest a better method I'd be more than grateful. My code currently is below.
The value in the below code returns Unknown School each time but without the user defaults works flawlessly in fetching the data.
Thanks in advance.
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
}
}
First, the UserDefaults key for your variable can't be empty:
@State private var selectedSchool: String = UserDefaults.standard.string(forKey: "selectedSchool") ?? "Unknown School"
Then you can use onReceive
to update the variable:
.onReceive(Just(selectedSchool)) {
UserDefaults.standard.set($0, forKey: "selectedSchool")
}
Full code:
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")
}
}
}
Note that in SwiftUI 2 / iOS 14 you can use @AppStorage instead.