【问题标题】:Parsing an array using Decodable [closed]使用 Decodable 解析数组 [关闭]
【发布时间】:2018-02-14 20:11:40
【问题描述】:

这是我正在尝试解析并想了解容器概念的 JSON。

 {
"results": [
{
  "type": "TEST",
  "date": 1518633000000,
  "slots": [
    {
      "startDatetime": 1518665400000,
      "endDatetime": 1518667200000,
    },
    {
      "startDatetime": 1518667200000,
      "endDatetime": 1518669000000,
    }
  ]
}
]
}

这是我正在尝试使用我的代码。我还为slots 制作了一个确认可解码协议的结构。我在解析Expected to decode Dictionary<String, Any> but found an array instead 时遇到此错误。请给我使用覆盖可解码协议的解决方案。 当解码器尝试解码结果时,此行发生错误。

struct Slots: Codable
{
var startDateTime: UInt64?
var endDateTime: UInt64?
}

struct Results:Codable {
var type:String?
var date:UInt64?
var slots:[Slots]?

private enum CodingKeys:String, CodingKey
{
    case type
    case date
    case slots
}

private enum ResultsKey: String, CodingKey
{
    case results
}

public init(from decoder:Decoder) throws
{
   let values = try decoder.container(keyedBy: ResultsKey.self)
    let resultsValues = try values.nestedContainer(keyedBy: CodingKeys.self, forKey: .results)
    type = try resultsValues.decode(String.self, forKey: .type)
    date = try resultsValues.decode(UInt64.self, forKey: .date)
    slots = try resultsValues.decode([Slots].self, forKey: .slots)
}
}

 if let data = response.data {
            // init the decoder here
            let decoder = JSONDecoder()

            // Error occurs here
            let results = try! decoder.decode(Results.self, from: data)
        }

【问题讨论】:

  • 错误出现在哪一行?另外,什么是插槽?提供其他人复制所需的一切。
  • 为了更好的可读性省略了一些键并添加了错误行,请检查。

标签: ios json swift4 decodable


【解决方案1】:

这是典型的错误。您忘记了根(最外层)对象,即键为 results 的字典。

您不需要任何编码密钥或初始化程序,您可以通过添加一行将时间戳直接解码为Date

struct Root : Decodable {
    let results : [Result]
}

struct Result : Decodable {
    let type : String
    let date : Date
    let slots: [Slot]
}

struct Slot : Decodable {
    let startDatetime, endDatetime : Date
}

假设dataData格式的JSON字符串

do {
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .millisecondsSince1970
    let result = try decoder.decode(Root.self, from: data)
    print(result)
} catch { print(error) }

并且不要将每个属性示意性地、粗心地声明为可选

【讨论】:

  • 我正在关注本教程并尝试理解容器概念,因为我的案例结果是容器的关键。如果我真的想使用编码键,我该怎么做?你的一句话就能解开我的困惑。
  • 我只需要声明那个属性是可选的,响应中可能没有它,对吧?
  • 错误信息很清楚。 results 的值是一个数组,所以实际上你需要 nestedUnkeyedContainer。但这不是学习/做到这一点的好例子。是的,如果键可能丢失,则声明 only 选项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-27
相关资源
最近更新 更多