Codable in Swift and iOS
JSON -> Swift
Codable is one of those great features that shouldn’t escape the attention of any budding developer in the Swift ecosystem.
Difficulty: Beginner | Easy | Normal | Challenging
Prerequisites:
- This article covers Codable, and as such it would be good to have some knowledge of models, classes and structs in Swift
Terminology
Codable: A type alias for Decodable & Encodable that allows easy conversion to or from a serialised format (i.e. JSON)
JSON: JavaScript Object Notation, a lightweight format for storing and transporting data
The implementation: codable
A typical application takes data from an Endpoint and decoded into a Swift model. Now since structs
typically represent data and are value types they are suitable for models (over class
, although you need to make your own decision about this).
This user mode conforms to the Codable
protocol. This means that we can choose to either encode to decode to (from) the Swift UserModel
model.
We can encode this through the following function:
We then can decode user model:
The issue with the above is that this is the simple case. The JSON format exactly matches the model which is a rather lovely synergy of a back and front end.
This isn’t always possible in real life: The backend model may not match the struct
exactly.
The implementation: codable snake_case
We shouldn’t really be using snake_case in Swift code, yet your backend developer (this isn’t you, is it?) thinks that it’s a great idea.
Rather than resorting to physical assault (better to not do that at work, in any case) you can just convert snake_case to something more sensible using your JSONDecoder.
That would be wonderful.
This can be done with a little nudge making “user_Id”: 1
not match userId
.
We can then add the following line just after the decoder declaration (that being let decoder = JSONDecoder()
)
decoder.keyDecodingStrategy = .convertFromSnakeCase
The implementation: non-matching key names
We can have a JSON string detailed by the following:
let data = “””{“idforuser”: 1,“globalid”: 2,“usertitle”: “test”,“complete”: true}“””
I’ve decided to write this into an extension, that is an enum CodingKeys (Which is a enum that uses strings for the raw value)
The implementation: nested JSON
which then needs a slightly different model; that is, one that can be combined with another Struct:
The owner can then be accessed through content.owner.name
or content.owner.age
.
Parsing data using coding
If you need to convert a date from JSON into your struct model, the decoder has you covered
You might be expected to use the ISO8601 format when processing dates (and you’d be well advised to do so).
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
and in fact you can even use custom formats just like with a standard date formatter
let readableDateFormatter = DateFormatter()
readableDateFormatter.dateFormat = "M-dd-yyyy HH:mm"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
dateDecodingStrategy
can even process a closure, with a user-defined function.
Conclusion:
Look, in the world of software development there is one thing that you are likely to have to do repeatedly. That is, you will need to convert JSON data to Swift objects.
Codable helps you do just that!
This guide has taken you through ways that can help you complete your project using codable, and make use of this great feature from Apple — and don’t forget about the fun formatting of dates covered towards the end of this article.
Extend your knowledge
- Apple’s documentation is reasonably good at explaining this topic
- I’ve written an article on naming conventions in programming languages
The Twitter contact:
Any questions? You can get in touch with me HERE