Как добавить дополнительное поле в структуре массива JSON - PullRequest
0 голосов
/ 29 апреля 2018

Мне нужно добавить дополнительное логическое поле, чтобы выбрать таблицу марок и моделей. Исходная структура json:

    {
        "brands": [
            {
                "id": "19",
                "name": "Audi",
                "sort": "1",
                "num": 1,
                "models": [
                    {
                        "id": "190",
                        "name": "TTS",
                        "num": 1
                    },
                    {
                        "id": "189",
                        "name": "TT",
                        "num": 2
                    },
                    {
                        "id": "188",
                        "name": "V8",
                        "num": 3
                    },
                    {
                        "id": "187",
                        "name": "SQ5",
                        "num": 4
                    }
                ],
......

Мне нужно добавить isExpended: Bool = false в брендах и моделях структур. Поэтому массив должен выглядеть так:

{
        "brands": [
            {
          --->  "isExpanded": false,
                "id": "19",
                "name": "Audi",
                "sort": "1",
                "num": 1,
                "models": [
                    {
                 --->   "isExpanded": false,
                        "id": "190",
                        "name": "TTS",
                        "num": 1
                    },

мои модели:

struct auto_data: Decodable {
    var brands: [brands]
    var gearbox: [gearbox]
    var fuel: [fuel]
    var version: String
}

struct brands: Decodable {
    var id: String
    var name: String
    var sort: String
    var num: Int
    var models: [brand_models]
}

struct brand_models: Decodable {
    var id: String
    var name: String
    var num: Int
}

для получения JSON я использую:

func get_data (order_type: String, localization: String, version: String, completion: @escaping ([brands]?) -> Void) {
    let encodedBodyParams = "order_type=\(order_type)&localization=\(localization)&version=\(version)"
    let url = URL(string: "http://skat.az/forapi/api/get_data.php")
    Alamofire.request(url!, method: .post, parameters: [:], encoding: encodedBodyParams, headers: [:]).responseJSON { (response) in
        if response.result.isSuccess {
            do {
                let result = response.data
                let data = try JSONDecoder().decode(auto_data.self, from: result!)

                completion(data.brands)
            } catch {
                print("Error: \(error)")
            }
            print("models ОК!")
        } else {
            print("error response: \(String(describing: response.error))")
            completion(nil, nil, nil)
        }
    }
}

Я не хочу просматривать все элементы массива и помещать их в другие, с правильной структурой. Есть ли другой способ изменить структуру массива?

Ответы [ 2 ]

0 голосов
/ 29 апреля 2018

Прежде всего, пожалуйста, соблюдайте соглашение об именах, согласно которому имена структур и классов начинаются с заглавной буквы и имеют значение CamelCased . Далее название структурируется в единственном числе. С точки зрения языковой семантики вы создаете одну BrandModel, а не одну BrandModels

Если вам нужно добавить пользовательские элементы в структуры, соответствующие Decodable, вы должны указать CodingKeys

И в большинстве случаев достаточно объявить декодированные члены структуры как константы (let)

struct Brand: Decodable {

    private enum CodingKeys : String, CodingKey {
        case id, name, sort, num, models
    }

    var isExpanded = false
    let id: String
    let name: String
    let sort: String
    let num: Int
    let models: [BrandModel]
}

struct BrandModel: Decodable {

    private enum CodingKeys : String, CodingKey {
        case id, name, num
    }

    var isExpanded = false
    let id: String
    let name: String
    let num: Int
}
0 голосов
/ 29 апреля 2018

Простым решением будет анализ вашего JSON, а затем добавление ожидаемого нового поля путем итерации по каждому бренду. Наконец, вам придется преобразовать объект обратно в JSON.

1. var obj = JSON.parse('{ your json }');      parse object 
2. obj.brands(2)["isExpanded"] = false;        add new propertie
3. JSON.stringify(obj)                         convert back to JSON
...