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)