Search code examples
iosswiftdictionaryswift5

Swift Dictionary API "No value associated with key CodingKeys(stringValue: \"type\", intValue: nil) (\"type\").", underlyingError: nil))


I am running into a error showing that there is no value for "type" from the API I'm trying to grab from. Ive tried looking through other posts revolving around this but can't find anything that works for me without causing a different issue to come up.

The full error I'm getting is "No value associated with key CodingKeys(stringValue: "type", intValue: nil) ("type").", underlyingError: nil))

The API I'm trying to grab from is: https://github.com/ToontownRewritten/api-doc/blob/master/invasions.md

import UIKit

struct InvasionList: Decodable {
    let type: String
    let asOf: Int?
    let progress: String?
    
    
}

class ViewController: UIViewController {
    

    override func viewDidLoad() {
        super.viewDidLoad()
        let jsonUrlString = "https://www.toontownrewritten.com/api/invasions"
        guard let url = URL(string: jsonUrlString) else { return }
        
        URLSession.shared.dataTask(with: url) { (data, response, err) in
            
            guard let data = data else {return }
            
            do {
                let invasions = try JSONDecoder().decode(InvasionList.self, from: data)
                print(invasions.type)
            
            
            } catch let err {
                print(err)
            }
            
            
            }.resume()
        
    }


}

Solution

  • Your InvasionList doesn't actually match the structure of the JSON that you're trying to decode. It matches one small part of it, but you need to decode the entire thing. This includes the outermost wrapper (the part with lastUpdated and the dynamic keys for each "invasion").

    Here's a working example:

    let jsonData = """
       {"lastUpdated":1624230138,"invasions":{"Gulp Gulch":{"asOf":1624230127,"type":"Robber Baron","progress":"3797/7340"},"Splashport":{"asOf":1624230129,"type":"Ambulance Chaser","progress":"2551/8000"},"Kaboom Cliffs":{"asOf":1624230131,"type":"Money Bags","progress":"5504/6000"},"Boingbury":{"asOf":1624230132,"type":"Tightwad","progress":"4741/8580"}},"error":null}
    """.data(using: .utf8)!
    
    struct InvasionWrapper: Decodable {
        let lastUpdated : Int
        let invasions : [String:Invasion]
    }
    
    struct Invasion: Decodable {
        let type: String
        let asOf: Int?
        let progress: String?
    }
    
    do {
        let list = try JSONDecoder().decode(InvasionWrapper.self, from: jsonData)
        print(list)
    } catch {
        print(error)
    }