Move away from hefty NSCoding and any other JSON Parsing Though its a bit lengthy article, but trust me its going to be worth it. Most of the time when an app interact with external API or even sometimes local static data, we actually manipulates the different data types like JSON or plist or sometime even some other formats too. These tasks often require data to be encoded and decoded to and from an intermediate format while the data is being transferred or consumed. Most of the times, developers uses JSONSerialization to parse the JSON which actually converts the data to dictionary which you have to again parse through and convert to your application friendly data model to make it efficient and easy to read that data every time you need it. And again if you have to send some data to external source using some API, most probably you need to again convert your data model to dictionary to later it being serialised to JSON. Which was obviously tedious task with lot of manual effort. In this article we will learn the following: Whats new in Swift4 to get away from NSCoding and JSONSerialization Encoding and decoding custom model to and from JSON data Choosing specific propertied to Encode/Decode (Skipping unnecessary properties) Handling different key names in JSON and Model class/struct Encoding/Decoding Nested JSON data Merging the Multiple Nesting level while Encoding and Decoding was the existing protocol which can enable your data model to and from to manipulate it any further, whether to save in , other sources or archiving/unarchiving custom objects. NSCoding NSData NSUserDefaults Making your class complaint to protocol require you class to implement two additional method and which again require you to manually serialised and deserialised the properties in each of this method which you require to be converted in to encoded/decoded data. NSCoding encode(with aCoder:) init(coder aDecoder:) 1. Whats New in Swift 4 So, here is the rescue, Swift Standard library now includes new Protocols: In a nutshell, Encoding is the process of transforming your own custom type, class or struct to external data representation type like JSON or plist or something else & Decoding is the process of transforming external data representation type like JSON or plist to your own custom type, class or struct For Encoding model to external representation of data like JSON or plist Encodable: For decoding the external representation of data to your model. Decodable: **Codable:**For both encoding and decoding. Apple defines it as: typealias Codable = Encodable & Decodable Adopting on your own types enables you to serialize them to and from any of the built-in data formats, and any formats provided by custom encoders and decoders. Codable So What types I can Encode and Decode? If you want to encode or decode any model or your custom type, you must conform it to . Few built in types like and are already conform to . Codable String, Int, Double, Date Data Codable Built-in types such as , , and also conform to whenever they contain types. Array Dictionary Optional Codable Codable In below example, all properties can be encoded or decoded as they are either standard types or contains the types. Codable Codable Lets go in more details by encoding and decoding the data for real scenarios: There are two encoders available to encode your data to required format: — PropertyListEncoder Encode your type to plist format — JSONEncoder Encode your type to JSON format 2. Encoding and decoding custom model to and from JSON data So, lets start with encoding and decoding some real data. Consider a few data structures like below: lets create a instance, and encode it to JSON Encode: Car Consider the below JSON, conforming to the class metadata. Simply use JSON decoder to decode this JSON back to object. Decode: Car Car 3. Choosing specific properties to Encode/Decode (Skipping unnecessary properties) Its very unlikely that you will need to all of the class/struct properties to be encoded or to decode all the fields of JSON to your native model. Like and API response may include a bunch or values in JSON but in you application you may need only few of them. In such case you probably just need to worry about the fields you are interested in rather than decoding or parsing the entire JSON. Codable types can declare a special nested enumeration named CodingKeys that conforms to the CodingKey protocol. When this enumeration is present, its cases serve as the authoritative list of properties that must be included when instances of a codable type are encoded or decoded. The names of the enumeration cases should match the names you’ve given to the corresponding properties in your type. Omit properties from the CodingKeys enumeration if they won’t be present when decoding instances, or if certain properties shouldn’t be included in an encoded representation. While using enum, it has few rule which needs to be followed while using. has RawType as and values must match case with the JSON key names. CodingKey Enum — CodingKey CodingKey String Enum Example: Consider the below defenitions Lets encode the object of Class. Encode: Person Consider the below JSON, conforming to the class metadata. Decoded object from JSON will have only properties populated but ‘ ’ and ‘ ’ will be as we excluded these properties for Encoding/Decoding in enum. Decode: Person name, age, gender phone country nil CodingKeys 4. Handling different key names in JSON and Model class/struct As might be aware till now that declaring require the values to exactly case math with the property name declared in your class or struct. CodingKey enum But in real world, data received from external API in JSON format may have completely different key names which may or may not match the property names defined in your class. For example, in some API response for list of books, book key might be ‘ ’ but that does not mean that you are also forced to use the same name for the property in you model. What if you just wanted to use ‘ ’ and this ‘ ’ should automatically map to ‘ ’ key defined in the JSON. name bookName name name bookName Well, you can achieve this with little bit of code, lets see it how, consider the below class declarations: Lets create a object and encode Encoding: Book This encode json will rename the property names in JSON as per above defined enum. CodingKey name property will get renamed to **** bookName author property will get renamed to **** writtenBy numberOfPages property will get renamed to pagesInTheBook All other properties will have the same name in JSON as they are defined in the Book class. **Decoding:**Consider the below JSON, conforming to the class metadata. Decoded object from JSON will automatically map JSON keys to respective properties in class. Book Book 5. Encoding/Decoding Nested JSON data Although, I have already covered it in first example, but lets go through again about how to handle multiple level of Nested objects in JSON data or even in your own class/struct. Lets start with below class declaration inspired by one of the example illustrated on Apple documentation: Any custom type or collection which contains data type, can be encoded and decoded. In above example each of our nested class is , so do . Codable Codable Supermarket **Encode:**Lets create one Supermarket and encode it. Self explanatory! just check and it will have all the level of nested information. encodedObjectJsonString Consider the JSON created in above example for variable, To save some space, I will not put this JSON again, we will just reuse the same variable and will try to decode same JSON back to object. (Why not you give it a try by creating a JSON by adding multiple ?) Decoding: encodedObjectJsonString Supermarket products/shelfs/aisles Works like a charm ! 6. Merging the Multiple Nesting level while Encoding and Decoding All these example are perfectly great until you say that you don’t want to retain the same level of Nesting in your object model as its in JSON or you don’t want same level of Nesting in your JSON as you have defined in your class. Lets target one by one: 6.A. Removing Object Level Nesting while Encoding to JSON Consider below class declaration conforming to some JSON structure: When you encode it to JSON, you will get something like: But actually you want to to be something like: Lets update our class as below: Photo First, Include a enum in Photo class by specifying the values in desired hierarchy: CodingKey enum Notice that enum includes and enum values rather than as we were following till now. CodingKeys height width Size Now, You need to implement and methods of and protocols explicitly in your class: encode(to:) init(from:) Encodable Decodable And that it, Once you now encode your object model or decode the JSON data back to your class model by mapping and keys to your struct in your object model. height width Size 6.B. Removing JSON Level Nesting while Decoding to Object model Remember the class and its other related structures which we have used in point 5? Supermarket Well, What if we could directly map the from JSON under class so that my API still uses same JSON format even though my application trims it down to only the required hierarchy and data? To be more clear, I want my class to look like this while decoding it from the same JSON. Products Supermarket Supermarket So my actual JSON from class looks like: Supermarket But I want my Decode class object look like below by avoiding hierarchy: Supermarket Supermarket->Aisle->Shelf->Product Unfortunately, Its not directly supported yet in swift. But that does not mean that you can achieve it. So what you can do is keep the original class as it is and let it decode all the data with original hierarchy and Create a new class which can match the declaration as mentioned above in class and write the getter method for allProducts property which can consume the original class and can return all the across and by iterating the collection. Supermarket SupermarketData ExpectedSupermarket Supermarket Products Aisles Shelves I know its not smart solution but that how you can achieve it until Apple provide inbuilt support for it. For sample application for all the scenarios used in this article, you can use the code from . here If you have further comments or questions, feel free to put the below. You can follow me on . Connect with me on . Medium LinkedIn