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
}