Search code examples
jsonswiftsubclassingjsondecoder

Getting Errors when Subclassing JSON (Swift)


I'm fairly new to dealing with JSON data in Swift and I am trying to subclass some products. I don't mean to code dump, but I want to give you the whole picture. I have three errors that say the same thing: Errors thrown from here are not handled They occur in required init. Thanks in advance. Here's the code:

import UIKit

class Product: Decodable {
    var category: String = ""
    var material: String = ""

    init() {

    }
}

class TelephoneWithCord: Product {

    var sku: Double
    var isNew: Bool

    private enum CodingKeys: String, CodingKey {
        case sku = "sku"
        case isNew = "isNew"
    }

    required init(from decoder: Decoder) {

        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.sku = try container.decode(Double.self, forKey: .sku)
        self.isNew = try container.decode(Bool.self, forKey: .isNew)
    }
}

let json = """

{
    "category" : "home",
    "material" : "plastic",
    "sku" : 264221,
    "isNew" : true
}

""".data(using: .utf8)!

let telephoneWithCord = try! JSONDecoder().decode(TelephoneWithCord.self, from: json)

telephoneWithCord.category
telephoneWithCord.material
telephoneWithCord.sku
telephoneWithCord.isNew

Solution

  • "Errors thrown", could perhaps, be a hint on how to fix this. Add throws to required init. Also, don't forget to call super for your code to be properly initialized or you will get another error. Try these changes ...

    required init(from decoder: Decoder) throws {  // add throws to eliminate errors
    
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.sku = try container.decode(Double.self, forKey: .sku)
        self.isNew = try container.decode(Bool.self, forKey: .isNew)
        try super.init(from: decoder)  // calling super for proper intialization of code
    }
    

    As a side note: If you are not using any decimal points in your sku's, then you should change the type to Int instead of Double.