How can I use @AppStorage in my ViewModel to save an array of custom types? How do I use @AppStorage with an @Published property?
Here is my example code:
MODEL
struct MyModel: Hashable, Codable {
var text: String
var number: Int
}
VIEW MODEL
class ViewModel: ObservableObject {
@Published private(set) var myModels = [MyModel]()
@Published private(set) var subscribedMyModels = [MyModel]() // TODO: sync this with AppStorage
func fetchMyModels() {
myModels = [
MyModel(text: "Setting", number: 1),
MyModel(text: "Setting", number: 2),
MyModel(text: "Setting", number: 3),
MyModel(text: "Setting", number: 4),
MyModel(text: "Setting", number: 5),
MyModel(text: "Setting", number: 6),
MyModel(text: "Setting", number: 7),
MyModel(text: "Setting", number: 8)
]
}
func toggleSubscription(for myModel: MyModel) {
if subscribedMyModels.contains(myModel) {
subscribedMyModels.removeAll(where: { $0 == myModel } )
} else {
subscribedMyModels.append(myModel)
}
}
}
VIEW
struct ContentView: View {
@StateObject var viewModel = ViewModel()
@AppStorage(wrappedValue: false, "settings0") private var settings0
var body: some View {
List {
Section(header: Text("Some Settings")) {
Toggle(isOn: $settings0, label: {
Text("Setting 0")
})
}
Section(header: Text("Some other Settings")) {
ForEach(viewModel.myModels, id: \.self) { myModel in
Button(action: {
viewModel.toggleSubscription(for: myModel)
}, label: {
HStack {
HStack {
Text(myModel.text)
Text(String(myModel.number))
}
Spacer()
if viewModel.subscribedMyModels.contains(myModel) {
Image(systemName: "checkmark.circle.fill")
} else {
Image(systemName: "circle")
}
}
})
}
.foregroundColor(.black)
}
}
.listStyle(InsetGroupedListStyle())
.onAppear {
viewModel.fetchMyModels()
}
}
}
TODO: Store checked settings of list "some other settings" in AppStorage / UserDefauls.