swiftswift4json-deserializationjsondecoderparsing-error

How To Conform to the Sequence Protocol in Swift 4


Currently trying to parse a json dictionary to the screen in swift however I'm running into this sequence protocol error, and also a type mismatch error where it gets a string/data and expects a Int. Error is "Type 'ProductResponse' does not conform to protocol 'Sequence'" and

"typeMismatch(Swift.Int, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "code", intValue: nil)], debugDescription: "Expected to decode Int but found a string/data instead.", underlyingError: nil))"

 struct ProductResponse: Codable {
    let code: String
    let product: Product
    let statusVerbose: String
    let status: Int

    enum CodingKeys: String, CodingKey {
        case code, product
        case statusVerbose = "status_verbose"
        case status
    }
}

struct Product: Codable {
    let code: String
    let productName: String

    enum CodingKeys: String, CodingKey {
        case code
        case productName = "product_name"
    }

}


class ViewController: UIViewController {
    //var products = [Product]()
    let API_URL = "https://carsdata/api/v0/product/5000112630794.json"
    override func viewDidLoad() {
        super.viewDidLoad()
        Alamofire.request(API_URL).responseJSON {
            response in
            let json = response.data
            do
            {
                let decoder = JSONDecoder()
                let productData = try decoder.decode(ProductResponse.self, from: json!)
                for product in productData{  print(product.productName!) } }
            catch
                let err{  print(err) }
        }
    }
}

Solution

  • The problem is you are not parsing the JSON as it comes. You have two objects here. ProductResponse and Product and you're trying to parse it as one. productName is part of Product but you're trying to get it from ProductResponse. For clarity, I would recommend you to create 2 entities and try with this:

    struct ProductResponse: Codable {
        let code: String
        let product: Product
        let statusVerbose: String
        let status: Int
    
        enum CodingKeys: String, CodingKey {
            case code, product
            case statusVerbose = "status_verbose"
            case status
        }
    }
    
    struct Product: Codable {
        let code: String
        let productName: String
    
        enum CodingKeys: String, CodingKey {
            case code
            case productName = "product_name"
        }
    }
    

    And try to decode ProductResponse.self instead.