Search code examples
iosjsonswiftcodable

How to display JSON data from API?


I am developing in Swift 4 and currently using Walmart's API in order to display their products and certain information about the products (example: name of product, price of product). I have read and watched many tutorials regarding parsing JSON data however I continue to get the same error. If anyone could tell me why I'm getting an error it would be highly appreciated.

Here is the JSON data I am getting from the API call:

{
query: "ipod",
sort: "relevance",
format: "json",
responseGroup: "base",
totalResults: 3570,
start: 1,
numItems: 10,
items: [
{
    itemId: 15076191,
    parentItemId: 15076191,
    name: "Apple iPod Touch 4th Generation 32GB with Bonus Accessory Kit",
    salePrice: 189
 }

I just want to display the name and salePrice data but I am unable to do so at the moment, instead I get this error: typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))

Here is my data model:

  struct Product: Codable {
    let name: String
    let salePrice: String

}

Here is the code in my ViewController class:

class ViewController: UIViewController {


import Foundation
import UIKit    


var products: [Product]?
override func viewDidLoad() {
    super.viewDidLoad()
    
    
    
    let urlString = "http://api.walmartlabs.com/v1/search?query=sauce&format=json&apiKey=xyz"
    guard let url = URL(string: urlString) else { return }
    
    URLSession.shared.dataTask(with: url) { (data, response, error) in
        if error != nil {
            print(error!.localizedDescription)
        }
        
        guard let data = data else { return }
        //Implement JSON decoding and parsing
        do {
            //Decode retrived data with JSONDecoder and assing type of Article object
            let productData = try JSONDecoder().decode([Product].self, from: data)
            print(productData)
            
        } catch let jsonError {
            print(jsonError)
        }
        
    }.resume()
    
    

}


}

Solution

  • Your json data is a dictionary not an array you either parse it and get the array , or try this

    struct Item: Codable {
       let query: String
       let sort: String
       let format: String
       let responseGroup: String
       let totalResults: Int
       let start: Int
       let numItems: Int
       let items: [Product]
    
    }
    
    struct Product: Codable {
       let itemId: Double 
       let parentItemId: Double 
       let name: String
       let salePrice: Int
    
    }
    
    let productData = try JSONDecoder().decode(Item.self, from: data)