I have a built up List with using an array of Codable type called Package. At some point, I need to update the isFavorite value of an Package item when user taps favorite button in the list. However I am getting the error of Cannot use mutating member on immutable value: 'package' is a 'let' constant. First I tried to directly change the value in the action. It did not work, so the point I got so far is below.
Obviously the code is longer than that but I just wanted make it simple and deleted irrelevant parts.
SwiftUIView
struct AView: View {
@ObservedObject var store: JSONController
var body: some View {
NavigationView {
List(self.store.packages) { (package) in
return self.row(package)
}
}
}
private func row(_ package: Package) -> some View {
HStack{
Text(package.name)
Spacer()
Button(action: {
package.changeFavoriteState()
}) {
Image(systemName: package.isFavorite ? "star.fill" : "star")
}.buttonStyle(PlainButtonStyle())
}
}
}
Package.struct
struct Package: Codable, Identifiable {
var id: UUID
var isFavorite: Bool
mutating func changeFavoriteState() {
self.isFavorite.toggle()
}
}
PackageList.struct
struct PackageList: Codable {
var packages: [Package]
private enum CodingKeys: CodingKey {
case packages
}
init(){
self.packages = [Package]()
}
init(from decoder: Decoder) throws {
do {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.packages = try container.decode([Package].self, forKey: .packages)
}catch let error {
print(error.localizedDescription+" Initializing packages with an empty array.")
self.packages = [Package]()
}
}
}
JSONController.class
class JSONController: ObservableObject {
@Published var packages: [Package] = [Package]()
init(){
self.readJSONFile(from: "packageList")
}
func readJSONFile(from url: String) {
//stuff
}
}
And finally the error I got,

it is simple, you need access the value, not its copy, provided by List
or using the ObservableObject
which is generally the same ... but in more complex scenarios preferable
UPDATE based on request You have to redefine row function
Or the second option
UPDATE with conditional sorting