【发布时间】:2019-11-11 15:39:24
【问题描述】:
让我们假设这个表示多语言单词的 json:
[{
"id": "en_cat",
"name": "cat",
"def": "A cat is a domestic animal of the feline family.",
"trans": {
"fr": "fr_chat",
"ru": "ru_ко́шка"
}
}, {
"id": "fr_chat",
"name": "chat",
"def": "Le chat est un animal domestique de la famille des félins.",
"trans": {
"en": "en_cat",
"ru": "ru_ко́шка"
}
}, {
"id": "ru_ко́шка",
"name": "ко́шка",
"def": "..."
"trans": {
"en": "en_cat",
"fr": "fr_chat"
}
}]
这个json在“trans”(翻译)嵌套容器中有相互关联的项目。
我的课很直接
class Word: Decodable {
var id: String
var name: String
var definition: String
var enTranslation: Word?
var frTranslation: Word?
var ruTranslation: Word?
enum JsonCodingKey: String, CodingKey {
case id
case name
case def
case trans
}
enum JsonTransCodingKey: String, CodingKey {
case en
case fr
case ru
}
convenience init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: JsonCodingKey.self)
let id = try container.decode(String.self, forKey: .id)
let name = try container.decode(String.self, forKey: .name)
let definition = try container.decode(String.self, forKey: .def)
self.init(id: id, name: name, definition: definition)
// Tricky part here...
let transContainer = try container.nestedContainer(keyedBy: JsonTransCodingKey.self, forKey: .trans)
if let en = transContainer.decode(String.self, forKey: .en) {
self.enTranslation = realm.find(wordId: en) // Singleton that looks into memory for the word
}
// And repeat the same if logic for the other languages...
}
}
JSON 解码的最快 (CPU) 方式是什么?
我的处理方式“感觉”不对:
- 我使用解码字词
let jsonDecoder = JSONDecoder()
let words = jsonDecoder.decode([Word].self, from: data)
但是这些词没有任何翻译链接,因为它们在实时解析过程中不是“已知的”。
在我的示例中,当我们解析第一个单词“cat”时,我们仍然不知道法语或俄语单词。
- 所以我必须再次解码,一旦我记住了所有单词。
let jsonDecoder = JSONDecoder()
let words = jsonDecoder.decode([Word].self, from: data) // Words don't have their translations
self.saveInMemory(words) // In my case, it is saved to Realm.
let words = jsonDecoder.decode([Word].self, from: data)
/* Words are now linked to each others
Because during decoding, the func Word.init(from decoder) will
look into `Realm` and find the translations. */
这种双重解码感觉有点过头了。反正不直接搜索json数据吗?
【问题讨论】:
-
解码并不意味着生成你的最终数据结构。以对象的编码方式(“翻译”)解码对象,然后使用不同的对象将它们链接在一起。
-
JSON 表示数据树。您不能仅使用 JSON 来“链接”或引用任何内容。不过,您可以这样做 int YAML。但它仍然不能为你做所有事情。
标签: ios json swift jsondecoder