Hey in my app I am trying to store whether the User wants a location to be its favourite. In order to make the change in this UserDefaults update the view I need to use @AppStorage. However, at the moment I only get the ERROR "No exact matches in call to initializer" Do i need to use Data instead of the [String: String], if yes how? Does anyone know how to fix this? Thanks in advance
import SwiftUI
struct SpotDetailView: View {
@State var spot: WindApp //knows which spot it's at
var spotname:String
//@State var favourites: [String:String] = UserDefaults.standard.object(forKey: "heart") as? [String:String] ?? [:]
@AppStorage("heart") var favourites: [String: String] = [:]
var body: some View {
ZStack {
List {
SpotMapView(coordinate: spot.locationCoordinate)
.cornerRadius(8)
ForEach(0..<9) { i in
SingleDayView(spot: spot, counter: (i * 8))
}
}
.navigationTitle("(spot.spot)")
VStack {
Spacer()
HStack {
Spacer()
Button(action: {
if favourites[spot.spot] == "heart" {
favourites[spot.spot] = "heart.fill"
UserDefaults.standard.set(favourites, forKey: "heart")
}
else if favourites[spot.spot] == "heart.fill" {
favourites[spot.spot] = "heart"
UserDefaults.standard.set(favourites, forKey: "heart")
}
else {
favourites[spot.spot] = "heart.fill"
UserDefaults.standard.set(favourites, forKey: "heart")
}
}, label: {
Image(systemName: favourites[spot.spot] ?? "heart")
})
.frame(width: 20, height: 20)
}
}
}
}
}
3
Answers
You will have to use Data. @AppStorage currently only supports:
See this answer for sample implementation and further details
You can make Dictionary [String:String] conform to RawRepresentable.
I would recomend storing your [String: String] object as Data.
Since [String: String] conforms to Codable out of the box this is an easy task.
This is an example of how you could implement it and also get Combine support.
Notice that
MyUserDefaultsStorage
is not only for this value but you can add additional values you would like to store inAppStorage
.