Codables: (De)Serializing - Ch. 1: Coder Options

The first chapter to customize your Codable (de)serialization is about the options of your selected Decoder and Enc​oder.

Codables: (De)Serializing - Ch. 1: Coder Options

Most of our (De-) Serializing work is done by Codables themself. All keys of the data structure are mapped directly to the property names of your model. Without any modification to the naming. But in most cases you want to optimize the data in a way that works better for you.

At first you should check out what options your Coder gives you that could already fix a lot of your issues with the naming of the API and your model properties.

keyDecodingStrategy

The JSONDecoder for example has a keyDecodingStrategy property which can be set to .useDefaultKeys (default) or .convertFromSnakeCase. This fixes the  issues that you get a snake_case (words separated by underscores) property from an API, but you want your model properties to be camelCase (words separated by uppercasing the first letter of the new word). This is also available on the JSONEncoder with equivalent naming of keyEncodingStrategy and .convertToSnakeCase.

Data and Date conversion

And the JSON Coders have strategy options for Data and Date conversion. The properties for this are named dataEncodingStrategy and dateEncodingStrategy for the

Data is converted from and to Base64 by default and Date will be encoded by it's own encoding/decoding logic by default (.deferredToDate). But the strategy can be changed to .iso8601 which creates/parses an ISO 8601 compatible string, .formatted(DateFormatter) which takes a custom DateFormatter or if you are more into UNIX timestamps: .secondsSince1970 and .millisecondsSince1970.

All of these strategy options also have a .custom option. More on that in a later chapter when we get into ValueContainer. (A Link will follow as soon as the article is online)

A short annotation if you are using a PHP based backend for your app:‌‌‌‌PHP does have an option to encode a DateTime object to ISO 8601 and it works fine on the decoding side of your app. But if you want to send a Date whereas you have to encode it to an ISO 8601 string, this doesn't work in most cases. That's because PHP isn't conforming to the standard and uses a default format of  "Y-m-d\TH:i:sO" (Source) - The O indicates a timezone like +0100, but Z is valid for UTC timezone by ISO 8601 definition, but PHP throws an error if it gets such a date string for parsing.‌‌‌‌Use a .formatted(DateFormatter) strategy and use "yyyy-MM-dd'T'HH:mm:ssxxxx" as your dateFormat on the app side.

This is it for the Coder options. At least for the JSON Coder provided by the Swift Standard Library. The PropertyListEncoder only has an option for the output format. If you want the encoded data to be binary, xml or openStep formatted. The corresponding decoder has no options at all.

Additional note: Both the JSON and PropertyList Encoder and Decoder are available on Linux as well.

There are 3rd party Encoder and Decoder out there, just check their documentation on how to modify their logic. Maybe this options will already help you a lot.

References