Swift JSON解码器接受不同的 JSON 密钥
Swift JSONDecoder accepting different JSON keys
我一直在努力开发一个代码来将多个不同的 JSON 字符串解码成一个组合数据结构(struct)。
正如您在下面的代码中看到的,两个 JSON 字符串 correctInput
和 faultyInput
包含相同的值,但键具有不同的名称。
有没有办法将这些不同的字符串(2 个或更多)解码为一个通用的 Codable 结构?
谢谢!
import Foundation
struct Fruit: Codable, Equatable {
var apple: String
var banana: String
var pineapple: String
}
let correctInput = """
{
"apple": "Akane",
"banana": "Bria",
"pineapple": "Sarawak"
}
""".data(using: .utf8)!
let faultyInput = """
{
"appl": "Akane",
"nana": "Bria",
"pine": "Sarawak"
}
""".data(using: .utf8)!
let decoder = JSONDecoder()
let correctFruit = try? decoder.decode(Fruit.self, from: correctInput)
let faultyFruit = try? decoder.decode(Fruit.self, from: faultyInput)
print(correctFruit)
print(faultyFruit)
这是一个解决方案,我们有一个单独的结构用于带有内置映射函数的错误数据
struct FaultyFruit: Codable, Equatable {
var appl: String
var nana: String
var pine: String
func asFruit() -> Fruit {
Fruit(apple: appl, banana: nana, pineapple: pine)
}
}
然后我们这样解码
var fruit: Fruit?
do {
fruit = try? decoder.decode(Fruit.self, from: faultyInput)
if fruit == nil {
let faultyFruit = try decoder.decode(FaultyFruit.self, from: faultyInput)
fruit = faultyFruit.asFruit()
}
} catch {
print(error)
}
这是一个使用自定义 init(from:)
并尝试不同 keys/property 名称的解决方案。
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let values = try container.decode([String: String].self)
apple = values["apple"] ?? values["appl"] ?? values["a"] ?? ""
banana = values["banana"] ?? values["nana"] ?? ""
pineapple = values["pineapple"] ?? values["pine"] ?? ""
}
安静地将“”分配给 属性 可能不是正确的方法,因此您可以添加 nil 检查并在无法为 属性 解析任何值时抛出错误。
我一直在努力开发一个代码来将多个不同的 JSON 字符串解码成一个组合数据结构(struct)。
正如您在下面的代码中看到的,两个 JSON 字符串 correctInput
和 faultyInput
包含相同的值,但键具有不同的名称。
有没有办法将这些不同的字符串(2 个或更多)解码为一个通用的 Codable 结构?
谢谢!
import Foundation
struct Fruit: Codable, Equatable {
var apple: String
var banana: String
var pineapple: String
}
let correctInput = """
{
"apple": "Akane",
"banana": "Bria",
"pineapple": "Sarawak"
}
""".data(using: .utf8)!
let faultyInput = """
{
"appl": "Akane",
"nana": "Bria",
"pine": "Sarawak"
}
""".data(using: .utf8)!
let decoder = JSONDecoder()
let correctFruit = try? decoder.decode(Fruit.self, from: correctInput)
let faultyFruit = try? decoder.decode(Fruit.self, from: faultyInput)
print(correctFruit)
print(faultyFruit)
这是一个解决方案,我们有一个单独的结构用于带有内置映射函数的错误数据
struct FaultyFruit: Codable, Equatable {
var appl: String
var nana: String
var pine: String
func asFruit() -> Fruit {
Fruit(apple: appl, banana: nana, pineapple: pine)
}
}
然后我们这样解码
var fruit: Fruit?
do {
fruit = try? decoder.decode(Fruit.self, from: faultyInput)
if fruit == nil {
let faultyFruit = try decoder.decode(FaultyFruit.self, from: faultyInput)
fruit = faultyFruit.asFruit()
}
} catch {
print(error)
}
这是一个使用自定义 init(from:)
并尝试不同 keys/property 名称的解决方案。
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let values = try container.decode([String: String].self)
apple = values["apple"] ?? values["appl"] ?? values["a"] ?? ""
banana = values["banana"] ?? values["nana"] ?? ""
pineapple = values["pineapple"] ?? values["pine"] ?? ""
}
安静地将“”分配给 属性 可能不是正确的方法,因此您可以添加 nil 检查并在无法为 属性 解析任何值时抛出错误。