解码此简单的JSON结构不起作用

时间:2019-06-22 05:39:17

标签: swift

我有一个简单的模型,该模型定义为对结构进行解码。 但是它在解码上失败了。 有人可以告诉我我在做什么错吗?

struct Model: Codable {
    let firstName: String
    let lastName: String
    let age: Int

    enum Codingkeys: String, CodingKey {
        case firstName = "first_name"
        case lastName = "last_name"
        case age
    }
}


class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let session = URLSession.shared
        let url = URL(string: "https://learnappmaking.com/ex/users.json")!
        let task = session.dataTask(with: url) { (data, response, error) in
            let decoder = JSONDecoder()
            let d = try! decoder.decode([Model].self, from: data!) //fails here
            print(d)
        }
        task.resume()
    }
}

我再次检查了json是否正确,但仍然无法解码。

显示错误

  

线程5:致命错误:“尝试!”表达式意外引发错误:   Swift.DecodingError.keyNotFound(CodingKeys(stringValue:“ firstName”,   intValue:nil),Swift.DecodingError.Context(codingPath:   [_JSONKey(stringValue:“索引0”,intValue:0)],debugDescription:“否   与键CodingKeys(stringValue:\“ firstName \”,   intValue:nil)(\“ firstName \”)。“,底层错误:nil))

它一直在搜索firstName,但是我专门有一个枚举来检查first_name

这是JSON有效载荷

[
  {
    "first_name": "Ford",
    "last_name": "Prefect",
    "age": 5000
  },
  {
    "first_name": "Zaphod",
    "last_name": "Beeblebrox",
    "age": 999
  },
  {
    "first_name": "Arthur",
    "last_name": "Dent",
    "age": 42
  },
  {
    "first_name": "Trillian",
    "last_name": "Astra",
    "age": 1234
  }
]

我知道我可以添加decoder.keyDecodingStrategy = .convertFromSnakeCase,但是我想知道为什么现有代码不起作用?

2 个答案:

答案 0 :(得分:0)

代码是正确的,但是您的模型显然存在一些问题(尽管convertFromSnakeCase可以正常工作)

我重新输入了结构,错误消失了。请复制并粘贴

struct Model : Decodable {
    let firstName : String
    let lastName : String
    let age : Int

    private enum CodingKeys : String, CodingKey { case firstName  = "first_name", lastName  = "last_name", age }
}

答案 1 :(得分:0)

其中一些值是可选的,为了安全起见,请全部设为可选,这肯定会起作用。

struct Model: Codable {
    let firstName: String?
    let lastName: String?
    let age: Int?

    enum Codingkeys: String, CodingKey {
        case firstName = "first_name"
        case lastName = "last_name"
        case age
    }
}