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 Encoder.
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 aDateTime
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) - TheO
indicates a timezone like+0100
, butZ
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 yourdateFormat
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
- JSON
- Property List
- 3rd Party