I want to generate Codable implementation

This template generates Codable implementation for structs that implement AutoCodable, AutoDecodable or AutoEncodable protocols. You should define these protocols as follows:

protocol AutoDecodable: Decodable {}
protocol AutoEncodable: Encodable {}
protocol AutoCodable: AutoDecodable, AutoEncodable {}

Swift template

Generating coding keys.

If you have few keys that are not matching default key strategy you have to specify only these keys, all other keys will be generated and inlined by the template:

struct Person: AutoDecodable {
    let id: String
    let firstName: Bool
    let surname: String

    enum CodingKeys: String, CodingKey {
        // this is the custom key that you define manually
        case firstName = "first_name"

// sourcery:inline:auto:Person.CodingKeys.AutoCodable
        // the rest is generated by the template
        case id
        case surname
// sourcery:end
    }

}

Computed properties are not encoded by default, but if you define a coding key for computed property, template will generate code that will encode it.

If you don’t define any keys manually the template will generate CodingKeys enum with the keys for all stored properties, but only if custom implementation of init(from:) or encode(to:) is needed.

Generating init(from:) constructor.

Template will generate implementation of init(from:) when needed. You can define additional methods and properties on your type to be used to decode it.

  • method to get decoding container. This is useful if your type needs to be decoded from a nested key(s):
struct MyStruct: AutoDecodable {
    let value: Int

    enum CodingKeys: String, CodingKey {
        case nested
        case value
    }

    static func decodingContainer(_ decoder: Decoder) throws -> KeyedDecodingContainer<CodingKeys> {
        return try decoder.container(keyedBy: CodingKeys.self)
            .nestedContainer(keyedBy: CodingKeys.self, forKey: .nested)
    }
}
  • method to decode a property. This is useful if you need to decode some property manually:
struct MyStruct: AutoDecodable {
    let myProperty: Int

    static func decodeMyProperty(from container: KeyedDecodingContainer<CodingKeys>) -> Int? {
        return (try? container.decode(String.self, forKey: .myProperty)).flatMap(Int.init)
    }
    //or
    static func decodeMyProperty(from decoder: Decoder) throws -> Int {
        return try decoder.container(keyedBy: CodingKeys.self)
            .decode(Int.self, forKey: .myProperty)
    }
}

These methods can throw or not and can return optional or non-optional result.

  • default property value. You can define a static variable that will be used as a default value of a property if decoding results in nil value:
struct MyStruct: AutoDecodable {
    let myProperty: Int

    static let defaultMyProperty: Int = 0
}

Generating encode(to:) method.

Template will generate implementation of encode(to:) method when needed. You can define additional methods to be used to encode it.

  • method to get encoding container. This is useful if your type needs to be encoded into a nested key(s):
struct MyStruct: AutoDecodable {
    let value: Int

    enum CodingKeys: String, CodingKey {
        case nested
        case value
    }

    func encodingContainer(_ encoder: Encoder) -> KeyedEncodingContainer<CodingKeys> {
        var container = encoder.container(keyedBy: CodingKeys.self)
        return container.nestedContainer(keyedBy: CodingKeys.self, forKey: .nested)
    }
}
  • method to encode a property. This is useful when you need to manually encode a property:
struct MyStruct: AutoDecodable {
    let myProperty: Int

    func encodeMyProperty(to container: inout KeyedEncodingContainer<CodingKeys>) {
        try? container.decode(String(myProperty), forKey: .myProperty)
    }
    //or
    func encodeMyProperty(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(String(myProperty), forKey: .myProperty)
    }
}

These methods may throw or not.

If you need to manually encode computed property and you have defined custom encoding method for it, template will generate a coding key for it too, so you don’t have to define it manually (though you may still need to define it if it needs custom raw value).

  • method to encode any additional values. This is useful when you need to encode computed properties or constant values:
struct MyStruct: AutoDecodable {

    func encodeAdditionalValues(to container: inout KeyedEncodingContainer<CodingKeys>) throws {
        ...
    }
    // or
    func encodeAdditionalValues(to encoder: Encoder) throws {
        ...
    }
}

This method will be called in the end of generated encoding method.

  • enum SkipEncodingKeys for keys to be skipped during encoding. This is useful when you have stored properties that you don’t want to encode, i.e. constants:
  struct MyStruct: AutoCodable {
      let value: Int
      let skipValue: Int

      enum SkipEncodingKeys {
          case skipValue
      }
  }

Codable enums

Enums with numeric or string raw values are Codable by default. For enums with no raw value or with associated values template will generate Codable implementation.

Enums with no raw values and no associated values

For such enums template will generate decoding/encoding code that will expect values in JSON to be exactly the same as cases’ names.

enum SimpleEnum: AutoDecodable {
  case someCase
  case anotherCase
}

For such enum template will generate code that will successfully decode from/encode to JSON of following form:

{
  "value": "someCase"
  "anotherValue": "anotherCase"
}

You can define coding keys to change the values:

enum SimpleEnum: AutoDecodable {
  case someCase
  case anotherCase

  enum CodingKeys: String, CodingKey {
    case someCase = "some_case"
    case anotherCase = "another_case"
  }
}

Enums with assoicated values

Template supports two different representations of such enums in JSON format.

enum SimpleEnum: AutoDecodable {
  case someCase(id: Int, name: String)
  case anotherCase
}

If you define a coding key named enumCaseKey then the template will generate code that will encode/decode enum in/from following format:

{
  "type": "someCase" // enum case is encoded in a special key
  "id": 1,
  "name": "John"
}

All enum cases associated values must be named.

If you don’t define enumCaseKey then the template will generate code that will encode/decode enum in/from following format:

{
  "someCase": {
    "id": 1,
    "name": "John"
  }
}

Associated values of each enum case must be either all named or all unnamed. For cases with unnamed associated values JSON format will use array instead of dictionary for associated values, in the same order in which they are defined:

{
  "someCase": [
    1,
    "Jhon"
  ]
}

You can use all other customisation methods described for structs to decode/encode enum case associated values individually.