问题描述
我在网上发现了一些示例,这些示例在json文件中使用了硬编码的uuid,并且非常适合我,但是当我添加从我的应用程序中的json数组中删除项目的功能时,我需要动态创建这些uuid。
这是我的json文件(list.json),它以前具有像“ id”这样的硬编码ID:1并且可以工作(当我将int用作ID时)
[
{
"name": "Dune","author": "Frank Herbert","page": "77"
},{
"name": "Ready Player One","author": "Ernest Cline","page": "234"
},{
"name": "Murder on the Orient Express","author": "Agatha Christie","page": "133"
}
]
这是我的结构(Book.swift)
struct Book: Hashable,Codable,Identifiable {
var id = UUID()
var name: String
var author: String
var page: String
}
当我使用带有代码(Data.swift)的此结构解码json文件时...
let bookData: [Book] = load("list.json")
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename,withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self,from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
执行上一个致命错误是因为id密钥没有与之关联的值(因为我已将其从json文件中删除了)
如何使用ID初始化json文件,以便结构中的id = UUID()
语句可以为其分配唯一ID?
解决方法
在这种情况下,您必须指定CodingKeys
并省略id
struct Book: Hashable,Codable,Identifiable {
let id = UUID()
let name: String
let author: String
let page: String
private enum CodingKeys : String,CodingKey { case name,author,page }
}
显然,结构成员不会被修改,因此将它们声明为常量。
,(我想我在Reddit上看到了您的帖子。)
您可以为生成UUID的Book结构创建一个初始化。实际上,您可以为一个对象创建多个init,以请求不同的输入,或者为各种参数提供默认值,具体取决于您希望构造逻辑的运行方式。那可以很方便。
如果UUID是数据结构的重要组成部分,则应将其保留在CodableKeys中。
您可能要考虑运行时生成的UUID是否将按您的意愿真正地使对象唯一。您是否想要多个共享相同标题和作者的对象?用户可能会忘记他们添加了一本特定的书。您是要使用ISBN还是自己尝试独特的事情,例如检测重复的或接近重复的书名,并询问用户它们是否真的意味着要翻一本同一本书?
,好的,这是我的解决方案。现在,当我使用带有变量= UUID()。uuidstring的Encodable函数时,将填充它们,而不是现在动态填充id字段。因此,我的示例将使用硬编码的ID,但是当人们将自己的图书添加到我的应用时,我的应用将生成ID。这是一个简单的解决方案,但作为一个初学者,我不知道要寻找什么。