首页 > 解决方案 > How to fix the "no value associated" error with CodingKeys?

问题描述

I am trying to decode the API from the API below, but I am still getting the error below:

keyNotFound(CodingKeys(stringValue: "resources", intValue: nil), Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "resources", intValue: nil)], debugDescription: "No value associated with key CodingKeys(stringValue: \"resources\", intValue: nil) (\"resources\").", underlyingError: nil))

API Address: https://age-of-empires-2-api.herokuapp.com/docs/

I have already tried reviewing my structs numerous times, and trying the call code within different levels of the API, but still cannot get the data. I have also tried calling the objects from different levels with the print(resources.XXX) format.

This is my first data call from the API:

{
  "resources": {
    "civilizations": "https://age-of-empires-2-api.herokuapp.com/api/v1/civilizations", 
    "units": "https://age-of-empires-2-api.herokuapp.com/api/v1/units", 
    "structures": "https://age-of-empires-2-api.herokuapp.com/api/v1/structures", 
    "technologies": "https://age-of-empires-2-api.herokuapp.com/api/v1/technologies"
  }
}

These are the first two levels of the structs:

// MARK: - Resources
struct Resources: Codable {
    let resources: [String : ResourcesList]

    enum CodingKeys: String, CodingKey {
        case resources
    }
}

// MARK: - ResourcesList
struct ResourcesList: Codable {
    let civilizations: CivilizationList
    let units: UnitList
    let structures: StructureList
    let technologies: TechnologyList

    enum CodingKeys: String, CodingKey {
        case civilizations, units, technologies, structures
    }
}

Below these structs, I have implemented the models as indicated in the API website, e.g., CivilizationList, Civilization etc.

This is my call code:

        let jsonUrl = "https://age-of-empires-2-api.herokuapp.com/api/v1"
        guard let url = URL(string: jsonUrl) else { return }
        URLSession.shared.dataTask(with: url) { (data, response, error) in

            guard let data = data else { return }
            let dataAsString = String(data: data, encoding: .utf8)

            do {
                let decoder = JSONDecoder()
                let resources = try decoder.decode([String : Resources].self, from: data)
                print(resources)
            } catch {
                print(error)
            }
            print(dataAsString!)
        }.resume()

I have reviewed all the other threads here about the same error code, tried stuff, but there is probably something very basic that I am missing, unfortunately I am too much of a beginner to notice it. Any help is appreciated.

标签: jsonswift

解决方案


Model should be

// MARK: - Empty
struct Resources: Codable {
    let resources: ResourcesList
}

// MARK: - Resources
struct ResourcesList: Codable {
    let civilizations, units, structures, technologies: String
}

Decode

let resources = try decoder.decode(Resources.self, from: data)

as civilizations, units, structures, technologies are strings not models

OR

let resources = try decoder.decode([String : ResourcesList].self, from: data)

推荐阅读