Search code examples
swiftswiftuiswift5decodable

Is Decodable inheritance even possible in Swift?


I usually use structs that inherit from Decodable to serialize JSON data i'm pulling from my backend. However, I have an application where a JSON payload is identical to an existing struct with a few minor differences. Thus, I would like to have a decodable struct that inherits from another decodable struct like this:

class Party: Decodable {
    var theme: String

}

class PublicParty : Party {
    var address: String = ""
}

However, when I send the following JSON payload, only "theme" from the Party class gets decoded while the "address" from PublicParty remains "":

{
"theme": "Black out or get out",
"address": "404 Mundus, Tabasko Beach 45778 WA"
}

Swift code:

func test(completion: @escaping(Result<PublicParty, Error>) -> ()) {
        guard let url = URL(string: "127.0.0.1:8000/test") else { return }

        URLSession.shared.dataTask(with: url) { (data, response, error) in

            // handle error
            if let error = error {
                completion(.failure(error))
                return
            }

            // decode data
            do {
                let search = try JSONDecoder().decode(PublicParty.self, from: data!)
                    print(search)
                completion(.success(search))
            } catch let error {
                completion(.failure(error))
            }

        }.resume()

}

As nothing is off in my front end/back end, does Swift even allow this functionality?


Solution

  • This worked:

    class Party: Decodable {
        var theme: String
    
    }
    
    class PublicParty : Party {
        var address: String = ""
    
         required init(from decoder: Decoder) throws {
    
            try super.init(from: decoder)
    
            let values = try decoder.container(keyedBy: CodingKeys.self)
            address = try values.decode(String.self, forKey: .address)
          }
    
        private enum CodingKeys: String, CodingKey
        {
            case address
    
        }
    }