【问题标题】:Parsing JSON Swift 4解析 JSON Swift 4
【发布时间】:2018-09-24 23:19:03
【问题描述】:

这是我试图从 Strava API 解析的 JSON:

{
"firstname": "Evan",
"lastname": "Arthur",
"city": "",
"state": "",
"country": "",
"sex": "M",
"measurement_preference": "feet",
"ftp": 285,
"bikes": [
    {
        "id": "b4770368",
        "primary": true,
        "name": "Felt Disc",
        "resource_state": 2,
        "distance": 2528687
    }
]
}

我正在尝试访问一些条目并从中创建一个对象。这是我的运动员课:

import Foundation

struct athlete: Codable{
    let firstName: String
    let lastName: String
    let sex: String
    let measurement: String

    enum CodingKeys: String, CodingKey {
         case firstName = "firstname"
         case lastName = "lastname"
         case sex = "sex"
         case measurement = "measurement_preference"
         case bikes = "bikes"
    }

    struct Bike: Codable {
         let name: String
         let distance: String
     //  enum CodingKeys: String, CodingKey{
     //     case name = "name"
     //     case distance = "distance"
     //  }
    }

    let bikes: [Bike]

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.firstName = try container.decode(String.self, forKey:      .firstName)
        self.lastName = try container.decode(String.self, forKey: .lastName)
        self.sex = try container.decode(String.self, forKey: .sex)
        self.measurement = try container.decode(String.self, forKey: .measurement)
        self.bikes = try container.decode([Bike].self, forKey: .bikes)
   } 
}

我尝试用这段代码解析它:

let decoder = JSONDecoder()
let definition = try? decoder.decode(athlete.self, from: jsonData)

我知道我正在正确检索 api,并且我可以访问解析“自行车”之前的所有字段,但我无法访问自行车。使用此代码,decoder.decode() 会失败。如何正确访问数组并对其进行解码?

【问题讨论】:

  • 为什么要添加自己的init 方法?你没有做任何特别的事情。尝试删除您的自定义init,它可能会起作用。如果没有,请在您的问题中发布错误。

标签: arrays json swift swift4


【解决方案1】:

您的代码一切都很好,除了一件事。在您的 Bike 声明中,更改

let distance: String

let distance: Int

好的,既然我已经说过了,我要带你去完成任务。你的最后一行是:

let definition = try? decoder.decode(athlete.self, from: jsonData)

这是非常愚蠢的。这个方法返回一个错误,告诉你问题出在哪里,你把这个错误扔掉了!要么将 try? 更改为 try! 以强制崩溃并在控制台中记录错误,要么将其更改为 try 并将整个内容包装在 try/catch 博客中并自己记录:

do {
    let definition = try decoder.decode(athlete.self, from: jsonData)
} catch {
    print(error)
}

我就是这样知道你犯了什么错误的。不是因为我聪明。不是因为我有一双锐利的眼睛。两者都不是真的!这是因为我记录了错误,而不是像你那样把它扔掉。如果你这样做了,你一开始就不需要问这个问题。

【讨论】:

  • 此外,rmaddy 在这方面是正确的:如果您省略 init(from:) 实现,您的代码将同样有效,因为它没有任何意义。自动合成的实现在这里很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
相关资源
最近更新 更多