我刚刚开始学习SwiftUI。我哪里出错了? 我正在尝试在我的课程(ManyItems)中添加可编码的一致性。这样,我最终可以使用JSON将数组保存到磁盘。 两个错误:
1)在“必需的init(...)“ id = try ...”和编码函数中:“ try container.encode ...”导致中的“ id”不可用Swift:'id'在Swift中不可用;使用“任何””
2)在必需的init(...)和func编码中:“使用未解析的标识符'one'。” 我假定该结构中的标识符将被结转到类中?
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)
}
}
答案 0 :(得分:0)
您的Codable
模型应该是
struct Item: Codable, Identifiable {
var id = UUID()
var one: String
}
class ManyItems: Codable, ObservableObject {
@Published var manyitems = [Item]()
}
从代码中可以明显看出,您没有处理任何特定的解析案例。因此,无需显式实现init(from:)
和encode(to:)
方法。
答案 1 :(得分:0)
我找到了解决方案,但必须采取略有不同的方法。希望这可以帮助需要使用符合Codable和ObservableObject的Collection的其他人保存到Apps documentDirectory。
我使结构'Item'符合Codable(即不是类'ManyItem')。我为JSON编码添加了代码,并将集合保存到Apps documentDirectory。属性值更改时,这会自动发生。该类通过从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]
}
}