Search code examples
arraysjsonswiftalamofire

how to add additional field in json array structure


i need to add addition boolean field то make selectable table of brands and models. Original json struct is:

    {
        "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
                    }
                ],
......

i need to add isExpended: Bool = false in brands and models structs. So array should look like this:

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

my models:

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
}

to getting json i use:

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

I do not want to go through all the elements of the array and put them in another, with the correct structure. Is there another way to change the structure of an array?


Solution

  • First of all please conform to the naming convention that struct and class names start with a capital letter and are CamelCased. Further name structs in singular form. In terms of language semantics you are creating one BrandModel, not one BrandModels

    If you need to add custom members in the structs conforming to Decodable you have to specify the CodingKeys

    And in most cases it's sufficient to declare the decoded struct members as constants (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
    }