接受不同JSON键的Swift JSONDecoder。

问题描述 投票:0回答:1

我一直在努力开发一个代码,将多个不同的JSON字符串解码成一个组合的数据结构(struct)。

正如你在下面的代码中所看到的,两个JSON字符串是 correctInputfaultyInput有什么办法可以将这样不同的字符串(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)
json swift codable decodable jsondecoder
1个回答
0
投票

这里有一个解决方案,我们有一个单独的结构来处理有问题的数据,并有一个内置的映射函数。

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:) 并尝试使用不同的keysproty名称。

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的检查,如果一个属性没有值可以被解析,就抛出一个错误。

© www.soinside.com 2019 - 2024. All rights reserved.