swift - SwiftUI 使用 'id' 属性为 @Published 属性添加 Codable 一致性
问题描述
我刚刚开始学习 SwiftUI。我哪里错了?我正在尝试在我的类(ManyItems)中添加 Codable 一致性。这样我最终可以使用 JSON 将数组保存到磁盘。两个错误:
1) 在 "required init(...) "id = try..." 和 encode func: "try container.encode..." 导致"'id' 在 Swift 中不可用:'id' 是在 Swift 中不可用;使用‘任何’”
2) 在所需的 init(...) 和 func 编码中:“使用未解析的标识符‘一’。” 我假设结构中的标识符将被带到类中?
struct Item: Identifiable {
var id = UUID()
var one: String
}
class ManyItems: ObservableObject, Codable {
@Published var manyitems = [Item]()
enum CodingKeys: CodingKey {
case id
case one
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(UUID.self, forKey: .id)
one = try container.decode(String.self, forKey: .one)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(one, forKey: .one)
}
}
解决方案
我找到了解决方案,但不得不采取稍微不同的路线。希望这可以帮助其他需要使用符合 Codable 和 ObservableObject 的集合来保存到 Apps 文档目录的人。
我将 struct 'Item' 符合 Codable(即不是类 'ManyItem')。我添加了用于 JSON 编码和将 Collection 保存到 Apps 文档目录的代码。当属性值更改时,这会自动发生。该类通过从 Apps 文档目录读取/解码 JSON 文件启动,或者如果 JSON 文件尚不可用,则作为新的空白实例启动。
struct Item: Identifiable, Codable {
var id = UUID()
var one: String
}
class ManyItems: ObservableObject {
@Published var manyitems: [Item] {
didSet {
// Saves the array 'items' to disc
do {
// find the documentDirectory and create an URL for the JSON
file
let filename = getDocumentsDirectory().appendingPathComponent("manyitems.json")
let data = try JSONEncoder().encode(self.manyitems)
try data.write(to: filename, options: [.atomicWrite])
} catch {
print("Unable to save data.")
}
}
}
init() {
// replaces a call to 'getDocumentsDirectory()' methode as it created an initialisation error.
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
// Add the first [0] path to the filename and create 'filename'
let filename = paths[0].appendingPathComponent("manyitems.json")
//print(filename)
do {
// Try to read the file (if it exist) and load the data into the array 'manyitem'
let data = try Data(contentsOf: filename)
manyitems = try JSONDecoder().decode([Item].self, from: data)
// Yes all good then exit
return
} catch {
// Something whent wrong. Initialize by creating an empty array 'manyitems'
self.manyitems = []
print("Unable to load saved data.")
}
}
// retreives the App's first DocumentDirectory
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
}
推荐阅读
- python - YOLOv4 中的损失波动
- security - cookie 加密密钥应该是唯一的吗?
- ios - 如何在 Xcode 中使用 Swift 从 Firebase 中的 Cloud Firestore 数据库访问数据?
- angular - 从文本(Angular)客户端生成pdf?
- sql-server - 有没有办法为我们本地 sql express 中的所有表和数据生成数据库脚本
- google-apps-script - 如何在 Google Sheet 中以文本形式获取值(不执行公式)?
- c# - Toast 在 Xamarin Forms 项目中不起作用
- android - Android glide:裁剪 - 从图像底部截断 X 像素
- django - Django Admin:如何自定义 autocomplete_fields 宽度以适应内容?
- java - Android - 从 sqlite 获取字符串数据并使用 if 条件更改列表视图输入