Over the past weeks I have been preparing for two CiscoLive Barcelona breakout sessions. In one of them I will give a brief demo and the other session where I will be covering parts of the Cisco Press book that I wrote. The preparation itself is not only about the slides, but also developing code that is to be used in the demo’s. These demo’s are built on iOS devices and run on some containers, so I have been writing that software in Swift, which is a beautiful and powerful programming language. One of my previous posts covers some principles of Swift. One really powerful feature is the easy capability to encode or decode data to the JSON format.
If you want to have a class to be able to convert to and from a JSON format, just use the Codable protocol and you’re ready, see the code example below:
To convert this to JSON, this would only require a few lines of code:
The variable jsonData (of type Data) now contains a JSON-version of the earlier created message. Just to check the output, I can use the following commands to convert that data to String and output it in XCode’s Playground.
Suppose you would like to extend our message class with a special broadcast message, where the message can be sent to a all endpoints.. You could add an optional broadcastContent variable to the message class and create a state machine to determine when to use that value. Another alternative is to leverage the power of object-oriented programming and create a new subtype, like the following code example:
So when you’d create a multicast message, like below, you’d expect that it would contain all attributes in the json file, right? Let’s check it out in Playground:
As you can see, the output does not contain all attributes of the broadcast message! It only contains the base message type class values. The msgContent variable is not included. It took me some time debugging and researching to figure out what happens. Swift bug SR-5431 and SR-4722 provide more details. Without going into those bugs, it comes down to the fact that as soon as you subclass a class that conforms to Codable, you need to override the default encode/decode methods and write your own. After some fiddling around, I have used the following code pattern to achieve that result.
As you can see, when BroadcastMessage is converted to JSON, it is now correctly encoded.
I am now using the coding pattern below to achieve this functionality:
- Create a private enum called CodingKeys that follows CodingKey. ]
- Enter all class variables as part of the enumeration
- Create custom encoders and decoders for the base class
- In the subclass, define a new private enum called CodingKeys . I have marked both private so the compiler knows which variable to know in which function
- Create the custom encoders
- Encode the variables of the child class and then
- Call the encoder / decoder of the parent class