我的JSON如下:
{
"status": true,
"data": {
"img_url": "/images/houses/",
"houses": [
{
"id": "1",
"name": "Kapital",
"url": "https://kapital.com/",
"img": "10fbf4bf6fd2928affb180.svg"
}
]
}
}
我正在使用下一个结构:
struct ServerStatus: Decodable {
let status: Bool
let data: ServerData
}
struct ServerData: Decodable {
let img_url: String
let houses: [House]
}
struct House: Decodable {
let id: Int
let img: String
let name: String
let url: String
}
但是当我使用时:
let houses = try JSONDecoder().decode(ServerStatus.self, from: data)
我遇到下一个错误:
3 : CodingKeys(stringValue: "id", intValue: nil)
- debugDescription : "Expected to decode Int but found a string/data instead."
这是我第一次使用Decodables,我正在搜索此问题,但无法解决。有人可以帮助我找出问题所在并向我解释吗?
从data
移除ServerStatus
部分后,一切正常。所以问题出在解析data
部分
答案 0 :(得分:6)
将您的House
结构更改为此:
House: Decodable {
let id: String
let name: String
let url: String
let img: String
}
id
应该是String
。并获得房屋:
let houses = try JSONDecoder().decode(ServerStatus.self, from: data).data.houses
如果您不想将来自服务器的id
更改为Int
,则可以提供Encodable和Decodable的自定义实现,以定义自己的编码和解码逻辑。
struct House {
let id: Int
let img: String
let name: String
let url: String
enum CodingKeys: String, CodingKey {
case id, img, name, url
}
}
extension House: Decodable {
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
guard let idInt = Int(try values.decode(String.self, forKey: .id)) else {
fatalError("The id is not an Int")
}
id = idInt
img = try values.decode(String.self, forKey: .img)
name = try values.decode(String.self, forKey: .name)
url = try values.decode(String.self, forKey: .url)
}
}
//Just in case you want to encode the House struct
extension House: Encodable {
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(String(id), forKey: .id)
try container.encode(img, forKey: .img)
try container.encode(name, forKey: .name)
try container.encode(url, forKey: .url)
}
}
let decoder = JSONDecoder()
let data = """
{
"status": true,
"data": {
"img_url": "/images/houses/",
"houses": [
{
"id": "1",
"name": "Kapital",
"url": "https://kapital.com/",
"img": "10fbf4bf6fd2928affb180.svg"
}
]
}
}
""".data(using: .utf8)!
let houses = try JSONDecoder().decode(ServerStatus.self, from: data).data.houses
print(houses)