As you have seen in the last post, NSUserDefaults is not as sophisticated as we want it to be in more complex scenarios such as persisting an
object graph like an array of arrays, for example. Often times we get into situations where we do not see app persistence even though we should.
Let’s start with an example. When you create a
Master-Detail project in
Xcode you will notice that all the date entries you create will be lost if you run the app again. If we look at the code inside
MasterViewController we notice that a mutable array named objects is used to store objects of the type
NSDate every time we click the + button at the right end of the navigation bar. So
objects will be a proper object graph candidate for us to persist.
When the app starts for the first time there is no file to store the array, so we first need to construct the full path. Let’s add a calculated
Swift property to
MasterViewController that specifies the location of a file name we choose, and then place it inside the
The root of the graph for this app is the objects array. We can persist the array using a class method on the
NSKeyedArchiver and add this line to the insertNewObject() method:
To unarchive the array from the file we use a conditional optional check in case our file does not exist, and add it to the viewDidLoad() method:
Now run the app, create a few date entries, close the app and run it again. You should now see that the array is being persisted. That was easy. But what about complex objects graphs such as arrays of custom objects? In this case we need to complement
NSKeyedUnarchiver with the NSCoding protocol that we will need to implement.
Let’s create a new Person class:
You noticed we conformed this class to the
NSCoding protocol so we needed to implement the two methods the protocol requires, init(coder:) and encodeWithCoder(archiver:). Assume that we have another array persons in
MasterViewController and another method that adds
Person objects to this array. Having the
Person class set up with an archiver for saving data and an unarchiver for retrieving saved data makes our task as easy as calling the archiver in the
and the unarchiver in the
Stay tuned for the last part of this series.
Until next time!