# Inheriting from a Codable class

**URL:** <https://forums.swift.org/t/inheriting-from-a-codable-class/14874>\
**Category:** Using Swift\
**Created:** [July 31, 2018, 2:02pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874 "2018-07-31T14:02:59Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jon889](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon889/32/3139_2.png) [@Jon889](https://forums.swift.org/u/Jon889)\
**Post date:** [July 31, 2018, 2:02pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/1 "2018-07-31T14:02:59Z")

</div>

In the following code, I get the error that SuperClass has no initialisers. However the compiler is able to automatically generate code to conform to the Cod able protocols, it doesn't seem to do this with classes that inherit from a class that is Codable.

class BaseClass: Codable {  
let foo: String  
}

class SuperClass: BaseClass {  
let bar: Int

// required init(from decoder: Decoder) throws {  
// let container = try decoder.container(keyedBy: CodingKeys.self)  
// bar = try container.decode(Int.self, forKey: .bar)  
// try super.init(from: decoder)  
// }  
//  
// override func encode(to encoder: Encoder) throws {  
// var container = encoder.container(keyedBy: CodingKeys.self)  
// try container.encode(bar, forKey: .bar)  
// try super.encode(to: encoder)  
// }  
//  
// enum CodingKeys: String, CodingKey {  
// case bar  
// }  
}

let s = try? JSONDecoder().decode(SuperClass.self, from: "{ "foo": "Hello", "bar": 2 }".data(using: .utf8)!)

String.init(data: try! JSONEncoder().encode(s), encoding: .utf8)

The commented code shows the code that is required to make it work, and it's quite clearly capable of being auto generated by the compiler

is this another half implemented feature and we can expect this to work or is there some obscure reason why automatic conformance doesn't work here, even though it would be useful to have this a default which the developer can implement themselves if needed?

---

<div class="post-metadata">

**Author:** ![Patrick\_Gili](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/patrick_gili/32/6033_2.png) [@Patrick\_Gili](https://forums.swift.org/u/Patrick_Gili)\
**Post date:** [July 31, 2018, 2:21pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/2 "2018-07-31T14:21:10Z")

</div>

The compiler is telling `SuperClass` has no initializer, because `SuperClass` has no initializer. Either define an initializer or give `bar` a default value.

In addition, `SuperClass` needs to conform to `Codable`. It doesn't automatically conform because `BaseClass` conforms.

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [July 31, 2018, 3:15pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/3 "2018-07-31T15:15:37Z")

</div>

> [@Patrick\_Gili](#):
>
> In addition, `SuperClass` needs to conform to `Codable`. It doesn't automatically conform because `BaseClass` conforms.

This is not true here — any class which inherits from a class that adopts a protocol inherits that protocol conformance; that inheritance may conflict with other requirements on the class, though. This is actually exactly what leads to this behavior: `SuperClass` inherits `BaseClass`’s `Codable` implementation directly as it cannot yet synthesize its own.

In any inheritance situation, if a subclass adds new properties which do not have default values, it cannot inherit its superclass’s initializers since those would not initialize said properties. One would need to add an initializer which explicitly initializes `SuperClass.bar`, i.e., `init(from:)`.

Essentially the following is happening:

```swift
class Foo { var a: Int; init() { a = 3 } }
class Bar : Foo { var b: String } // Class ‘Bar’ has no initializers

```

The reason the compiler cannot synthesize an implementation on behalf of `SuperClass` is mostly due to two things:

1. Some amount of implementation detail (which is not a good answer)

2. There’s currently no way to indicate in any given class whether a subclass wants to inherit or re-synthesize conformance. This is a somewhat unique situation: in traditional inheritance, there are only two options — either you provide an overridden implementation of a method, or you don’t. Synthesis adds a third option in allowing neither you nor your superclass to provide that code. We would need new syntax to explicitly specify that you’d like to synthesize over the other two options, since doing nothing already indicates “inherit”.

There’s some amount of design work that needs to happen here that we plan on doing.

(See also [SR-4772](https://bugs.swift.org/browse/SR-4772) and [SR-7210](https://bugs.swift.org/browse/SR-7210))

---

<div class="post-metadata">

**Author:** ![Jon889](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon889/32/3139_2.png) [@Jon889](https://forums.swift.org/u/Jon889)\
**Post date:** [July 31, 2018, 4:00pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/4 "2018-07-31T16:00:05Z")

</div>

At least with Decodable, there is no option of choosing to inherit the implementation as you can't inherit initialisers like that.

Tbh, I think the whole auto synthesised conformance system is ugly. I'm surprised it was allowed to be implemented based on some of the other things that have been refused based on them not being "swifty" enough. Also the fact that gyb.py needs to be used anywhere (not just for Codable), and that synthesised conformance has to be implemented in the compiler shows that Swift is not as capable as we need it to be.

1. Developers should be able to create protocols that have synthesised conformance, not just people who maintain the compiler.

2. it should be obvious which protocols synthesise conformance. eg `class Foo : @synthesize Codable { }` in the same manner of `@autoclosure`. This would also mean that leaving off that attribute requires you to implement it yourself, solving this problem.

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [July 31, 2018, 4:13pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/5 "2018-07-31T16:13:56Z")

</div>

> [@Jon889](#):
>
> At least with Decodable, there is no option of choosing to inherit the implementation as you can't inherit initialisers like that.

What do you mean? Inheritance is the only option here — synthesis does not happen for subclasses, which is the issue. Or am I misunderstanding the assertion?

> [@Jon889](#):
>
> \<snip\> ... synthesised conformance has to be implemented in the compiler shows that Swift is not as capable as we need it to be.
> 
> 1. Developers should be able to create protocols that have synthesised conformance, not just people who maintain the compiler.

This is a non-trivial addition and change to the language, though one that I would readily welcome! There are languages which do offer the power to modify the AST at compile-time in userland code (e.g. [Rust](https://www.rust-lang.org) and [Nim](https://nim-lang.org)), which would be great. Getting to the point where we could offer that with a syntax that's easy to express and understand... is something else altogether.

Hygienic macros are on the roadmap for Swift eventually, and there has been a lot of discussion around them and the need for them, but we're not there yet.

> [@Jon889](#):
>
> 1. it should be obvious which protocols synthesise conformance. eg `class Foo : @synthesized Codable { }` in the same manner of `@autoclosure`. This would also mean that leaving off that attribute requires you to implement it yourself, solving this problem.

This is indeed one solution to the problem. Until now we've approached synthesis as something implicit and automatic, but it's not necessarily too late to change. Rust, for instance, has `#[derive(...)]` to request and indicate synthesis, and that's one route we could go down too.

One difficulty here is source compatibility — a lot of code out there already requires this implicit synthesis, and we'd need a migration strategy to bring all of that code forward. You could imagine, for instance, that Swift 6 would start warning and providing fix-its on implicit synthesis, and Swift 7/8 would require explicit synthesis.

[As an aside, there are other forms of synthesis in the compiler which are not so clear; for instance, the compiler has long synthesized `RawRepresentable` conformance on `enum`s which are backed by primitive types even if those types didn't request to be `RawRepresentable`, and this is something that I think we'd like to keep indefinitely.]

If this is something that we view is the better way forward, then a pitch and gathering ideas around this would be an excellent start.

---

<div class="post-metadata">

**Author:** ![Jon889](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon889/32/3139_2.png) [@Jon889](https://forums.swift.org/u/Jon889)\
**Post date:** [July 31, 2018, 4:35pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/6 "2018-07-31T16:35:15Z")

</div>

> [@"itaiferber](#):
>
> What do you mean? Inheritance is the only option here — synthesis does not happen for subclasses, which is the issue. Or am I misunderstanding the assertion?

You said there were 3 options, inherit, provide an implementation, or synthesis. But for Decodable which is a initialiser, there are only two options provide an implementation or sythesis as you can't inherit the implementation of initialisers. (though this isn't really relevant to the larger topic as it's specific to Decodable)

> [@"itaiferber](#):
>
> This is a non-trivial addition and change to the language, though one that I would readily welcome! There are languages which do offer the power to modify the AST at compile-time in userland code (e.g. [Rust](https://www.rust-lang.org) and [Nim](https://nim-lang.org)), which would be great. Getting to the point where we could offer that with a syntax that's easy to express and understand... is something else altogether.
> 
> Hygienic macros are on the roadmap for Swift eventually, and there has been a lot of discussion around them and the need for them, but we're not there yet.

I think it would be great to be able to go all the way and say download a file (eg swagger file), or load a file like a graphql query, and generate an swift API from it, all from within Swift using the APIs (to download and load files) that swift developers already know and use. Even just a swift version of gyb.py with built in support in the compiler (eg .tswift files are found by the compiler and internally run through the equivalent of gyb) would work.

> [@"itaiferber](#):
>
> One difficulty here is source compatibility — a lot of code out there already requires this implicit synthesis, and we'd need a migration strategy to bring all of that code forward. You could imagine, for instance, that Swift 6 would start warning and providing fix-its on implicit synthesis, and Swift 7/8 would require explicit synthesis.

The same migration strategy as the @escaping for closure parameters would work here I think.

> [@"itaiferber](#):
>
> [As an aside, there are other forms of synthesis in the compiler which are not so clear; for instance, the compiler has long synthesized `RawRepresentable` conformance on `enum`s which are backed by primitive types even if those types didn't request to be `RawRepresentable`, and this is something that I think we'd like to keep indefinitely.]

I think primitives are enough of a special case already, and this wouldn't have to be perfectly uniform there are edge cases to everything.

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [July 31, 2018, 5:13pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/7 "2018-07-31T17:13:42Z")

</div>

> [@Jon889](#):
>
> You said there were 3 options, inherit, provide an implementation, or synthesis. But for Decodable which is a initialiser, there are only two options provide an implementation or sythesis as you can't inherit the implementation of initialisers. (though this isn't really relevant to the larger topic as it's specific to Decodable)

This is not true — classes can definitely inherit initializers. See [the "Automatic Initializer Inheritance" section from the Swift language guide](https://docs.swift.org/swift-book/LanguageGuide/Initialization.html#ID222) for more info on that. To clarify this case specifically here:

- For a base class conforming to `Decodable` (e.g. your `BaseClass`), you have two options: manually implement `Decodable`, or allow the compiler to synthesize it for you, if possible
- For a class adopting `Decodable` inheriting from a class which does not (e.g. `Bar` in `class Foo {} class Bar : Foo, Decodable {}`) you have the same two options: manually implement `Decodable`, or allow the compiler to synthesize
- For a subclass of a class already adopting `Decodable` (e.g. your `SuperClass`), you have to options: override your superclass's implementation by offering your own, or inheriting it, if possible. There is no way for the compiler to synthesize an implementation here for you

To show off this last case, let's implement `BaseClass` and `SuperClass` manually with the same code that we'd expect compiler to otherwise generate:

```swift
import Foundation

class BaseClass : Decodable {
    var foo: String
    init(foo: String) { self.foo = foo }

    private enum CodingKeys: String, CodingKey {
        case foo
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        foo = try container.decode(String.self, forKey: .foo)
    }
}

class SuperClass : BaseClass {
    var bar: Int
    init(foo: String, bar: Int) {
        self.bar = bar
        super.init(foo: foo)
    }

    private enum CodingKeys: String, CodingKey {
        case bar
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        bar = try container.decode(Int.self, forKey: .bar)
        try super.init(from: container.superDecoder())
    }
}

let decoder = JSONDecoder()
let json = """
{
    "bar": 42,
    "super": { "foo": "Hello, world!" }
}
""".data(using: .utf8)!

let superClass = try! decoder.decode(SuperClass.self, from: json)
print(superClass.foo, superClass.bar) // Hello, world! 42

```

This prints out "Hello, world! 42", as we might expect. Now, let's try removing `BaseClass.init(from:)` to allow the compiler to synthesize the implementation:

```swift
class BaseClass : Decodable {
    var foo: String
    init(foo: String) { self.foo = foo }
}

// ...

print(superClass.foo, superClass.bar) // => Hello, world! 42

```

So far, no change in behavior — great! Now, let's try the same with `SuperClass`:

```swift
class BaseClass : Decodable {
    var foo: String
    init(foo: String) { self.foo = foo }
}

class SuperClass : BaseClass {
    var bar: Int
    init(foo: String, bar: Int) {
        self.bar = bar
        super.init(foo: foo)
    }
}

// ...

```

This time, we get

```swift
error: 'required' initializer 'init(from:)' must be provided by subclass of 'BaseClass'
}
^
<unknown>:0: note: 'required' initializer is declared in superclass here

```

This is the error message you get when you need to provide an implementation for a `required` initializer but have provided a different initializer, and new requirements on the class prevent inheritance. For instance:

```swift
class BaseClass {
    required init() {} // note: 'required' initializer is declared in superclass here
}

class SuperClass : BaseClass {
    var foo: Int
    init(foo: Int) { self.foo = foo }
} // error: 'required' initializer 'init()' must be provided by subclass of 'BaseClass'

```

If `SuperClass` didn't provide its own `init(foo:)` you'd get a different error message saying it has no initializers (your original error message above). In any case, we can get around this by providing `foo` with a default value instead of assigning in an `init`:

```swift
class BaseClass {
    required init() {}
}

class SuperClass : BaseClass {
    var foo: Int = 3
}

```

This allows inheritance of `required init()` while still initializing `SuperClass.foo`. Let's apply that to our situation as well:

```swift
class BaseClass : Decodable {
    var foo: String = "This is some default"
}

class SuperClass : BaseClass {
    var bar: Int = 3
}

// ...

```

This compiles just fine — but, does `SuperClass` here get its own `init(from:)`, or is it inheriting `BaseClass.init(from:)`? If we try with the same JSON payload, we get the following error:

```swift
Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "foo", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"foo\", intValue: nil) (\"foo\").", underlyingError: nil))

```

This error boils down to: "we tried to find `"foo"` as a key in the root dictionary (`codingPath` is empty), but failed to find it". Which is true, because the JSON payload we're using has `foo` nested:

```swift
{
    "bar": 42,
    "super": { "foo": "Hello, world!" }
}

```

For the sake of the test, let's un-nest to see what happens:

```swift
let json = """
{
    "bar": 42,
    "foo": "Hello, world!"
}
""".data(using: .utf8)!

let superClass = try! decoder.decode(SuperClass.self, from: json)
print(superClass.foo, superClass.bar) // Hello, world! 3

```

We're now getting `bar`'s default value rather than the value in the JSON — that's because `SuperClass` has inherited `BaseClass.init(from:)` directly, and `BaseClass.init(from:)` has no knowledge of `bar`; `SuperClass` has to then use `bar`'s default value.

If, by the way, we tried to remove the default value from `bar`, we'd see the following errors:

```swift
error: class 'SuperClass' has no initializers
class SuperClass : BaseClass {
      ^
note: did you mean to override 'init(from:)'?
class SuperClass : BaseClass {
      ^
note: stored property 'bar' without initial value prevents synthesized initializers
    var bar: Int
        ^
                 = 0

```

That first note is the relevant one: we can't inherit `init(from:)` so we would otherwise need to override it. (The "synthesized initializers" note refers only to synthesizing a default constructor of `init()`, not `init(from:)`.

* * *

This case would be improved if the compiler _could_ synthesize `SuperClass.init(from:)` instead of inheriting, but it won't be able to without a refactor of Swift's protocol conformance and inheritance system (and without syntax to disambiguate between "I'm not providing an implementation because I'd like to inherit" vs. "I'm not providing an implementation because I'd like to synthesize")

---

<div class="post-metadata">

**Author:** ![Patrick\_Gili](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/patrick_gili/32/6033_2.png) [@Patrick\_Gili](https://forums.swift.org/u/Patrick_Gili)\
**Post date:** [July 31, 2018, 7:16pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/9 "2018-07-31T19:16:31Z")

</div>

This better explains the behavior I've observed. Given the behavior, I assumed that protocol conformance isn't inherited, but now that I think about it, the sub-class inherits the implementation that supports conformance and hence it must also conform. However, it doesn't, and you have explained this in a later post. Thank you.

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [July 31, 2018, 7:28pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/10 "2018-07-31T19:28:46Z")

</div>

Yep! Happy to have helped clarify. To thoroughly cover the other possible combinations too:

- If a class re-declares conformance that the parent class already declares, you'll currently get errors:

- If a class inherits from a non-`Codable` class, you'll synthesize conformance in the subclass:

---

<div class="post-metadata">

**Author:** ![Patrick\_Gili](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/patrick_gili/32/6033_2.png) [@Patrick\_Gili](https://forums.swift.org/u/Patrick_Gili)\
**Post date:** [July 31, 2018, 8:01pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/11 "2018-07-31T20:01:31Z")

</div>

I've been playing with this to clarify my understanding. The last combination does result in synthesized conformation, but only for the sub-class. For example:

```
class A {
    var a1: Int
    
    init() {
        a1 = 10
    }
}

class B: A, Codable {
    var b1: Int
    
    override init() {
        b1 = 20
        super.init()
     }

}

let b = B()

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted

let data = try encoder.encode(b)
print(String(data: data, encoding: .utf8))

```

This code prints to the console:

```
Optional("{\n \"b1\" : 20\n}")

```

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [July 31, 2018, 8:03pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/12 "2018-07-31T20:03:08Z")

</div>

Yes, that's correct — see my second bullet point above. In this case, `A` itself isn't `Codable`, so there's no `init(from:)` to inherit. From a synthesis perspective, `A` may as well not exist, save for the properties which `B` inherits from it.

Slightly more formally: during type checking, the compiler encounters `B`, which claims to conform to `Codable`. When type checking this conformance, the compiler looks through all of the requirements that `Codable` (`Encodable` and `Decodable`) imposes; for each of those requirements, the type checker looks through `B` for a match.

Matches can be found by being inherited from the superclass, or by an explicit member on the type itself (i.e. if `B` implemented `init(from:)` itself). If no match is found, some protocols like `Encodable` and `Decodable` can get synthesized members which satisfy those requirements.

In the case of `B` here, because it doesn't inherit `init(from:)` from `A` to satisfy the requirement, and doesn't supply its own, it gets a synthesized implementation. (This is as opposed to a class like `BaseClass`, whose match is found by directly inheriting it from the superclass. This is why synthesis currently does not happen: the inherited match is necessarily preferred over synthesizing a new one.)

---

<div class="post-metadata">

**Author:** ![sloanseven](https://avatars.discourse-cdn.com/v4/letter/s/94ad74/32.png) [@sloanseven](https://forums.swift.org/u/sloanseven)\
**Post date:** [August 5, 2018, 10:57pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/13 "2018-08-05T22:57:04Z")

</div>

Similar question,

class Foo { //}: Codable {

}

class Bar : Foo {  
func c() -\> Int {  
return 2;  
}  
}

let x = Bar()  
let y = x.c() // \<-throws bad\_exc when codable is uncommented

What am I missing?

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [August 7, 2018, 7:15pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/14 "2018-08-07T19:15:44Z")

</div>

What version of Swift (and Xcode) are you using? Sounds like this could be [SR-6468](https://bugs.swift.org/browse/SR-6468) which was fixed a little while back. I'm not seeing it on the latest beta.

---

<div class="post-metadata">

**Author:** ![sloanseven](https://avatars.discourse-cdn.com/v4/letter/s/94ad74/32.png) [@sloanseven](https://forums.swift.org/u/sloanseven)\
**Post date:** [August 8, 2018, 2:12am UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/15 "2018-08-08T02:12:29Z")

</div>

Swift 4.1

works if i move the function to the base class

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [August 8, 2018, 2:22am UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/16 "2018-08-08T02:22:51Z")

</div>

Sounds like the issue above, then, which is resolved for Swift 4.2

---

<div class="post-metadata">

**Author:** ![xsada](https://avatars.discourse-cdn.com/v4/letter/x/3be4f8/32.png) [@xsada](https://forums.swift.org/u/xsada)\
**Post date:** [December 16, 2019, 1:44pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/17 "2019-12-16T13:44:05Z")

</div>

This line code gives me error  
try super.init(from: container.superDecoder())  
It should be  
try super.init(from: decoder)

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [December 16, 2019, 2:11pm UTC](https://forums.swift.org/t/inheriting-from-a-codable-class/14874/18 "2019-12-16T14:11:24Z")

</div>

What is the error you're seeing? If you're using a `KeyedDecodingContainer` (i.e., you called `decoder.container(keyedBy: ...)` and are using that container), the `.superDecoder()` call will need to be `.superDecoder(forKey: ...)`. [Unless you have specific format requirements and know what you're doing, it's relatively rare to need to pass your own `decoder` into `super.init(from:)`]
