Как добавить или удалить объект в результате JSON Codable Swift 4 (с динамическими ключами) - PullRequest
0 голосов
/ 02 декабря 2018

Я хочу импортировать JSON в swift с помощью Codable, изменить объект, добавив или удалив объект, и экспортировать его в JSON.

Здесь моя структура

class GenericCodingKeys: CodingKey {
var stringValue: String
var intValue: Int?

required init?(stringValue: String) { self.stringValue = stringValue }
required init?(intValue: Int) { self.intValue = intValue; self.stringValue = "\(intValue)" }
}

class ListSpecie : Codable {
var species: [String : Specie]

required init(from decoder: Decoder) throws
{
    let container = try decoder.container(keyedBy: GenericCodingKeys.self)
    self.species = [String: Specie]()
    for key in container.allKeys{
        let value = try container.decodeIfPresent(Specie.self, forKey: GenericCodingKeys(stringValue: key.stringValue)!)
        self.species[key.stringValue] = value
    }
}
}

class Specie : Codable {
var name : String?
var latinName : [String]?

enum CodingKeys: String, CodingKey {
    case name = "l"
    case latinName = "ll"
}
required init(from decoder: Decoder) throws
{
    let sValues = try decoder.container(keyedBy: CodingKeys.self)
    name = try sValues.decodeIfPresent(String.self, forKey: .name)
    latinName = try sValues.decodeIfPresent(Array<String>.self, forKey: .latinName)
}
func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encodeIfPresent(name, forKey: .name)
    try container.encodeIfPresent(latinName, forKey: .latinName)
}
}

Здеськод с образцом JSON

let myJson = """
       {
            "especeID1": {
            "l": "Ail",
            "ll": ["Allium sativum L.","Allium"]
            },
            "especeID2": {
            "l": "Artichaut",
            "ll": ["Cynara cardunculus"]
            }
        }
    """

    let jsonDATA = myJson.data(using: .utf8)!

    do{
        self.jsonResult = try JSONDecoder().decode(ListSpecie.self, from: jsonDATA)
    }catch{
        print(error.localizedDescription)
    }

Здесь я хочу добавить или удалить объект specie в jsonResult

    for myspecie in (self.jsonResult?.species)! {
        print(myspecie.key + " " +  myspecie.value.name!)
    }

    // Encodage
    let encoder = JSONEncoder()
    let productJSON = try! encoder.encode(self.jsonResult?.species) 

    let jsonString = String(data: productJSON, encoding: .utf8)!

Кто-то может сказать мне, как я могу добавить или удалить объект specie в моем jsonResultпеременная.

Большое спасибо за помощь, которую вы можете оказать мне.

1 Ответ

0 голосов
/ 02 декабря 2018

Прежде всего ваш код слишком сложный, большая часть кода избыточна.

Достаточно одного класса (рассмотрим структуру)

class Specie : Codable {
    var name : String?
    var latinName : [String]?

    enum CodingKeys: String, CodingKey {
        case name = "l"
        case latinName = "ll"
    }
}

Если name и latin name должен появляться везде, объявлять свойства необязательными (убрать вопросительные знаки).

И декодировать JSON

self.jsonResult = try JSONDecoder().decode([String:Specie].self, from: jsonDATA)

jsonResult теперь словарь ([String:Specie])Вы можете удалить элементы

self.jsonResult.removeValue(forKey: "especeID2")

или добавить элемент

let newSpecies = Specie()
newSpecies.name = "Potato"
newSpecies.latinName = ["Solanum tuberosum"]
self.jsonResult["especeID3"] = newSpecies

и кодировать объект

let encoder = JSONEncoder()
let productJSON = try! encoder.encode(self.jsonResult)
let jsonString = String(data: productJSON, encoding: .utf8)!
...