Reputation: 7068
ClassA conforming to Cadable and has a bunch of properties. One of them is a property of an already existing very complex ClassB that does not conform to Codable. Can I manually decode a non Codable property of a Codable class?
struct ClassA: Codable {
let title: String?
let subtitle: String?
let property: ClassB?
enum CodingKeys: String, CodingKey {
case title
case subtitle
case property
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
title = try container.decode(String.self, forKey: .title)
subtitle = try container.decode(String.self, forKey: .subtitle)
let JSONString = ?
property = ClassB.initWith(JSONString: JSONString)
}
class ClassB: NSObject {
// Already existing very complex ClassB implemenatation...
}
I get error:
Type 'ClassA' does not conform to protocol 'Encodable'
Upvotes: 1
Views: 674
Reputation: 22325
Yes you can.
The error is that you're missing func encode(to encoder: Encoder) throws
in ClassA
. Codable = Encodable & Decodable
, so it's trying to find a way to encode ClassA
as well. ClassB
isn't encodable so it can't do it automatically, and you haven't told it how to do it manually either.
If you don't need to encode ClassA
instances, just make it Decodable
. Otherwise implement the missing encode
func.
Or just put in the work and make ClassB
codable as well. You can use an extension to add it after the fact. If you don't want to do that either, a workaround I've used is to declare a small private codable struct inside ClassA
like struct ClassBInfo: Codable
. Use that to get the info you need, then read its properties to init ClassB
.
Upvotes: 1
Reputation: 1278
try this
struct ClassA: Codable {
let title: String?
let subtitle: String?
let property: ClassB?
enum CodingKeys: String, CodingKey {
case title
case subtitle
case property
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
title = try container.decode(String.self, forKey: .title)
subtitle = try container.decode(String.self, forKey: .subtitle)
let JSONString = ?
property = ClassB.initWith(JSONString: JSONString)
}
class ClassB: Codable {
// Already existing very complex ClassB implemenatation...
}
Upvotes: 0