Now, those of you guys who are looking closely, you might have noticed that in the last lesson, we've ran 1
our app and tested whether if our checking and unchecking was persisted into our plist, as soon as we checked 2
off the first item, the last two items in our item.plist got erased. 3
And the reason for that is because we're calling save items when we toggle the check box and that will 4
overwrite the current Item.plist file. 5
So let's go ahead and add it back in. 6
So why does our app do that? 7
Well, the problem is that we're not yet loading up our data from our Items.plist, 8
instead we're loading it up by hardcoding the items and appending them to this itemArray which we 9
know does not get persisted. 10
So whereas, previously, we loaded our items from the UserDefault by using these lines, 11
now we've commented out, and so we have to replace it with some more code that loads up our 12
Item.plist. 13
So instead of writing our code here, I'm just going to call a method called loadItems and it doesn't 14
exist yet, 15
so Xcode is going to complain. But not for long because I'm going to create the function here and 16
I'm going to call it loadItems, just as I called it above. 17
And inside here, we're going to tap into our data by creating a constant and we're going to set it to 18
equal data created using the contents of a URL, 19
so this method. Hit enter. And the URL is, of course, still going to be our dataFilePath. 20
And this is, again, a method that can throw an error. 21
So I'm going to mark it with a "try?" which will turn the result of this method into an 22
optional. 23
So then I'm going to use optional binding to unwrap that safely. 24
So, now just as above we created an object that was an encoder using the PropertyListEncoder in order 25
to decode our items. 26
We have to create a decoder, and you guessed it, it's a PropertyListDecoder. 27
So let's hit enter. And we're going to create a new object of that class. Once we've got our decoder, 28
we're going to set our array up here, 29
itemArray, which contains an array of items. 30
So itemArray is now going to be equal to 31
decoder.decode. 32
So this is the method that's going to decode our data from the dataFilePath. 33
But we have to specify what is the data type of the thing that's going to be decoded because Swift isn't 34
able to reliably infer the data type. 35
And this is one of those rare cases where you actually have to tell it what is the data type. 36
So the data type is, of course, an array of items. 37
And because we're not specifying object, in order to refer to the type that is array of items, we actually 38
also have to write .self here. 39
And the Data is, of course, that data that we safely unwrapped above. And this method, again, needs a "try" 40
keyword in front of it. 41
So we're going to wrap this inside a do block and we're going to catch the errors by printing out. 42
Now, let's just make sure that we called loadItems correctly inside viewDidLoad and we can safely 43
delete all of this hardcoded item initialization, because as we can see, we've already successfully saved 44
all of those items into our Item.plist, 45
so we don't need to initialize it all over again. 46
Now, before we run our app, there's one last thing that we need to do with decoding that we did with 47
encoding. 48
We need to say that our Item class is not only encodedable, but it's also conforming to the decodable protocol. 49
This is a type that only contains standard data types and it can be decoded from another representation 50
which in our case is a plist. 51
Now, it's a little bit silly having encodable and decodable. And since Swift 4, you can replace it with 52
just the word "Codable." And this specifies that a particular class and all of their objects conform to 53
both the encodable and the decodable protocols. 54
So let's hit save and let's check that we've called loadItems in vieDidLoad, and let's run our app. 55
Cool. 56
So we've now managed to successfully load up all of the items that currently exist in our Items.plist, 57
and you can see that if I check on one of these items, that the done property updates live. 58
Cool, right? 59
So we've now managed to successfully do what we weren't able to do before which is save an array of 60
custom objects into persisted storage and retrieve it at a later date. 61
So, now if I go ahead and terminate this app, if I open it again, all my checkmarks still exist in the 62
right places and all my items still get loaded up. 63
So in this lesson, we use the NSCoder in order to encode and decode our data to a prespecified file path, 64
and our code converted our array of items into a plist file which we can then save and retrieve from. 65
Now, does encoding and decoding makes sense to you? 66
Not yet? 67
All right, let's think about it from a different perspective. 68
When you encode data, you're essentially converting one data type into another. 69
It's almost the same as converting your music into a vinyl disc. 70
And what this machine does is that it takes music and it etches into a vinyl disc all the grooves that 71
correspond to the music. 72
So we're using the encoder to turn music into a vinyl disc, and that is our encoder. Now, our decoder takes 73
that same vinyl disc and plays it or turns it back into the music. 74
And this is exactly the same as what we're doing here. 75
We're encoding one type of data, 76
our array of custom objects into data that can be written into a plist, and then when we need that data, 77
we use a plist decoder to take out that data in the form of an array of items. 78
So this gives us way more flexibility over our NSUserDefaults. And when we save data to our 79
NSUserDefaults, 80
they all went into the same plist. But in our case, we can actually initialize different plists. 81
For example, if we had different categories to our to-do list, we had one to-do list that was for home, 82
one to-do list that was for work, 83
instead of loading up a large plist that contains all of our items, we could actually separate it out 84
into individual plist for each and every category, 85
reducing the loading time every time we want to read and write to that plist. 86
So have a play around with the code. And in the next lesson, we're going to make our persistent storage 87
even more flexible and even more scalable by using Core Data. 88
So I'll see you there.