【发布时间】:2018-01-25 12:29:13
【问题描述】:
我正在尝试使用 Swift 4 的新 JSON 解码来解析来自远程服务器的 JSON。 JSON 模式包括枚举值,其中一些我实际上并不需要用于我的目的,我想忽略它。此外,我还希望足够健壮,以便当 JSON 架构发生变化时,我仍然能够读取尽可能多的数据。
问题是,当我尝试解析包含枚举的任何内容的数组时,除非每个枚举值都与我的枚举的文字完全匹配,否则解码器会抛出异常,而不是跳过它无法解析的数据。
这是一个简单的例子:
enum Size: String, Codable {
case large = "large"
case small = "small"
}
enum Label: String, Codable {
case kitchen = "kitchen"
case bedroom = "bedroom"
case livingRoom = "living room"
}
struct Box: Codable {
var contents: String
var size: Size
var labels: [Label]
}
当我解析完全符合我的 Size 枚举的数据时,我得到了预期的结果:
let goodJson = """
[
{
"contents": "pillows",
"size": "large",
"labels": [
"bedroom"
]
},
{
"contents": "books",
"size": "small",
"labels": [
"bedroom",
"living room"
]
}
]
""".data(using: .utf8)!
let goodBoxes = try? JSONDecoder().decode([Box?].self, from: goodJson)
// returns [{{contents "pillows", large, [bedroom]}},{{contents "books", small, [bedroom, livingRoom]}}]
但是,如果有不符合枚举的内容,解码器会抛出异常,我什么也得不到。
let badJson = """
[
{
"contents": "pillows",
"size": "large",
"labels": [
"bedroom"
]
},
{
"contents": "books",
"size": "small",
"labels": [
"bedroom",
"living room",
"office"
]
},
{
"contents": "toys",
"size": "medium",
"labels": [
"bedroom"
]
}
]
""".data(using: .utf8)!
let badBoxes = try? JSONDecoder().decode([Box?].self, from: badJson) // returns nil
理想情况下,在这种情况下,我想取回尺寸符合“小”或“大”的 2 件物品,并且缠绕的第二件物品有 2 个有效标签,“卧室”和“客厅”。
如果我为 Box 实现自己的 init(from: decoder),我可以自己解码标签并丢弃任何不符合我的枚举的标签。但是,我无法弄清楚如何解码 [Box] 类型以忽略无效框,而无需实现自己的解码器并自己解析 JSON,这违背了使用 Codable 的目的。
有什么想法吗?
【问题讨论】:
-
我有一个类似的情况,我只想忽略无效的数组元素,不希望解析器在整个数组上失败。真的没有办法跳过无效元素,而不是完全“扔掉”数组并使整个解析失败吗? :-/