将 API JSON 数据转换为 Swift 结构
Converting API JSON data to a Swift struct
我是第一次使用 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",
},{
...
}]
}
在 swift 我有 data
从 API 返回。我得到了 第一个对象,我正在转换它并像这样访问它:
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"
这很好,直到我想开始处理属于第一个对象的子对象,所以我想出了以下 struct
s 来尝试使它更干净。
请注意 - 我不需要处理返回的所有 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
转换为 Person
或将 firstObject["info"]
转换为 PersonInfo
我似乎无法让它工作(我得到 nil
).
let personInfo = firstObject["info"] as? PersonInfo
有人可以指点一下吗?我只需要集中精力获取 API 响应数据并将其映射到给定的结构(带有子对象),而忽略我不需要的键。
您可以简单地使用 JSONDecoder
的 decode(_: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?
}
我是第一次使用 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",
},{
...
}]
}
在 swift 我有 data
从 API 返回。我得到了 第一个对象,我正在转换它并像这样访问它:
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"
这很好,直到我想开始处理属于第一个对象的子对象,所以我想出了以下 struct
s 来尝试使它更干净。
请注意 - 我不需要处理返回的所有 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
转换为 Person
或将 firstObject["info"]
转换为 PersonInfo
我似乎无法让它工作(我得到 nil
).
let personInfo = firstObject["info"] as? PersonInfo
有人可以指点一下吗?我只需要集中精力获取 API 响应数据并将其映射到给定的结构(带有子对象),而忽略我不需要的键。
您可以简单地使用 JSONDecoder
的 decode(_: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?
}