[iOS] Issues With Decodable And How to Overcome Them

Bach Le
3 min readMar 15, 2020

--

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?
}
Example of misused Vanilla Decodable protocol

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.

When one item cannot be decoded, the whole array fails

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!

--

--

Bach Le

iOS Developer with humble experience. Medium is where I read a lot, I say thanks by beginning to write stories.