0

I cant figure out the way to decode this JSON using Swift. I tried to follow a bunch of tutorials and guides but there is nothing that works for me.

The only things I am able to add static CodingKeys are: "especificaciones", "id", "titulo" and "default"

"especificaciones" : {
 "EXTERIOR" : {
  "sistema_automatico_de_ajuste_de_altura_para_faros" : {
    "id" : "865",
    "titulo" : "Sistema automatico de ajuste de altura para faros",
    "default" : ""
  },
  "antena_" : {
    "id" : "1366",
    "titulo" : "Antena ",
    "default" : ""
  },
  "luces_direccionales_en_espejos_laterales" : {
    "id" : "734",
    "titulo" : "Luces direccionales en espejos laterales",
    "default" : ""
  },
  "faros_traseros" : {
    "id" : "1430",
    "titulo" : "Faros traseros",
    "default" : ""
  },
},
 "DIMENSIONES INTERIORES" : {
  "espacio_para_las_piernas___delantera_trasera" : {
    "id" : "1417",
    "titulo" : "Espacio para las piernas - delantera/trasera",
    "default" : ""
  },
  "espacio_para_los_hombros____delantera_trasera" : {
    "id" : "1418",
    "titulo" : "Espacio para los hombros -  delantera/trasera",
    "default" : ""
  },
  "area_de_carga__l_" : {
    "id" : "1498",
    "titulo" : "Area de carga (L)",
    "default" : ""
  }
}

}

This is not the whole JSON but probably with this you can get an idea of what I am looking for.

1
  • Since you cant know what a categories user will create you need to use Dynamic Coding Keys. Can you update the question with a valid JSON? so we can get more information. Commented Nov 15, 2019 at 1:35

1 Answer 1

1
{ "especificaciones": { "RINES Y LLANTAS": { "llantas_delanteras": { "id": "935", "titulo": "Llantas delanteras", "default": "" }


private struct CustomCodingKeys: CodingKey {
    var stringValue: String
    init?(stringValue: String) {
        self.stringValue = stringValue
    }
    var intValue: Int?
    init?(intValue: Int) {
        return nil
    }
}

struct RootOutput {
    var entities:Entities?
    var mainRoot:String?
    var subRoot:String?
}


struct Root: Decodable {

    var rootLevel: SubTopRoot?

    init(from decoder: Decoder)  {
        do{
            let container = try decoder.container(keyedBy: CustomCodingKeys.self)
            for key in container.allKeys{
               rootLevel = try container.decodeIfPresent(SubTopRoot.self, forKey: CustomCodingKeys.init(stringValue: key.stringValue)!)
            }
        }catch{
            print(error.localizedDescription)
        }
    }
}

struct SubTopRoot: Decodable {

    var subTopLevel:SubRoot?

    init(from decoder: Decoder)  {
        do{
            let container = try decoder.container(keyedBy: CustomCodingKeys.self)
            for key in container.allKeys{
                subTopLevel = try container.decodeIfPresent(SubRoot.self, forKey: CustomCodingKeys.init(stringValue: key.stringValue)!)
                for index in 0..<(subTopLevel?.SubRootLevel.count ?? 0){
                    subTopLevel?.SubRootLevel[index].mainRoot = key.stringValue
                }
           }
        }catch{
            print(error.localizedDescription)
        }
    }


}

struct SubRoot: Decodable {

    var SubRootLevel:[RootOutput] = [RootOutput]()

    init(from decoder: Decoder)  {
        do{
            let container = try decoder.container(keyedBy: CustomCodingKeys.self)
            for key in container.allKeys{
                let entities = try container.decodeIfPresent(Entities.self, forKey: CustomCodingKeys.init(stringValue: key.stringValue)!)
                SubRootLevel.append(RootOutput.init(entities: entities, mainRoot:"" , subRoot: key.stringValue))
            }

        }catch{
            print(error.localizedDescription)
        }
    }

}

struct Entities: Codable {
    var id: String?
    var titulo: String?
    var defaultItem: String?

    init(from decoder: Decoder)  {
        do{
            let container = try decoder.container(keyedBy: CodingKeys.self)
                self.id = try container.decodeIfPresent(String.self, forKey: .id)
                self.titulo = try container.decodeIfPresent(String.self, forKey: .titulo)
                self.defaultItem = try container.decodeIfPresent(String.self, forKey: .defaultItem)


        }catch{
            print(error.localizedDescription)
        }
    }

    enum CodingKeys: String, CodingKey {
        case id = "id"
        case titulo = "titulo"
        case defaultItem = "default"
    }
}

Hope this is helpful for you !

//Dummy Test
   do {

            let dataString = "{\r\n\t\"especificaciones\": {\r\n\t\t\"RINES Y LLANTAS\": {\r\n\t\t\t\"llantas_delanteras\": {\r\n\t\t\t\t\"id\": \"935\",\r\n\t\t\t\t\"titulo\": \"Llantas delanteras\",\r\n\t\t\t\t\"default\": \"\"\r\n\t\t\t},\r\n\t\t\t\"llantas_traseras\": {\r\n\t\t\t\t\"id\": \"936\",\r\n\t\t\t\t\"titulo\": \"Llantas traseras\",\r\n\t\t\t\t\"default\": \"\"\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}"
            let data = Data(dataString.utf8)
            //here dataResponse received from a network request
            let decoder = JSONDecoder()
            let model = try decoder.decode(Root.self, from:data) //Decode JSON Response Data
            print(model.rootLevel?.subTopLevel?.SubRootLevel)
        } catch let parsingError {
            print("Error", parsingError)
        }

    }
Sign up to request clarification or add additional context in comments.

3 Comments

I tried it and it returns me this: The data couldn’t be read because it isn’t in the correct format. Root(rootLevel: Optional(TodoEnSubastas.SubTopRoot(subTopLevel: Optional(TodoEnSubastas.SubRoot(SubRootLevel: []))))) Optional([])
the json which you have posted is invalid ... may b thats y its throwing error
{ "especificaciones": { "RINES Y LLANTAS": { "llantas_delanteras": { "id": "935", "titulo": "Llantas delanteras", "default": "" }, "llantas_traseras": { "id": "936", "titulo": "Llantas traseras", "default": "" } } } } this is correct format for above json you posted

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.