Swift JSON 可编码类型不匹配反之亦然
Swift JSON Codable Type Missmatch Vice Versa
我在 Codable 结构中解析 JSON 时遇到问题。
我将 post 进行 2 次不同的尝试,每次尝试的行为都相反。
尝试 1:
var url = URL(string: "https://api.imgflip.com/get_memes")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
guard let data = data else {
print("Is NIL")
return
}
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let memeData = try! decoder.decode([Int: Generals].self, from: data)
print(memeData)
}
task.resume()
struct Generals: Codable {
let success: String
let data: [Int: Memes]
}
struct Memes: Codable {
let memes: [MemeDetail]
}
struct MemeDetail: Codable {
let id: Int
let name: String
let url: URL
let width: Int
let height: Int
let box_count: Int
}
这个给我以下错误信息:
Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(Swift.Int, Swift.DecodingError.Context(codingPath: [_DictionaryCodingKey(stringValue: "data", intValue: nil)], debugDescription: "Expected Int key but found String key instead.", underlyingError: nil)): file networking.playground, line 15
键入不匹配应为 Int 但找到的是 String。
如果我将 Decoder Dict 更改为 String:
let memeData = try! decoder.decode([String: Generals].self, from: data)
我收到相反的错误消息:
[_JSONKey(stringValue: "success", intValue: nil)], debugDescription: "Expected to decode Dictionary but found a number instead.", underlyingError: nil)): file networking.playground, line 11
任何人都可以给我一个建议,我做错了什么或者我遗漏了什么部分?
在 JSON 响应之后:
{
"success": true,
"data": {
"memes": [
{
"id": "112126428",
"name": "Distracted Boyfriend",
"url": "https://i.imgflip.com/1ur9b0.jpg",
"width": 1200,
"height": 800,
"box_count": 3
},
{
"id": "181913649",
"name": "Drake Hotline Bling",
"url": "https://i.imgflip.com/30b1gx.jpg",
"width": 1200,
"height": 1200,
"box_count": 2
},
提前致谢!
始终根据您的 API 响应制作您的可编码模型。在您的场景中,我认为您的模型将是这样的:
struct Generals: Codable {
let success: Bool
let data: Memes
}
struct Memes: Codable {
let memes: [MemeDetail]
}
struct MemeDetail: Codable {
let id: String?
let name: String?
let url: String?
let width: Int?
let height: Int?
let box_count: Int?
}
并且在从数据解码时,像这样解码。
let memeData = try! decoder.decode(Generals.self, from: data)
我在 Codable 结构中解析 JSON 时遇到问题。
我将 post 进行 2 次不同的尝试,每次尝试的行为都相反。
尝试 1:
var url = URL(string: "https://api.imgflip.com/get_memes")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
guard let data = data else {
print("Is NIL")
return
}
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let memeData = try! decoder.decode([Int: Generals].self, from: data)
print(memeData)
}
task.resume()
struct Generals: Codable {
let success: String
let data: [Int: Memes]
}
struct Memes: Codable {
let memes: [MemeDetail]
}
struct MemeDetail: Codable {
let id: Int
let name: String
let url: URL
let width: Int
let height: Int
let box_count: Int
}
这个给我以下错误信息:
Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(Swift.Int, Swift.DecodingError.Context(codingPath: [_DictionaryCodingKey(stringValue: "data", intValue: nil)], debugDescription: "Expected Int key but found String key instead.", underlyingError: nil)): file networking.playground, line 15
键入不匹配应为 Int 但找到的是 String。
如果我将 Decoder Dict 更改为 String:
let memeData = try! decoder.decode([String: Generals].self, from: data)
我收到相反的错误消息:
[_JSONKey(stringValue: "success", intValue: nil)], debugDescription: "Expected to decode Dictionary but found a number instead.", underlyingError: nil)): file networking.playground, line 11
任何人都可以给我一个建议,我做错了什么或者我遗漏了什么部分?
在 JSON 响应之后:
{
"success": true,
"data": {
"memes": [
{
"id": "112126428",
"name": "Distracted Boyfriend",
"url": "https://i.imgflip.com/1ur9b0.jpg",
"width": 1200,
"height": 800,
"box_count": 3
},
{
"id": "181913649",
"name": "Drake Hotline Bling",
"url": "https://i.imgflip.com/30b1gx.jpg",
"width": 1200,
"height": 1200,
"box_count": 2
},
提前致谢!
始终根据您的 API 响应制作您的可编码模型。在您的场景中,我认为您的模型将是这样的:
struct Generals: Codable {
let success: Bool
let data: Memes
}
struct Memes: Codable {
let memes: [MemeDetail]
}
struct MemeDetail: Codable {
let id: String?
let name: String?
let url: String?
let width: Int?
let height: Int?
let box_count: Int?
}
并且在从数据解码时,像这样解码。
let memeData = try! decoder.decode(Generals.self, from: data)