gpt4 book ai didi

json - Swift 4 JSON 解码器有什么办法不抛出包含无法识别的枚举值的数组吗?

转载 作者:行者123 更新时间:2023-12-04 14:00:55 28 4
gpt4 key购买 nike

我正在尝试使用 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 的目的。

有任何想法吗?

最佳答案

我承认这不是最漂亮的解决方案,但这是我想出的,我想我会分享。我在 Array 上创建了一个扩展,允许这样做。最大的缺点是您必须解码然后再次编码 JSON 数据。

extension Array where Element: Codable {
public static func decode(_ json: Data) throws -> [Element] {
let jsonDecoder = JSONDecoder()
var decodedElements: [Element] = []
if let jsonObject = (try? JSONSerialization.jsonObject(with: json, options: [])) as? Array<Any> {
for json in jsonObject {
if let data = try? JSONSerialization.data(withJSONObject: json, options: []), let element = (try? jsonDecoder.decode(Element.self, from: data)) {
decodedElements.append(element)
}
}
}
return decodedElements
}
}

您可以将此扩展用于任何符合 Codable 的内容。并且应该可以解决您的问题。
[Box].decode(json)

不幸的是,我不知道这将如何解决标签不正确的问题,您将不得不按照您说的去做并覆盖 init(from: Decoder)以确保您的标签有效。

关于json - Swift 4 JSON 解码器有什么办法不抛出包含无法识别的枚举值的数组吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45729205/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com