I want to set the variable "isfavorite" mapped to "id" as UserDefaults. I am able to save the whole of the struct encoded as JSON to UserDefaults. And then decode the UserDefaults JSON on init. There are two problems with this approach
1) I am using UserDefault to store a JSON file that could get bigger over time which is not the ideal usecase for UserDefaults
2) I am not able to update the content as during initialization, the last saved JSON on UserDefaults is loading
struct Labvalueslist: Codable, Identifiable, Equatable {
var topic: String
var sirange: String
var usrange: String
var id: Int
var isfavorite: Bool }
var labvaluesdata: [Labvalueslist] = load("labvalues.json")
final class UserData: ObservableObject {
@Published var labvaluesUserdata = labvaluesdata
{
didSet {
let encoder = JSONEncoder()
if let encoded = try?
encoder.encode(labvaluesUserdata) {
UserDefaults.standard.set(encoded, forKey: "isfavorite")
}
}
}
init () {
if let labvaluesUserdata = UserDefaults.standard.data(forKey: "labvaluesUserdata")
{
let decoder = JSONDecoder()
if let decoded = try?
decoder.decode([Labvalueslist].self, from: labvaluesUserdata) {
self.labvaluesUserdata = decoded
return
}
}
self.labvaluesUserdata = labvaluesdata
}
}
struct ImageView: View {
var list: Labvalueslist
@ObservedObject var userData = UserData()
var anatomyfavIndex: Int {
userData.labvaluesUserdata.firstIndex(where: { $0.id == list.id})!
}
// This is where I am confused; how do I get the "isfavorite" mapped to "id" and store it as UserDefaults and use only those values on init
var body: some View {
VStack {
ScrollView {
VStack(alignment: .leading)
{
Text("Normal Range:").font(.headline)
HStack
{ Text("SI: " + list.sirange)
Spacer()
Text("US: " + list.usrange)
}
.padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))
}
}.foregroundColor(.black)
}.navigationBarTitle(Text(list.topic), displayMode: .inline)
.padding(EdgeInsets(top: 10, leading: 10, bottom: 0, trailing: 5))
.navigationBarItems(trailing: Button(action: {
self.userData.labvaluesUserdata[self.anatomyfavIndex].isfavorite.toggle()
}) {
if self.userData.labvaluesUserdata[self.anatomyfavIndex].isfavorite {
Image(systemName: "star.fill").foregroundColor(.yellow).scaleEffect(1.5).padding (.trailing, 20)
}
else {
Image(systemName: "star")
.foregroundColor(.yellow)
.scaleEffect(1.5)
.padding (.trailing, 20)
}
})
}
}