1

I'm fairly new to decoding from a JSON file.

My question is, how do I decode to find this: "product_name_en": "Coca Cola"(there's a lot more to that file, but not the node)

My struct is set up as:

struct ParseStructs : Decodable {

   var product_name_en : String

}

and my retrieve code is:

var testCall = "https://world.openfoodfacts.org/api/v0/product/5449000000996.json"



func request(urlString : String ){

    if let url = URL(string: urlString){

        let session = URLSession(configuration: .default)

        let task = session.dataTask(with :url) { (data , response , error) in

            if(error != nil){
                print(error!)
            }

                if let safeData = data{

                    print(safeData)
                    self.parseFunc(inputData: safeData)
                }

        }
        task.resume()
    }

}


func parseFunc(inputData : Data){

    let decoder = JSONDecoder()


    do{
    let decode = try decoder.decode(ParseStructs.self, from: inputData)
        print(decode)
    }catch{
        print(error)
    }

}

I just keep running into this lovely issue from the terminal line: 71733 bytes

keyNotFound(CodingKeys(stringValue: "product_name_en", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"product_name_en\", intValue: nil) (\"product_name_en\").", underlyingError: nil))

I've noticed that a lot of these questions gets hit with dislikes, but any help would be appreciated.

Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67
JohnM
  • 73
  • 7

1 Answers1

2

Your struct assumes the following JSON structure:

{
    "product_name_en": "Coca Cola"
}

while in fact the data you are interested in is wrapped in another object:

{
    "product": {
        "product_name_en": "Coca Cola"
    }
}

Typically, you'd solve this by defining another intermediate struct:

struct Product: Decodable {
    var product_name_en: String
}

struct ProductWrapper: Decodable {
    var product: Product
}

and then decode this in your parseFunc function:

let decoded = try decoder.decode(ProductWrapper.self, from: inputData)
let product = decoded.product

There are other ways to work around this, check out the "Dealing with Object Wrapping Keys" section of this awesome guide.

Xavier Lowmiller
  • 1,381
  • 1
  • 15
  • 24