我对 SwiftUI 相当陌生,想使用 @AppStorage 属性包装器以数组的形式保存自定义类对象的列表。我在这里找到了几篇文章,它们帮助我创建了以下通用扩展,并将其添加到我的 AppDelegate 中:
extension Published where Value: Codable {
init(wrappedValue defaultValue: Value, _ key: String, store: UserDefaults? = nil) {
let _store: UserDefaults = store ?? .standard
if
let data = _store.data(forKey: key),
let value = try? JSONDecoder().decode(Value.self, from: data) {
self.init(initialValue: value)
} else {
self.init(initialValue: defaultValue)
}
projectedValue
.sink { newValue in
let data = try? JSONEncoder().encode(newValue)
_store.set(data, forKey: key)
}
.store(in: &cancellableSet)
}
}
这是我代表对象的类:
class Card: ObservableObject, Identifiable, Codable{
let id : Int
let name : String
let description : String
let legality : [String]
let imageURL : String
let price : String
required init(from decoder: Decoder) throws{
let container = try decoder.container(keyedBy: CardKeys.self)
id = try container.decode(Int.self, forKey: .id)
name = try container.decode(String.self, forKey: .name)
description = try container.decode(String.self, forKey: .description)
legality = try container.decode([String].self, forKey: .legality)
imageURL = try container.decode(String.self, forKey: .imageURL)
price = try container.decode(String.self, forKey: .price)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CardKeys.self)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
try container.encode(description, forKey: .description)
try container.encode(imageURL, forKey: .imageURL)
try container.encode(price, forKey: .price)
}
init(id: Int, name: String, description: String, legality: [String], imageURL: String, price : String) {
self.id = id
self.name = name
self.description = description
self.legality = legality
self.imageURL = imageURL
self.price = price
}
}
enum CardKeys: CodingKey{
case id
case name
case description
case legality
case imageURL
case price
}
我正在使用一个视图模型类,它声明数组如下:
@Published(wrappedValue: [], "saved_cards") var savedCards: [Card]
该类的其余部分仅包含将卡片附加到数组的函数,因此我认为没有必要在此处突出显示它们。
我的问题是,在应用程序运行期间,一切似乎都运行良好 - 卡片出现并且在数组中可见但是当我尝试关闭我的应用程序并再次重新打开它时,数组是空的,并且数据似乎没有持久化. 看起来 JSONEncoder/Decoder 无法序列化/反序列化我的类,但我不明白为什么。
我真的很感激建议,因为我似乎没有找到解决这个问题的方法。我也在使用与常规 Int 数组相同的方法,它完美地工作,所以我的自定义类似乎存在问题。