Add transformers to Codable

Hello everyone,

I’m suggesting to add a new way to encode/decode JSON properties for relevantly complex data formats such as regular expressions, well-known text, hex colours, custom date formats.

The problem:

Image you have a struct called House

struct House {
    let color: UIColor
}

and it has a properly called color and the color represented in JSON as hex value (#ffffff). Currently to make it working you have to extract the underline value (string with a hex value) and then try to make a UIColor from it. It works but it makes you to copy/past a lot of code and it leads to problems. Also it shifts focus from what to decode to how to decode.

The suggested solution:

I suggest that we have to introduce protocols for classes that will encapsulate transformation from a source data type to a destination data type. The source data types are all existing data that support of decoding.

We will provide only protocols (one for decoding and one for encoding) and users will be able to create transformers for their own data types.

The implementation:

The implementation is fairly easy. We only need introduce two protocols (encoding/decoding) and add a method to KeyedEncodingContainerProtocol that will accept a key and a transformer. In the method we will extract source data from JSON and then will ask the transformer to try to convert it to the desire data type.

Example of the decoding protocol:

protocol DecodingTransformer {
    associatedtype Input: Decodable
    associatedtype Output
    func transform(_ decoded: Input) throws -> Output
}

Inspired by: GitHub - tristanhimmelman/ObjectMapper: Simple JSON Object mapping written in Swift

Cheers,
Arsen

1 Like

For me definitely +1 as it's getting near to what I need to call the Decoding usable.

···

On Dec 18, 2017, at 5:51 PM, Arsen Gasparyan via swift-evolution <swift-evolution@swift.org> wrote:

Hello everyone,

I’m suggesting to add a new way to encode/decode JSON properties for relevantly complex data formats such as regular expressions, well-known text, hex colours, custom date formats.

The problem:

Image you have a struct called House

struct House {
    let color: UIColor
}

and it has a properly called color and the color represented in JSON as hex value (#ffffff). Currently to make it working you have to extract the underline value (string with a hex value) and then try to make a UIColor from it. It works but it makes you to copy/past a lot of code and it leads to problems. Also it shifts focus from what to decode to how to decode.

The suggested solution:

I suggest that we have to introduce protocols for classes that will encapsulate transformation from a source data type to a destination data type. The source data types are all existing data that support of decoding.

We will provide only protocols (one for decoding and one for encoding) and users will be able to create transformers for their own data types.

The implementation:

The implementation is fairly easy. We only need introduce two protocols (encoding/decoding) and add a method to KeyedEncodingContainerProtocol that will accept a key and a transformer. In the method we will extract source data from JSON and then will ask the transformer to try to convert it to the desire data type.

Example of the decoding protocol:

protocol DecodingTransformer {
    associatedtype Input: Decodable
    associatedtype Output
    func transform(_ decoded: Input) throws -> Output
}

Inspired by: GitHub - tristanhimmelman/ObjectMapper: Simple JSON Object mapping written in Swift

Cheers,
Arsen
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Hi Arsen,

What’s the difference between providing a method that takes a transformable object on the keyed container protocol and just transforming it yourself before you encode it?

- Tony

···

On Dec 18, 2017, at 8:51 AM, Arsen Gasparyan via swift-evolution <swift-evolution@swift.org> wrote:

Hello everyone,

I’m suggesting to add a new way to encode/decode JSON properties for relevantly complex data formats such as regular expressions, well-known text, hex colours, custom date formats.

The problem:

Image you have a struct called House

struct House {
    let color: UIColor
}

and it has a properly called color and the color represented in JSON as hex value (#ffffff). Currently to make it working you have to extract the underline value (string with a hex value) and then try to make a UIColor from it. It works but it makes you to copy/past a lot of code and it leads to problems. Also it shifts focus from what to decode to how to decode.

The suggested solution:

I suggest that we have to introduce protocols for classes that will encapsulate transformation from a source data type to a destination data type. The source data types are all existing data that support of decoding.

We will provide only protocols (one for decoding and one for encoding) and users will be able to create transformers for their own data types.

The implementation:

The implementation is fairly easy. We only need introduce two protocols (encoding/decoding) and add a method to KeyedEncodingContainerProtocol that will accept a key and a transformer. In the method we will extract source data from JSON and then will ask the transformer to try to convert it to the desire data type.

Example of the decoding protocol:

protocol DecodingTransformer {
    associatedtype Input: Decodable
    associatedtype Output
    func transform(_ decoded: Input) throws -> Output
}

Inspired by: GitHub - tristanhimmelman/ObjectMapper: Simple JSON Object mapping written in Swift

Cheers,
Arsen
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

1 Like

+1 this is missing functionality at the moment and what still puts tools like Mantle ahead.

···

Sent from my iPhone

On 19 Dec 2017, at 04:18, Charlie Monroe via swift-evolution <swift-evolution@swift.org> wrote:

For me definitely +1 as it's getting near to what I need to call the Decoding usable.

On Dec 18, 2017, at 5:51 PM, Arsen Gasparyan via swift-evolution <swift-evolution@swift.org> wrote:

Hello everyone,

I’m suggesting to add a new way to encode/decode JSON properties for relevantly complex data formats such as regular expressions, well-known text, hex colours, custom date formats.

The problem:

Image you have a struct called House

struct House {
    let color: UIColor
}

and it has a properly called color and the color represented in JSON as hex value (#ffffff). Currently to make it working you have to extract the underline value (string with a hex value) and then try to make a UIColor from it. It works but it makes you to copy/past a lot of code and it leads to problems. Also it shifts focus from what to decode to how to decode.

The suggested solution:

I suggest that we have to introduce protocols for classes that will encapsulate transformation from a source data type to a destination data type. The source data types are all existing data that support of decoding.

We will provide only protocols (one for decoding and one for encoding) and users will be able to create transformers for their own data types.

The implementation:

The implementation is fairly easy. We only need introduce two protocols (encoding/decoding) and add a method to KeyedEncodingContainerProtocol that will accept a key and a transformer. In the method we will extract source data from JSON and then will ask the transformer to try to convert it to the desire data type.

Example of the decoding protocol:

protocol DecodingTransformer {
    associatedtype Input: Decodable
    associatedtype Output
    func transform(_ decoded: Input) throws -> Output
}

Inspired by: GitHub - tristanhimmelman/ObjectMapper: Simple JSON Object mapping written in Swift

Cheers,
Arsen
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

+1, need this for NSPredicate!

Very annoying to have Codable synthesis broken by a single non-Codable property that itself has an obvious Codable representation.

Like mentioned above, the proposed additions would not really make a difference. You'd still have to implement codable methods yourself, with the only difference being passing the transformer into a keyed container method vs calling the transformer with the encodable/decoded object directly.

You can also add the proposed stuff yourself in your project if you really need it.

I think a proposal similar to this would be worth revisiting if we ever get variable decoratos/annotations, so decoders could be specified right on the variable declaration, but for now I don't feel like it provides much value.