# Introducing MetaCodable: A Collection of Macros helping with custom Codable implementation generation

**URL:** <https://forums.swift.org/t/introducing-metacodable-a-collection-of-macros-helping-with-custom-codable-implementation-generation/65731>\
**Category:** Community Showcase\
**Tags:** codable, macros, network, attached-macros, swift59\
**Created:** [June 21, 2023, 12:26pm UTC](https://forums.swift.org/t/introducing-metacodable-a-collection-of-macros-helping-with-custom-codable-implementation-generation/65731 "2023-06-21T12:26:00Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![soumyamahunt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/soumyamahunt/32/23427_2.png) [@soumyamahunt](https://forums.swift.org/u/soumyamahunt)\
**Post date:** [June 21, 2023, 12:26pm UTC](https://forums.swift.org/t/introducing-metacodable-a-collection-of-macros-helping-with-custom-codable-implementation-generation/65731/1 "2023-06-21T12:26:00Z")

</div>

Hey everyone!

I'm excited to introduce my latest project, MetaCodable, a powerful macro library that will help you with all your `Codable` needs. Using MetaCodable, you can get rid of repetitive boilerplate code that you often have to write. Some of the feature it provides:

> **Custom \`CodingKey\` value declaration per variable, instead of requiring you to write for all fields.**
>
> i.e. in the official [docs](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types#2904057), to define custom `CodingKey` for 2 fields of `Landmark` type you had to write:
> 
> ```swift
> struct Landmark: Codable {
> var name: String
> var foundingYear: Int
> var location: Coordinate
> var vantagePoints: [Coordinate]
>     
> enum CodingKeys: String, CodingKey {
> case name = "title"
> case foundingYear = "founding_date"
>         
> case location
> case vantagePoints
> }
> }
> 
> ```
> 
> But with MetaCodable all you have to write is this:
> 
> ```swift
> @Codable
> struct Landmark {
> @CodablePath("title")
> var name: String
> @CodablePath("founding_date")
> var foundingYear: Int
> 
> var location: Coordinate
> var vantagePoints: [Coordinate]
> }
> 
> ```

> **Create flattened model for nested \`CodingKey\` values.**
>
> i.e. in official [docs](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types#2904058) to decode a JSON like this:
> 
> ```json
> {
> "latitude": 0,
> "longitude": 0,
> "additionalInfo": {
> "elevation": 0
> }
> }
> 
> ```
> 
> You had to write all these boilerplate:
> 
> ```swift
> struct Coordinate {
> var latitude: Double
> var longitude: Double
> var elevation: Double
> 
> enum CodingKeys: String, CodingKey {
> case latitude
> case longitude
> case additionalInfo
> }
> 
> enum AdditionalInfoKeys: String, CodingKey {
> case elevation
> }
> }
> 
> extension Coordinate: Decodable {
> init(from decoder: Decoder) throws {
> let values = try decoder.container(keyedBy: CodingKeys.self)
> latitude = try values.decode(Double.self, forKey: .latitude)
> longitude = try values.decode(Double.self, forKey: .longitude)
>     
> let additionalInfo = try values.nestedContainer(keyedBy: AdditionalInfoKeys.self, forKey: .additionalInfo)
> elevation = try additionalInfo.decode(Double.self, forKey: .elevation)
> }
> }
> 
> extension Coordinate: Encodable {
> func encode(to encoder: Encoder) throws {
> var container = encoder.container(keyedBy: CodingKeys.self)
> try container.encode(latitude, forKey: .latitude)
> try container.encode(longitude, forKey: .longitude)
>     
> var additionalInfo = container.nestedContainer(keyedBy: AdditionalInfoKeys.self, forKey: .additionalInfo)
> try additionalInfo.encode(elevation, forKey: .elevation)
> }
> }
> 
> ```
> 
> But with MetaCodable all you have to write is this:
> 
> ```swift
> @Codable
> struct Coordinate {
> var latitude: Double
> var longitude: Double
>     
> @CodablePath("additionalInfo", "elevation")
> var elevation: Double
> }
> 
> ```

> **Provide default value in case of decoding failures and member-wise initializer generated considers these default values.**
>
> Instead of throwing error in case of missing data or type mismatch, you can provide a default value that will be assigned in this case. The memberwise initializer generated also uses this default value for the field. The following definition with MetaCodable:
> 
> ```swift
> @Codable
> struct CodableData {
> @CodablePath(default: "some")
> let field: String
> }
> 
> ```
> 
> will not throw any error when empty JSON(`{}`) or JSON with type mismatch(`{ "field": 5 }`) is provided. The default value will be assigned in such case. Also, the memberwise initializer generated will look like this:
> 
> ```swift
> init(field: String = "some") {
> self.field = field
> }
> 
> ```

Besides these features you can create **custom types with your own decoding/encoding strategies** and pass those to be used by macros. I hope you find MetaCodable useful. Let me know if you have any suggestions or additional feature request.

Happy coding!

> **[GitHub - SwiftyLab/MetaCodable: Supercharge Swift's Codable implementations...](https://github.com/SwiftyLab/MetaCodable)**
>
> Supercharge Swift's Codable implementations with macros meta-programming. - GitHub - SwiftyLab/MetaCodable: Supercharge Swift's Codable implementations with macros meta-programming.

[https://swiftylab.github.io/MetaCodable/documentation/metacodable](https://swiftylab.github.io/MetaCodable/documentation/metacodable)

---

<div class="post-metadata">

**Author:** ![momo](https://avatars.discourse-cdn.com/v4/letter/m/f4b2a3/32.png) [@momo](https://forums.swift.org/u/momo)\
**Post date:** [July 14, 2023, 8:20pm UTC](https://forums.swift.org/t/introducing-metacodable-a-collection-of-macros-helping-with-custom-codable-implementation-generation/65731/2 "2023-07-14T20:20:43Z")

</div>

This looks fantastic.

---

<div class="post-metadata">

**Author:** ![soumyamahunt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/soumyamahunt/32/23427_2.png) [@soumyamahunt](https://forums.swift.org/u/soumyamahunt)\
**Post date:** [July 18, 2023, 4:05pm UTC](https://forums.swift.org/t/introducing-metacodable-a-collection-of-macros-helping-with-custom-codable-implementation-generation/65731/3 "2023-07-18T16:05:14Z")

</div>

Hey everyone!

I am modifying the macro names and syntax for better readability, please see the full discussion and provide your feedback: [Suggest upcoming change to macro syntax · SwiftyLab/MetaCodable · Discussion #13 · GitHub](https://github.com/SwiftyLab/MetaCodable/discussions/13)

---

<div class="post-metadata">

**Author:** ![soumyamahunt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/soumyamahunt/32/23427_2.png) [@soumyamahunt](https://forums.swift.org/u/soumyamahunt)\
**Post date:** [November 7, 2023, 1:55pm UTC](https://forums.swift.org/t/introducing-metacodable-a-collection-of-macros-helping-with-custom-codable-implementation-generation/65731/4 "2023-11-07T13:55:25Z")

</div>

Hey everyone!

Just released [v1.1.0](https://github.com/SwiftyLab/MetaCodable/releases/tag/v1.1.0). This version includes some bug fixes and following major features:

- Support for generic struct types conformance generation.
- A new [`HelperCoders`](https://swiftpackageindex.com/SwiftyLab/MetaCodable/main/documentation/helpercoders) module with common custom decoding/encoding helpers, i.e. decoding with cudtom date and data formats, basic data types represented in other types etc.

For future version I am planning to add enum support and need your opinions to shape the design. Please feel free to chime in [this discussion](https://github.com/SwiftyLab/MetaCodable/discussions/31) about how you are using enums currently.

---

<div class="post-metadata">

**Author:** ![Sajjon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sajjon/32/12044_2.png) [@Sajjon](https://forums.swift.org/u/Sajjon)\
**Post date:** [November 7, 2023, 2:01pm UTC](https://forums.swift.org/t/introducing-metacodable-a-collection-of-macros-helping-with-custom-codable-implementation-generation/65731/5 "2023-11-07T14:01:35Z")

</div>

Nice! Only Base64 coding? Not hex? Base64 is the default for Data, so a Hex variant is that would benefit the most 😍

---

<div class="post-metadata">

**Author:** ![soumyamahunt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/soumyamahunt/32/23427_2.png) [@soumyamahunt](https://forums.swift.org/u/soumyamahunt)\
**Post date:** [November 8, 2023, 4:13am UTC](https://forums.swift.org/t/introducing-metacodable-a-collection-of-macros-helping-with-custom-codable-implementation-generation/65731/6 "2023-11-08T04:13:16Z")

</div>

I haven't seen hex being used to transfer data over web due to it being less efficient than base64. However, I would love to see some discussions how many users actually use it, PRs are also welcome 🙂

---

<div class="post-metadata">

**Author:** ![Sajjon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sajjon/32/12044_2.png) [@Sajjon](https://forums.swift.org/u/Sajjon)\
**Post date:** [November 8, 2023, 6:59am UTC](https://forums.swift.org/t/introducing-metacodable-a-collection-of-macros-helping-with-custom-codable-implementation-generation/65731/7 "2023-11-08T06:59:31Z")

</div>

The crypto industry uses hex a lot, because it makes it possible to read the data directly, which often is written in hex. I can see that a secp256k1 (bitcoin curve) public key is valid, since on compressed form it should start with 0x03 or 0x02

---

<div class="post-metadata">

**Author:** ![soumyamahunt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/soumyamahunt/32/23427_2.png) [@soumyamahunt](https://forums.swift.org/u/soumyamahunt)\
**Post date:** [January 10, 2024, 5:51am UTC](https://forums.swift.org/t/introducing-metacodable-a-collection-of-macros-helping-with-custom-codable-implementation-generation/65731/8 "2024-01-10T05:51:42Z")

</div>

Hey everyone!

Just released [v1.2.0](https://github.com/SwiftyLab/MetaCodable/releases/tag/v1.2.0) which is packed with features:

- [Support for classes, actors, externally/internally/adjacent tagged enums and protocols. MetaCodable now supports all first class Swift types](https://swiftpackageindex.com/swiftylab/metacodable/v1.2.0/documentation/metacodable).
- [Support for multiple coding key aliases](https://swiftpackageindex.com/swiftylab/metacodable/v1.2.0/documentation/metacodable/codedas(_:_:)#overview).
- [Introduction of a new helper type for sequence decoding and encoding](https://swiftpackageindex.com/swiftylab/metacodable/v1.2.0/documentation/helpercoders/sequencecoder).

and some bug fixes.

With the increase of features I am looking for any feedback and help on improving documentation.
