Home > Blockchain >  typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue
typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue

Time:03-08

I have had this problem for quite a while and still didn’t solve it. I am trying to decode the JSON from a URL response. I tried numerous things like changing the decoder. to this

let productData = try JSONDecoder().decode([ProductDetail].self, from: data)

the error I get is

typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "product", intValue: nil)], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))
typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "product", intValue: nil)], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))
typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "product", intValue: nil)], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))
typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "product", intValue: nil)], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))

this is my product struct



struct ProductDetail: Codable {
    var code: String?
    var product: [Product?]
}
struct Product: Codable {
    var _id: String?
    var additives_tags: [String]? // [JSON?]
    var allergens_tags: [String]?// [JSON?]
    var brand_owner: String?
    var countries_tags: [String]?  // [JSON?]
    var image_url: String?
    var image_front_small_url: String?
    var image_front_thumb_url: String?
    var image_front_url: String?
    var image_ingredients_small_url: String?
    var image_ingredients_thumb_url: String?
    var image_ingredients_url: String?
    
}

and this is the fetch function

func fetchProduct(completionHandler: @escaping (ProductDetail) -> Void){
        let url = URL(string: "https://world.openfoodfacts.org/api/v0/product/87222241")!
        
        URLSession.shared.dataTask(with: url) { (data,
        response, error) in
            guard let data = data else { return}
            
            do {
                let productData = try JSONDecoder().decode(ProductDetail.self, from: data)
                print(productData)
                completionHandler(productData)
            }catch {
                let error = error
                print(error)
            }
            
        }.resume()
        
    }

json file (https://world.openfoodfacts.org/api/v0/product/87222241)

{
    "code": "87222241",
    "product": {
        "_id": "87222241",
        "_keywords": [
            "aa",
            "drink"
        ],
        "added_countries_tags": [],
        "additives_debug_tags": [],
        "additives_old_tags": [],
        "additives_original_tags": [],
        "additives_prev_original_tags": [],
        "additives_tags": [],
        "allergens": "",
        "allergens_from_ingredients": "",
        "allergens_from_user": "(fr) ",
        "allergens_hierarchy": [],
        "allergens_tags": [],
        "amino_acids_prev_tags": [],
        "amino_acids_tags": [],
        "brands": "AA drink ",
        "brands_tags": [
            "aa-drink"
        ],
        "categories_debug_tags": [],
        "categories_hierarchy": [],
        "categories_prev_hierarchy": [],
        "categories_prev_tags": [],
        "categories_properties": {},

CodePudding user response:

You have product defined as an Array in your model. But, as the error says, in the JSON, it's a Dictionary. Change your model to:

struct ProductDetail: Codable {
    var code: String?
    var product: Product? //<-- Here
}
  • Related