Clave de análisis codificable rápido

Sep 09 2020

Tengo problemas para poner en marcha la codificación. Cualquier ayuda sería muy apreciada. Tengo lo siguiente en mi patio de recreo

Mi archivo JSON

{
"metadata": {
  "generated": {
    "timestamp": 1549331723,
    "date": "2019-02-04 20:55:23"
  }
},
"data": {
    "CA": {
    "country-id": 25000,
    "country-iso": "CA",
    "country-eng": "Canada",
    "country-fra": "Canada"
    }
  }
}

Usé la aplicación quicktype para ayudar a generar las siguientes estructuras

// MARK: - Welcome
struct Welcome: Codable {
    let metadata: Metadata?
    let data: DataClass?
}

// MARK: - DataClass
struct DataClass: Codable {
    let ca: CA

    enum CodingKeys: String, CodingKey {
        case ca = "CA"
    }
}

// MARK: - CA
struct CA: Codable {
    let countryID: Int
    let countryISO, countryEng, countryFra: String

    enum CodingKeys: String, CodingKey {
        case countryID = "country-id"
        case countryISO = "country-iso"
        case countryEng = "country-eng"
        case countryFra = "country-fra"
    }
}

// MARK: - Metadata
struct Metadata: Codable {
    let generated: Generated?
}

// MARK: - Generated
struct Generated: Codable {
    let timestamp: Int?
    let date: String?
}

Código SWIFT:

 do {
        guard let url = Bundle.main.url(forResource: "data", withExtension: "json") else { return 0 }

        let jsonData = try Data(contentsOf: url)
        let decoder = JSONDecoder()

        let data = try decoder.decode(CA.self, from: jsonData)
        print (data)
        print(data.countryID)
        print(data.countryISO)
    } catch { print("error" , error) }

Este es el mensaje de error que recibo.

jsonData 244 bytes
error keyNotFound(CodingKeys(stringValue: "country-id", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"country-id\", intValue: nil) (\"country-id\").", underlyingError: nil))

El valor está ahí, no estoy seguro de cuál es el problema. Si elimino country-id del json y el modelo, obtengo el mismo error para country-iso.

Respuestas

1 DávidPásztor Sep 09 2020 at 13:56

Eso es porque estás intentando decodificar el tipo incorrecto. El CAtipo está anidado en varios niveles en su JSON, debe pasar el tipo raíz a JSONDecoder.decode.

let root = try decoder.decode(Welcome.self, from: jsonData)
guard let ca = root.data?.ca else { return 0 }
print(ca)