5
votes

Given this class:

class MyClass: Codable {
    var variable : Codable? = nil
}

I get error:

Type 'MyClass' does not conform to protocol 'Decodable'

Type 'MyClass' does not conform to protocol 'Encodable'

How can I have a generic variable that conforms to Codable as a property in a Codable class?

3
None of the answers have actually covered the reason for your error: it is because Swift procotols don't conform to themselves. - Dávid Pásztor
I believe it has to do with Codable. This code works. I think the reason is Codable itself, check out Y.Bonafons answer. - amir

3 Answers

4
votes

May be like this if i got your question correctly

class MyClass<T: Codable>: Codable {
    var variable : T? = nil
}
3
votes

If you try to implement your decoder you will have something like:

class MyClass: Codable {
    var variable: Codable?
    enum MyClassKeys: String, CodingKey {
        case variable = "variable"
    }
    required init(from decoder: Decoder) {
        let container = try! decoder.container(keyedBy: MyClassKeys.self)
        variable = try! container.decode(XXXX, forKey: .variable)
    }
}

But instead of XXXX, you should put a class type (for example String.self). What can you put here? Its not possible for the compiler to guess what you want. Instead of Codable type maybe you can put a class which conform to Codable protocol. So you can have something like this:

class MyClass: Codable {
    var variable: MyClass?
    enum MyClassKeys: String, CodingKey {
        case variable = "variable"
    }
    required init(from decoder: Decoder) {
        let container = try! decoder.container(keyedBy: MyClassKeys.self)
        variable = try! container.decode(MyClass.self, forKey: .variable)
    }
}
0
votes

You can't.

But as a workaround, you can create an enum conforming to Codable.

enum SubType: Codable {
    case foo
    case bar
}