预计解码 Int 但找到一个字符串
Posted
技术标签:
【中文标题】预计解码 Int 但找到一个字符串【英文标题】:Expected to decode Int but found a string 【发布时间】:2019-02-15 08:29:05 【问题描述】:我的 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,我正在谷歌搜索这个问题,但无法解决它。有人可以帮我找出问题所在并解释一下吗?
当我从ServerStatus
中删除data
部分时,一切正常。所以问题在于解析data
部分
【问题讨论】:
id
是 JSON 中的字符串,但您的 struct
将 id
定义为 Int
。将其更改为String
,问题就消失了。
@rmaddy 哇!那太快了!非常感谢!但是一个简单的问题,我怎样才能将ID
保存为整数?
@J.Doe 你不能在服务器端发送一个 Int 吗?
看起来在未来,我们将能够选择加入 string-as-int 行为。见bugs.swift.org/browse/SR-5249。同时,转到该链接并支持该问题:)。
@ielyamani,你如何从服务器发送一个 int? json 编码时,所有数值都会自动用引号括起来。我不知道你将如何从服务器返回一个实际的整数。
【参考方案1】:
将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)
【讨论】:
基于 cmets,OP 希望id
成为 Int
,所以现在的问题是如何将 JSON 中的字符串转换为结构中所需的 Int
值。
以上是关于预计解码 Int 但找到一个字符串的主要内容,如果未能解决你的问题,请参考以下文章
JSONDecoder - “预期解码 Dictionary<String, Any> 但找到了一个字符串/数据。”
Swift Codable 期望解码 Dictionary<String, Any> 但找到了一个字符串/数据