【问题标题】:Converting API JSON data to a Swift struct将 API JSON 数据转换为 Swift 结构
【发布时间】:2020-10-15 10:28:37
【问题描述】:

我是第一次使用 Swift,我希望能够将 API 响应中的一些信息处理成可用的 Swift 对象。

我有(例如)从我的 API 返回的以下数据:

{
    data: [{
       id: 1,
       name: "Fred",
       info: {
           faveColor: "red",
           faveShow: "Game of Thrones",
           faveIceCream: "Chocolate",
           faveSport: "Hockey",
       },
       age: "28",
       location: "The Moon",
    },{
        ...
    }]
}

我很快就从 API 中返回了 data。我得到了第一个对象,我正在转换它并像这样访问它:

let json = try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
let dataParentNode = json["data"] as! [[String:Any]]
let firstObject = dataParentNode[0]

let _id = firstObject["id"] as? String ?? "0"
let _name = firstObject["name"] as? String ?? "Unknown"

这很好,直到我想开始处理属于第一个对象的子对象,所以我想出了以下structs 来尝试使这个更干净。

请注意 - 我不需要处理所有返回的 JSON 数据,因此我想将其转换为结构中所需的内容

struct PersonInfo : Codable {
    let faveColor: String?
    let faveShow: String?
}

struct Person : Codable {
   let id: String?
   let name: String?
   let info: PersonInfo?
}

当我接受这个时:

let json = try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
let dataParentNode = json["data"] as! [[String:Any]]
let firstObject = dataParentNode[0]

然后尝试将firstObject 转换为PersonfirstObject["info"] 转换为PersonInfo 我似乎无法让它工作(我得到nil)。

let personInfo = firstObject["info"] as? PersonInfo

谁能给点建议?我只需要考虑获取 API 响应数据并将其映射到给定的结构(带有子对象),而忽略我不需要的键。

【问题讨论】:

  • let personInfo = firstObject as? PersonInfo, firstObject as? PersonInfo 为 nil,因为 firstObject 不能作为 PersonInfo 移动,它充其量只是一个字典。 let personInfo = PersonInfo(faveColor: firstObject["faveColor"] as? String ?? "Unknown color", faveShow: firstObject["faveColor"] as? String ?? "Unknown show")
  • @Larme - 抱歉,这是一个错字。 firstObject 是 JSON 中 data 数组中的第一个结果,因此它应该是:let personInfo = firstObject["info"] as? PersonInfo 在我的 OP 中
  • let personInfoDict = firstObject["info"] as? [String: Any]let personInfo = PersonInfo(faveColor: personInfoDict["faveColor"] as? String ?? "Unknown color", faveShow: personInfoDict["faveColor"] as? String ?? "Unknown show")

标签: json swift codable


【解决方案1】:

您可以简单地使用JSONDecoderdecode(_:from:) 函数:

let decoder = JSONDecoder()
do {
    let decoded = try decoder.decode([String: [Person]].self, from: data)
    let firstObject = decoded["data"]?.first
} catch {
    print(error)
}

你可以像这样向你的模型添加另一个结构体:

struct PersonsData: Codable {
    let data: [Person]
}

并使用该类型映射您的 JSON:

let decoder = JSONDecoder()
do {
    let decoded = try decoder.decode(PersonsData.self, from: data)
    let firstObject = decoded.data.first
} catch {
    print(error)
}

更新:您的 Person 结构可能需要稍作更改,因为 id 属性在 JSON 中是整数。

所以,最终会是这样的:

struct Person : Codable {
   let id: Int?
   let name: String?
   let info: PersonInfo?
}

【讨论】:

  • 再次感谢您。这就是我的答案。我曾尝试做类似的事情,但仍然出现错误。结果我没有注意到我需要覆盖的 API 响应的潜在变化。现在一切正常,代码更简洁!
猜你喜欢
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 2019-03-13
  • 2021-10-05
  • 1970-01-01
  • 2015-06-15
相关资源
最近更新 更多