The Decodable
protocol is convenient, but unfortunately is not complete for my use cases. Thus, I decided to add some custom code around it to create a more complete JSON parsing experience. I will walk through each of the shortcomings I have found and explained how I fixed the issue.
The list may not be exhaustive. It only contains defects I find so far and works as expected in my project.
[Issue 1] A String Must Strictly Be A String, Not Number Or Bool
The first problem I bumped into was decoding data as String
. Logically speaking, number and boolean can be converted to String
with ease. However, the default Decodable
protocol forbid it. If the JSON contains an Int
for ID while you want to represent them as String
, you are out of luck with the default Decodable
. I have composed a post about the problem before. It can be referenced here.
In summary, we create a custom struct to use in our model representation instead of the vanilla String
.
[Issue 2] Optional Fields Are Not Truly Optional
I naively believed that when I declare a field as Optional
, such field will simply be nil
whenever unexpected data passed into it. But I was wrong…
fileprivate struct NotTrulyOptionalFieldModel: Decodable {
let id: String
let item: Item?
}
As it turns out, an Optional
field will be Optional
itself, without affecting the whole Model
only when the key for it is missing, not when the key is available with unexpected data. As a result, we will have to define yet another wrapper class to cope with this situation.
Please note that the use of OptionalDecodable
only helps cope with scenario where the data within a CodingKey
cannot be parsed. In case the CodingKey
itself it missing, we must make OptionalDecodable
optional.
The test cases I used to test the implementation.
And its result. Sweet 😄!
[Issue 3] When one item cannot be decoded, the whole array fails
Below is a test case demonstrating and verifying the problem.
To solve this problem, I create another class and makes use of previously defined OptionalDecodable
.
It looks promising already. Let’s go for a test drive!
And there, everything works as expected 😻.
Happy Coding!