Codable, but with Super power made custom Codable behavior easy.

What's New

Can Codable with optional by @OptionalKeyed

- @Keyed var id: String?
+@OptionalKeyed var id: String?

Please note Keyed var _: TYPE? will make a runtime error to tell you the disability on optional.


From Foundation

struct AStudent: Codable {
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.aID = try container.decode(String.self, forKey: .aID)
        self.aName = try container.decode(String.self, forKey: .aName)
        let gradeDecoded = try container.decode(Double.self, forKey: .aGrade)
        self.AGrede = Int(gradeDecoded)

    enum CodingKeys: String, CodingKey {
        case aName = "name"
        case aGrade = "grade"
        case aID = "id"

    var aID: String
    var aName: String
    var AGrede: Int

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(aID, forKey: .aID)
        try container.encode(Double(AGrede), forKey: .aGrade)
        try container.encode(aName, forKey: .aName)

To SuperCodable

struct Student: SuperCodable {
    var id: String
    var aName: String
    @KeyedTransform("grade", doubleTransform)
    var AGrade: Int

let doubleTransform = SCTransformOf<Int, Double> {
    (double) -> Int in
} toEncoder: { (int) -> Double in


  • Working with Nested Foundation.Codable property

Known side effect

  • SuperDecoable must construct from nothing init()
  • @Keyed var id:Int will do O(n) calculation on underlaying wrapper _VARIABLE_NAME into key VARIABLE_NAME. Be ware of variable name takes too long

Known Disability

  • Every property in a SuperCodable should a DecodableKey / EncodableKey, otherwise the property(which should be Codable) will simply ignored during the Codable process.


Basically Mirror can't mutating the object value during the init(from decoder:) throws, since we create the object from self.init()

Other notes

  • Inspired by:

  • Try to merge @KeyedTransform into @Keyed, but it required @Keyed var id: String to be @Keyed() var id: String, with extra () 🧐

  • Swift should auto generate STRUCT.init(....) for you, but if you using @Keyed var id: String without default value, it will generate init(id: Keyed<String>), by giving default value @Keyed var id: String = "" should solve this problem.

Know Issues

  • @Keyed var id:String? will cause fatalError on force unwrapping Keyed.value?, you can using @OptionalKeyed to make it works.
  • OptionalKeyed may / may not a good name, I am thinking of make the easy to change, maybe KeyedOptional is EASY change? 🤔


  • Swift Tools 5.3.0
View More Packages from this Author


  • None
Last updated: Fri Dec 02 2022 15:10:18 GMT-0500 (GMT-05:00)