5

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?

Community
  • 1
  • 1
amir
  • 1,332
  • 8
  • 15
  • 1
    None of the answers have actually covered the reason for your error: it is because [Swift procotols don't conform to themselves](https://stackoverflow.com/questions/33112559/protocol-doesnt-conform-to-itself). – Dávid Pásztor Jun 13 '18 at 15:04
  • I believe it has to do with Codable. [This code works](https://gist.github.com/hayek/b7bdd14e720e36ad5b38ba518d1adf73). I think the reason is Codable itself, check out Y.Bonafons answer. – amir Jun 13 '18 at 19:19

3 Answers3

4

May be like this if i got your question correctly

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

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)
    }
}
Y.Bonafons
  • 2,329
  • 13
  • 20
0

You can't.

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

enum SubType: Codable {
    case foo
    case bar
}
CZ54
  • 5,488
  • 1
  • 24
  • 39