使用动态CodingKeys在Swift中解码JSON

时间:2019-11-14 23:37:06

标签: json swift codable

我无法弄清楚使用Swift解码此JSON的方法。 我试图遵循大量的教程和指南,但是没有任何适合我的东西。

我唯一能添加静态 CodingKeys 的东西是:“ especificaciones ”,“ id ”,“ titulo < / strong>“ 默认

"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" : ""
  }
}

}

这不是整个JSON,但也许您可以借此了解我要寻找的内容。

1 个答案:

答案 0 :(得分:0)

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

希望这对您有帮助!

//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)
        }

    }