-1

I have a problem with parsing JSON in a Codable Struct.

I will post 2 different Trys with each the opposite Behaviour.

Try 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
}

This one gives me the following Error Message:

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

Type Missmatch Expected Int but found String.

If I change the Decoder Dict to String:

let memeData = try! decoder.decode([String: Generals].self, from: data)

I get the Opposite Error Message:

[_JSONKey(stringValue: "success", intValue: nil)], debugDescription: "Expected to decode Dictionary but found a number instead.", underlyingError: nil)): file networking.playground, line 11

Can anyone give me an Advice what I am doing wrong or what part I am missing?

Following the JSON Response:

{
    "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
            },

Thanks in advance!

Midoxx
  • 67
  • 7

1 Answers1

1

Always make your codable model according to your API response. In your scenario, I think your model will be like this:

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?
}

and while decoding from data, decode like this way.

let memeData = try! decoder.decode(Generals.self, from: data) 
Asif Newaz
  • 557
  • 7
  • 17
  • Sorry for Second Comment but would you mind to tell me how you see in JSON Response which Value is actually an Int and which one a String? Thank you! – Midoxx May 09 '20 at 17:37
  • 1
    generally, JSON response value within a double quotation (" ") mark is a string and a value that is a number with a fractional amount may be float/double else integer. – Asif Newaz May 09 '20 at 17:44