Sivabalaa Jothibose
Sivabalaa Jothibose

Reputation: 800

Swift 4 Codable array with dictionary has value of String and Array

struct ProductDetails:Codable {
    var custom_attributes:[CustomAttributesData]
    struct CustomAttributesData:Codable {
        var attribute_code:String
        var value:String
    }
}

I have an Array of custom_attributes has dictionary with elements of attribute_code as String & value as String, but some value datatype's are in Array, due to Array I am not able to parse using codable, help me out, Thanks in advance

"custom_attributes": [
    {
        "attribute_code": "image",
        "value": "/6/_/6.jpg"
    },
    {
        "attribute_code": "small_image",
        "value": "/6/_/6.jpg"
    }
    {
        "attribute_code": "news_to_date",
        "value": "2017-09-30 00:00:00"
    },
    {
        "attribute_code": "category_ids",
        "value": [
            "2",
            "120"
        ]
    },
    {
        "attribute_code": "options_container",
        "value": "container2"
    }
]

I have added json above.

Upvotes: 1

Views: 1050

Answers (1)

vadian
vadian

Reputation: 285132

You have to add a custom initializer which distinguishes between String and [String].

This code declares value as [String] and converts a single string to an array

struct ProductDetails : Decodable {
    let custom_attributes : [CustomAttributesData]

    struct CustomAttributesData : Decodable {

        private enum CodingKeys : String, CodingKey {
            case attributeCode = "attribute_code", value
        }

        let attributeCode : String
        let value : [String]

        init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            attributeCode = try container.decode(String.self, forKey: .attributeCode)
            do {
                let string = try container.decode(String.self, forKey: .value)
                value = [string]
            } catch DecodingError.typeMismatch {
                value = try container.decode([String].self, forKey: .value)
            } 
        }
    }
}

Alternatively you could use two separate properties stringValue and arrayValue

Upvotes: 3

Related Questions