【问题标题】:Hot to decode JSON data that could and array or a single element in Swift?在 Swift 中解码可以和数组或单个元素的 JSON 数据很热门?
【发布时间】:2020-02-10 01:28:28
【问题描述】:

我有一个名为 Info 的结构,它根据接收到的数据进行解码。但有时,数据中的一个值可以是双精度数或双精度数组。我该如何设置我的结构?

struct Info: Decodable {
    let author: String
    let title: String
    let tags: [Tags]
    let price: [Double]
    enum Tags: String, Decodable {
        case nonfiction
        case biography
        case fiction
    }
}

根据网址,我要么得到双倍价格

{
    "author" : "Mark A",
    "title" : "The Great Deman",
    "tags" : [
      "nonfiction",
      "biography"
    ],
    "price" : "242"

}

或者我把它当作一个双精度数组

{
    "author" : "Mark A",
    "title" : "The Great Deman",
    "tags" : [
      "nonfiction",
      "biography"
    ],
    "price" : [
    "242",
    "299",
    "335"
    ]

}

我想设置我的结构,以便如果我收到一个双精度而不是双精度数组,价格应该被解码为一个 1 双精度数组。

【问题讨论】:

  • 你的意思是字符串或字符串数​​组检查重复项

标签: swift swift4 codable decodable


【解决方案1】:

您的 JSON 实际上是一个字符串或字符串数​​组。所以你需要创建一个自定义解码器来解码,然后将它们转换为Double:

struct Info {
    let author, title: String
    let tags: [Tags]
    let price: [Double]
    enum Tags: String, Codable {
        case nonfiction, biography, fiction
    }
}

extension Info: Codable {
    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        author = try container.decode(String.self, forKey: .author)
        title  = try container.decode(String.self, forKey: .title)
        tags = try container.decode([Tags].self, forKey: .tags)
        do {
            price = try [Double(container.decode(String.self, forKey: .price)) ?? .zero]
        } catch {
            price = try container.decode([String].self, forKey: .price).compactMap(Double.init)
        }
    }
}

游乐场测试

let infoData = Data("""
{
    "author" : "Mark A",
    "title" : "The Great Deman",
    "tags" : [
      "nonfiction",
      "biography"
    ],
    "price" : "242"

}
""".utf8)
do {
    let info = try JSONDecoder().decode(Info.self, from: infoData)
    print("price",info.price)  // "price [242.0]\n"
} catch {
    print(error)
}

let infoData2 = Data("""
{
    "author" : "Mark A",
    "title" : "The Great Deman",
    "tags" : [
      "nonfiction",
      "biography"
    ],
    "price" : [
    "242",
    "299",
    "335"
    ]

}
""".utf8)

do {
    let info = try JSONDecoder().decode(Info.self, from: infoData2)
    print("price",info.price)  // "price [242.0, 299.0, 335.0]\n"
} catch {
    print(error)
}

【讨论】:

  • 哇。非常感谢狮子座。解决方案奏效了。非常感谢。
  • 完美解决方案。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多