NSCoding, Codable in iOS

Tram Ho

I. Introduction

When we do data storage in iOS, we often think of CoreData right away. In addition to CoreData, iOS / OSX also provides us with another way of storage: NSKeyedArchiver / NSKeyedUnarchiver. If comparing between CoreData and NSKeyedArchiver / NSKeyedUnarchiver, CoreData is much better, it is faster, provides Entity modeling, the ability to query data, … However, in certain situations, NSKeyedArchiver / NSKeyedUnarchiver is again a better solution for archiving. For example, we simply need to save the object, and use it later.

The archiving process using NSKeyedArchiver / NSKeyedUnarchiver will look like this:

  • convert objects from common forms (Int, Double, String, …) or complex (class, array, dictionary, …) to NSData / Data form by NSKeyedArchiver / NSKeyedUnarchiver
  • save NSData / Data to file / UserDefault

In this article, I will introduce NSCoding and Codable, two protocols that must be used when you use NSKeyedArchiver / NSKeyedUnarchiver to turn objects into data.

II. content

1. NSCoding

First, you open Xcode and create a new playground project. Now, suppose we have Class like this:

When we want to save the data of the instance person in UserDefault, we do the following:

Building test playground, we will encounter bug crash, log content on console as follows:

libc ++ abi.dylib: terminating with uncaught exception of type NSException

Ok, of course there must be errors, if not errors this article has no effect at all . To save the object into UserDefault, we need to comply with the following 3 rules:

    1. Data must belong to one of the basic data types: Int, Float, Double, String, Boolean, Date
    1. If the data is of Array, Dictionary, all its keys and values ​​must obey rule number 1
    1. If the data is a complex Class, Array, and Dictionary format, it needs to comply with NSCoding / Codable protocol, and needs NSKeyedArchiver / NSKeyedUnarchiver to convert to Data.

Class Person did not follow rule number 3, so we will crash when running the App. To comply with rule 3, we add the code for the Person class like this:

Above, we take turns to:

  • 1: Let the Person class extend from NSObject, and extend the NSCoding protocol. The reason to inherit from NSObject is because NSCoding protocol requires so, if you don’t do that, compile time has no error, but the App runtime will crash.
  • 2: constructor, which is also the decode data function of NSCoding. This is a required function when conforming to the NSCoding protocol
  • 3: encode function of NSCoding, this function is called when saving data. This is also a required function when conforming the NSCoding protocol

Next, to save and retrieve the instance person into UserDefault, we do the following:

Above, we take turns using

  • NSKeyedArchiver.archivedData () to turn the instance person into Data and save it
  • and NSKeyedUnarchiver.unarchiveTopLevelObjectWithData () to convert the data back to instance of Person class.

Ok, so we understand how to use NSCoding and how to use NSKeyedArchiver to store data. UserDefault is just a place to save, you can completely save data to a file.

2. Codable

We will continue to learn about Codable. Codable is basically a Swift-written version of NSCoding. The functionality of both protocols is the same, but Codable has many advantages over NSCoding. We consider the following example:

At first glance, the usage of Codable and NSCoding is quite similar:

  • both adopt Codable / NSCoding protocol
  • both have two functions encode and init (decode) to encode and decode

However, if we look closely, we will notice many differences

    1. Person is a class, and People is a struct. Above when learning about NSCoding, we already know that in order to use NSCoding, we must inherit from NSObject, which means it must be a class. Whereas Codable gives us the ability to use struct. Swift encourages us to use struct more, so using Codable is more reasonable.
    1. Enum Key must adopt from the CodingKey protocol, so that the encryption / decryption process in the underlying functions is more secure.
    1. The decoder function defines the type that will be returned in the parameter, we don’t have to cast the type like we did with NSCoding
    1. The encoding is also needed through the containter, an instance of the struct KeyedEncodingContainer. This will make the code more secure, avoiding errors during the runtime phase.

That is, write code with clearer Codable, more Swift direction, avoid bugs occurring during runtime.

And yet, it’s also safer to use NSKeyedArchiver / NSKeyedUnarchiver with Codable. The conversion from People to Data instance form is done with PropertyListEncoder, so if we just need to save it to UserDefault we can ignore NSKeyedArchiver / NSKeyedUnarchiver and do the following:

In the code above, the encode / decode parts all use the try / catch function to catch the exception, to prevent the App from crashing at runtime.

III. Conclude

Here we have together learned about how to use NSCoding and Codable in iOS. Hope this article brings useful information to you. Thank you for following this article, have a nice day ^ _ ^.

Share the news now

Source : Viblo