【发布时间】:2021-09-16 10:15:16
【问题描述】:
如何在我的 ViewModel 中使用 @AppStorage 来保存一组自定义类型?如何将@AppStorage 与@Published 属性一起使用?
这是我的示例代码:
型号
struct MyModel: Hashable, Codable {
var text: String
var number: Int
}
查看模型
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)
}
}
}
查看
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()
}
}
}
待办事项: 在 AppStorage / UserDefauls 中存储列表“其他一些设置”的检查设置。
【问题讨论】:
-
在存储到 AppStorage 之前将您的自定义类型编码为字符串或数据(NSUserDefaults 支持的类型)并在加载时解码。
-
This question 向您展示如何订阅和here is 一种编码选项
标签: swift mvvm swiftui userdefaults appstorage