So, now that we've had to look at what's the code inside our AppDelegate, this is a good time to go back 1
into our TodoListvView Controller and fix all of these errors that we've got by switching over from a 2
custom class that saved using plist to our Core Data data model. 3
And in the process, we'll learn about how to create or rather save data using Core Data. 4
So the first thing that we need to change is that instead of creating a newItem as a new object of 5
item, we actually need to initialize our Core Data object a little bit differently. 6
So if we say let newItem = item, which if you remember is our Core Data class, 7
so if you hold down option and click on it, you can see it's an i object of the type 8
NSManagedObject. 9
And if we open a round bracket to initialize it, then we get to specify the context where this item is 10
going to exist. 11
So what is that context? 12
Well, it's basically going to be the viewContext of our persistentContainer. 13
So while we're inside the same class, it's easy to access this variable called persistentContainer. 14
But if we're inside TodoListViewController, how do we create that context? 15
We can just say let context = AppDelegate.persistentContainer.viewContext. And the 16
reason why this doesn't work is because AppDelegate is a class, 17
it's not the object of AppDelegate. 18
So remember, when we refer to the TodoListViewController, for example, we won't try to call its 19
methods or grab its properties by calling the class. 20
Instead, we need to get the object of AppDelegate. 21
So this would be the blueprint and we need to get the object that's created from the blueprint. 22
So this, again, is where our handy singletons come into use. And instead of calling App Delegate, I'm instead 23
going to tap into UIApplication.shared, 24
and this is a singleton app instance. 25
And at the time point when our app is running live inside the user's iPhone, then the shared UIApplication 26
will correspond to our live application object. 27
And inside this shared UIApplication object is something called delegate, and this is the delegate of 28
the app object, 29
alternatively known as the AppDelegate, 30
and we're going to downcast it as our class AppDelegate. 31
So let's just give you a bit more space to see that whole line as it is. 32
So we're tapping into the UIApplication class. 33
We're getting the shared singleton object which corresponds to the current app as an object, tapping 34
into its delegate which has the data type of an optional UIApplicationDelegate. 35
We're casting it into our class AppDelegate, because they both inherit from the same superclass 36
UIApplicationDelegate. 37
This is perfectly valid and we now have access to our AppDelegate as an object. 38
So we're able to tap into its property code persistentContainer and we're going to grab the viewContext 39
of that persistentContainer. So we can now say our context is this context. 40
Now, the next error that we have is inside saveItems. And because we're no longer using the encoder, 41
we can delete that, 42
and we have to delete all of this as well. 43
So what we ultimately need to do inside our saveItems method is we need to be able to commit our context 44
to permanent storage inside our persistentContainer. 45
And in order to do that, we need to call rye context.save. And that basically transfers what's currently 46
inside our staging area or our scratchpad 47
that's the context to our permanent data stores. 48
So inside the do block, we need to be able to say context.save. 49
Now, where are we going to get our context? 50
Well, it's going to be exactly the same as this. 51
So we can either copy and paste it over here or whenever you're copying and pasting the exact same pieces 52
of code, then it's a good time point to evaluate. 53
Maybe we should make it a shared constant up here. 54
So, now instead of having this long line of code here, we can simply say let newItem = item 55
the context is going to be self.context because we're inside a closure. 56
And down here, we can simply say context.save and mark it with the "try" keyword. 57
And inside the catch block, we're going to print and say "Error saving context" with this error message. 58
So all that we've done so far is to set up the code to use Core Data for saving our new items that have 59
been added using the UIAlert. 60
So I'm going to comment out the load items function and I'm also going to comment out the part where 61
we call that function. And if we want to be able to use item which, if you remember, is an NSManagedObject, 62
so it's something that only exists in the Core Data framework. 63
Then, of course, we also need to import Core Data, 64
and now those errors will go away. 65
So if I run the app now, you're going to see that we're going to come into an interesting bug. 66
So when I hit Add, let's create a new item. 67
And once I hit an add item, you can see it show up inside the table view, but that's only because it's being 68
added to an array. 69
And if we drag up our debug console, we'll see the reason. And it gives us an error with a code, and it says, 70
"Error saving context." 71
So that, of course, refers to this line here. And this is the error that we're catching because we wrote 72
this "Error saving context," remember? 73
And the error message is "The operation couldn't be completed" because if we have a look at our data, we've 74
got this item called done and it's equal to nil. 75
So because our item done is not optional, 76
we have to provide it with a value when we create our newItem. 77
So over here, in addition to adding a title, we're going to set the done to false for every single new 78
item that we add into our table view 79
which makes sense, right? Because everything starts off being not done. 80
So let's run our app again and see if this now works. 81
So let's add a new item. 82
And now you can see that the item has been added to the table view and we don't get any errors in our 83
debug console from that catch block. 84
So the problem, though, is that right now, we haven't yet got code that loads our items from our Core Data 85
data model. 86
And if I terminate this app and I reopen it, you can see that we have no items in here. But we did save 87
our data using Core Data and we didn't get any errors, 88
so it succeeded. 89
So how can I prove this to you? 90
Well, in the next lesson, I'm going to show you how you can view your SQLite database and see the 91
items that get saved into it. 92
So for all of that and more, see you on the next lesson.