All About Codable in Swift (Part 2)

https://learnappmaking.com/codable-json-swift-how-to/

This is the continuation of part 1. In this part we will cover the following topics

  1. Swift Models Generator tools
  2. Working With Deep JSON Hierarchies
  3. Working With Date
  4. Working With Enum and Url Data Type
  5. Codable Ability to Realm Models
  6. Working with class inheritance

Swift Models Generator

This is the tool that generate json response into swift classes highly recommended. Just paste your json response and get your swift model classes

Working With Deep JSON Hierarchies

As shown in Figure 1 we have json with deep hierarchy

Figure 1

As shown in Figure 2 our structure is same as json response so we don’t need to do extra efforts. Like User expect array of Custom Company model and Company model expect array of SubCompany model structure

Figure 2

As shown in Figure 3 magic of Codable is working automatically

Figure 3

Now if your json has changed something as shown in Figure 4, where company data were added after extra layer under key and due to this there is a mismatch between our model and the json.

Figure 4

As shown in Figure 5 we got crash while unwrapping optional since some of the json don’t parse because of the mismatch between our model and json

Figure 5

So to solve this problem we need to write custom decoding and as shown in Figure 6 we used nested keyed containers for key in this case as this key add one more level to access our company model. We did the following things

  1. Create your top-level coding keys.
  2. Create another set of coding keys, which you’ll use to create another container.
  3. Decode the name and id the way you’re used to.
  4. Create a nested container nestedContainer(keyedBy:forKey:) and decode company with it.
Figure 6

For the encoding part it will create json same as our model and as shown in Figure 7 after encoding it removed key from it, so to add this nested hierarchy level we need to do custom encoding

Figure 7

As shown in Figure 8 we wrote custom encoding , now it added key in our final json what the server expect

Figure 8

Working With Date

JSON has no data type to represent dates, so these are serialized into some representation that the client and server have to agree on. Typically this is done with ISO 8601 date formatting and then serialized as a string.

As shown in Figure 9 we want to parse dob key value in date type which is coming in Int as UNIX millisecond timestamp in json so parsing will failed

Figure 9

As shown in Figure 10 by using dateDecodingStrategy we successfully parsed it. It convert date in milliseconds which is Int to proper Date type

dateDecodingStrategy →The strategy to use in decoding dates. Means while decoding of a model if it find any property as Date dataType it tries to decode according to the strategy defined

Figure 10

You can pass your own formatter as well as shown in Figure 11. Most of the time you will use this if both backend and frontend will use this format to communicate about the DateTime format in overall application because you write the decoding logic with generic in single time

Figure 11

As shown in Figure 12 since we define millisecondsSince1970 as a dateDecodingStrategy. So for dob we implement custom decoding and dobInMili will be easily parse by our dateDecodingStrategy

Figure 12

Working With enum

As shown in Figure 13 by conforming to Codable protocol , decoder automatically parse String and convert it to enum type with rawvalue.

Figure 13

Working With Url

As shown in Figure 13.1 Codable automatically convert string into Url

Figure 13.1

Working With Realm Model

Realm is a cross platform mobile object database. If you want to learn more about Realm see this link where I wrote a whole series on this. You should look first then come again because here our focus only on parsing

As shown in Figure 14 decoding still working but there are couple of things we change in order to use Realm model as a decodable

  1. Replaces struct with class unless you will get this error “cannot inherit from class ‘Object` )”
  2. Move the model to outside to the controller
Figure 14

As shown in Figure 15 as we added RealmOptional type , since codable don’t know how to parse this type of datatype it will throw an error and unable to show its magic. to solve this problem we wrote custom decoding and took the value as an Int and assign it to the realm optional . Note convenience required init is used. If you want to learn more about Initialization hell see the documentation

Figure 15

Since Realm doesn’t support optional lists. You could just use empty by default. While decoding first decode in temporary variable if key may or may not exists then assign it to. Note let companies = List<Company>() we used let since it’s a reference type appending value will not mutate it

Figure 16

Working With Class Inheritance

We get the Codable conformance by inheriting from the user class, but what happens if we try to encode an instance of GoldUser? . Well that’s not what we wanted. As it turns out the auto-generated implementation doesn’t quite work with subclasses. So we’ll have to customize the encode/decode methods again.

Figure 17

Writing the custom decoding in subclass only, will not able to decode the super class property since decoder is expecting coding keys defined keys

Figure 18

As shown in Figure 19 we solved this issue by custom decoding in base class as well and called super.decoder in sub class. There is a bug previously where calling super.init(from: decoder) causes EXC_BAD_ACCESS when attempting to do so. At that point apple suggested

“If a shared container is desired, it is still possible to call `super.encode(to: encoder)` and
`super.init(from: decoder)`, but we recommend the safer containerized option.”

Now it is fixed so no worry.

Figure 19

If we have a base class model under some key in json we can superDecoder method. This produces the super-class decoding underneath this key: ”user”

Figure 20

Useful Links

https://www.hackingwithswift.com/articles/119/codable-cheat-sheethttps://www.hackingwithswift.com/articles/119/codable-cheat-sheet

Senior iOS Engineer | HungerStation | Delivery Hero