[MUSIC] Okay, welcome back to our case study of a To Do list manager. This is part of our peer review preparation. And our big picture is that we're trying to put together a To Do list that has a CoreData backed list of To Dos, and we have a detail pane that we can edit. We did a few steps in the beginning that involved setting up our storyboard and subclassing our different view controllers, so that we can add code to them, so that we could move the managed object controller down through that view hierarchy. In this section what we'd like to do is we would like to work with our CoreData model. We're going to create that CoreData model. And then we're going to subclass the cell in the table that's going to be used to create the cell view of our entity that we're creating the CoreData. Then we're going to go ahead and add some navigation items to our views. We're going to add a button to make a New To Do, so that there's a place where to start them. We'll create a segue that will be the what happens or give action to the button, the New To Do button, and then I'll show you how we're going to pass that managed object context all the way down, using our protocols or protocols. And then how that all comes together. So let's go back to our project, our Xcode project that we've been working on. First thing we're going to do is we're going to create our CoreData model that's going to hold our To Do. Now, in principle there's a lot of different things that you might want to make a To Do list manager keep track of. And we're going to ask you in the assignment to think a little bit creatively about what you might want to do. For this one we're going to basically just have three different items that are going to be set up. We're going to have the title of the To Do. We're going to have a detailed description of the To Do. And then we're going to have a due date when that To Do presumably is done. So to do that we're going to add, ha to do that, that's kind of funny, we're going to add an entity and we're going to give it a name, and that name is going to be used throughout our code and we're just going to say, to do entity so that we know. We're going to leave the word entity on there so we know that it came from this interface, did I spell it right? Yeah, great. Remember, To Do, the entity is like a table in SQL database or a relational database and this is in fact what's underlying this. Then we're going to add some attributes which were the columns in our database. And the first one we're going to add is just the title. The title is going to be a string. And the title for this To Do is going to be required. So I'm going to go ahead and, this is a little bit strange about the interface, but you actually have to click outside of the attribute in order to get the attribute's properties to come up over here. I don't know what that's about, but. Now, then you click back in, it comes up. I don't know. I have a hard time getting those attributes to show up. But what I'm trying to get to is I'm trying to see that it says, attribute here, and I want to make the title not be optional. And not only do I want it not to be optional but I also don't want it to be there but empty. So I'm going to make it have a minimal length of one. And I'm going to watch the UI because it reset it to zero when I hit minimum length. Hit Tab, make sure it sticks, great. Now, it's going to be my first attribute. My second attribute is going to be the description because description's used in other places and objectives here, and I don't want that to mess me up. I'm going to go ahead and call it, we'll call it To Do details. And actually, let's finish that off. To Do details, make it a string. And again, the properties of that attribute aren't there. I'm going to click outside in order to get the properties of the To Do details. It's okay if the details are optional, we'll let that be optional. What I want to do here is come back here and make this consistent though. Get the properties of the attribute, and I'm going to make it consistent. So it's To Do, do title, I just wanted to change the name. Then the last thing that I want to do, is I want to add the due date. So I'm going to make a To Do Due Date. And this is going to be a date type. And for, I am fine if this is also optional. Now if you come over here on your pane, you can specify some minimum values. This messed me up earlier when I set it to something beyond, something in the future and it couldn't figure out where the error was coming from. So when you do this make sure that you're careful. I'm going to go ahead and give myself a little leeway and say it can go as far back as the beginning of 2015. And I won't worry about putting a maximum date or a default value. You don't have to put a constraint in here, but if, yeah this is just optional. But we'll go ahead. Give it a minimum value. All right. Looks like everything took. It looks like we have the three attributes we want. Our entity, we have named our entity, and now we're going to leverage Xcode to create the code that helps us to interact with this CoreData element. And we'll do that under editor. And we'll create our NS managed object subclass. We're going to create the To Do entity, please. That's one I'd like to manage. Like to put it in our project. Thank you very much. All right, and there we have the examples of our code where later on if we decide we want to use an entity, you see that we can access different aspects of it. That's if we want to add our own code, we add our own code here. And if Xcode needs to regenerate its portion of the code because we've changed something in that model interface that we were just working with, it will change these files. So here you can see we have access to the toDoTitles which is a string, toDoDetails which is a string, and the toDoDueDate which is an NSDate pointer object. Okay, so that's our CoreData. The next thing that we said we're going to do is we said we are going to create a UITableViewCell, All right? By that I mean we're going to create a class which is going to encapsulate the table view cell. So by that I mean this prototype cell here which currently if we click on the table cell identifier. And we come over here and we try to define its class. We see that it is a UITableViewCell. And that is what we're going to subclass and then we can have access to code for that class, same way that we did the other elements as well. So the UITableViewCell is the thing that we want to subclass. Let's do that by creating a new file. That is a new Cocoa IOS, boy, that keeps messing up on me. IOS, Source, Cocoa Touch Class, click Next, and we're going to go ahead and say it is a subclass of the UITableView, not TableViewController, but TableViewCell. There we go, and we will use our same pattern and say, MyUITableViewCell. All right, and because I am like that, I am going to move it down here so it's alphabetical. All right, so it is within here that we are able to have access to the different elements in our UI that we want to manage. Right now, our table view is not of that type, so now that we've created the subclass, we want to come over here and select our table cell. And we want to make it of the class that we just created, MyUITableViewCell, great. Now if we decide that we want to work with the UI element in code we can have access to it programmatically. The next thing that we said we wanted to is we wanted to add a To Do button and we wanted to segue it to the new view controller, and this should reduce, this should eliminate that one warning we had saying that our view controller was an island outside of our view hierarchy. So, let's do that next. Create a To Do button and segueway it to the new view controller. What that means is we have to look at our table view here and decide what we want. Well, for starters, our root view controller here, I don't like the name. Root view controller is not particularly user friendly. And so, I want to change it. Let's see if I can find where it's changed. All right. We're going to call this our to do list. Great. And what we would like to do is we would like to add a button. And we want a bar button item, a special kind of button. And we're going to put it on the right side. Put it on the right side. There we go. And it didn't show up in the right place. So, let's see. There we go. It's on the left side. I'm going to drag it down to the right side. So, what happened there is when I dropped it into the UI it didn't put it in the right place in the hierarchy of my scene. So, I came over here to the explicit hierarchy and I moved it so that it was part of our to do list navigation controller, and it is the right button bar. It's currently called item. I don't want it to be item. Item would be a custom class. And when I select it, it's not selecting it. Maybe I'm too far zoomed out. Sometimes if you're too far zoomed out you can't select it. But it's not letting me zoom in to select it. So, I'm going to select it over here instead. By selecting it over in this element hierarchy, sometimes gives you a little bit more confidence that you have the right thing. The reason why I'm selecting it is because I want to change the kind of button it is from being a custom button that says item, to being a button that reflects the semantic work of adding an item to our to do list. This is an example of using the built-in icons that come with the iOS UIKit so that, if in the future, part of the visual language of the SDK gets changed, if I add it, if I use this system wide add semantics, the button for adding will change but it will still mean add however they want to change it in the future. So, for now, it's a blue plus sign. And so, I've added it. When that blue plus sign is clicked, I want it to create a segueway that moves into this smaller view controler. I could do that by control clicking here and dragging it over. I'm having trouble selecting my UI. So, I'm going to come over here and I'm going to control drag here to this new view controller. I want that to be a show segueway. And you see that when I do that it adds the segueway here so that this is no longer an orphan. And to make this work right, I'm going to go ahead and add a navigation item to this which will give it a header. And the title for this one is going to be, this is going to be a place where we edit our to-do list items. And it's also a place where we will create a new one. So, I'll call it a to-do, let's call it the to-do editor. Actually, let's call it a to do item. Actually, let's just call it a to do. Because we have a to do list, and we have a to do, and everything in this scene is going to be the to do. So, let's just leave it as to do. And while we're here, let's change this. No, I think it's okay. I think, I want the back button to say To Do List, I think. Yeah. I like that. Was what we said we we were going to do. We said we were going to create a new to do button. That's the plus button that we added to the navigation bar. We could just segueway to the new control, and when we did that it made it, it gave it the navigation bar. We went ahead and added the navigation item so it would have a title and get the back functionality. Another last thing that we have to do is the tricky part of passing the managed object context down the hierarchy. Before we do that, I want to run it make sure it's working okay. Then we're going to get into the code and use this protocol that we created in the way that we meant for it to be created. All right. So, let's run it. First of all, oh, we have some warnings. So, let's check out what our warnings are. Incomplete implementation return the number of sections and incomplete implementation return the number of rows. This reflects the fact that we haven't created a delegate for our table view yet. That's okay. We don't need to do that quite yet. Let's run what we've got so far. Now we have our To Do List and our plus button. We hit our plus button and we get our new To Do view. And we can go back to our To Do List. Of course we haven't backed it by core data or anything at this point, so it's just a movement. Great. That's all we wanted to do at this point. So, let's stop that. So, the next thing that we want to do here is we want to allow these elements to move down while these managed object context to move down through our hierarchy as we are displaying the different views in the view controller. So, to do that, let's see. Let me get my notes here. All right. We know because we had added core data in the beginning that we have a lot of, and we're an app delegate now, we have a lot of core data code that was created for us automatically. And we know that here, when our application first finishes launching, this is the point at which we have a managed objects context. And we need to get a handle on that. We need to get a pointer to it. We need to send it to our navigation view controller, our navigation controller. That is our root to you controller. And so, let's see if we can get access to that. So, what we're going to do is we're going to say self.window.rootViewController. Now, this is a generic term for the first, and that initial view controller. Because of the way we set up our storyboard, we know that it's going to be an example of a myUI, my, whoops. Wait for the beach ball. Well, actually, what we're going to do is we're going to use our protocol here. So, we don't actually care what our root view controller is. But what we care about is that it is something that implements our DP handles mock protocol. All right? And so, we're going to cast it to that. So, we'll get an exception if it's not that. We know that it is our my navigation view controller. Our myUInavigation controller. Because of the way we set up our storyboard. We're going to need to implement this, but for the time being we're going to get a head of ourselves. And we're going to say that this is what we have. So, we'll say NS object dp handles lock. And this is going to be the child, and it is a pointer to that. And we're going to set that equal to the first root controller. And then, we don't recognize this, so let's include it. Give it a second to catch up. Great. And now, we should be able to say child receiveMOC. And I'm going to send it the app delegate's copy of the managedObjectContext. And then, we will return yes. And wait for our things to resolve. All right, that's terrific. Now, this assumes that our root view controller has implemented the protocol DPHandlesMOC. Now, the first one that gets hit in our view hierarchy is my UI navigation controller, and this doesn't implement it yet, so our next task is to implement it. So we're going to go into our interface and we're going to say explicitly that this implements the DPHandlesMOC interface. And we don't know what that is, and so we're going to tell the compiler what that is. And great, and then we actually have to declare that. Okay, great. And then we have to implement it. So when our application finishes launching, it will get a copy of the managed object context, and it will pass it to the root view controller, which happens to be the navigation controller. So in here we are going to say, oh, we're going to need a place to keep track of it. So we're going to keep track of it up here. And we're going to say that we're going to create a local property that is an example of the managed object context that we want to keep track of. And so it is a property that is going to be local to this class. And we are going to make it strong and nonatomic. And it is going to be an NSManagedObjectContext, and it's a pointer to that. And we are going to call it, I'll call it our managedObjectContext. All right, how's that working? Don't need these numbers, great. So that creates a local variable within our class that's going to keep track of it so that when our application calls it, we are going to keep track of it so that if we need it in order to change our Core Data objects, we have access to it. And in this way, we don't need our global singleton class, and we passed it down the chain. Now, our navigation controller. The next thing down the chain in the navigation controller is the table view. And so what we want to do is we want to pass it down the chain to the table view. And we know that the first child, the only child of our navigation controller is the table view, and so we know that it is going to. Oh. Yeah, Sam corrected me on something. Let's go back to our app delegate here. And rather than saying NSObject, let's call it an ID object that implements DPHandlesMOC like that. Okay. It's equivalent. It's a little bit more general. Okay, so the AppDelegate passes it to our navigation controller, our navigation controller receives it, and now it's going to find its child that it's going to pass it to. So it's going to be a DPHandlesMOC object, its child, and that is going to be equal to, we're going to cast it to the right thing. And we are going to look at all the view controllers that are its children. There is only one, and that is going to be the one that we have here. And then we are going to say, we're going to pass the managed object context down the chain. And we're going to pass it the self.managedObjectContext that we just created. All right. The reason why we're doing this here instead of in the segue is because the navigation controller now, as of iOS 9, apparently, doesn't actually do a segue in order to load its table view. It just creates it. Okay? Good. Our navigation controller has now passed it on to our table view. And so we need to do the same thing in our table view. Here, let's go to our navigation controller. We see that it has to handle MOC. And so we want our table view, not our table view cell, our table view controller. It is also going to have to handle the managed object context. We have to declare it. And it's going to be exactly the same code as what we had in our navigation controller. So I'm going to grab it from our navigation controller. Almost our same code. Good. That's our navigation controller. Now let's go to our table view controller. We're going to declare a local variable, which is our managed object context. We're going to go back to our navigation controller. We're going to get the code to save it. We're going to go to our table view controller and we're going to go down to the bottom where we have some space. And we are going to keep track of it here. Great. When our navigation view controller received the managed object context from the application, it immediately went and passed it down to the table view controller, because it didn't have any other way to do that, at least straightforward way. The table view in contrast is not going to pass the managed object context down to the view controller that has the details of our to-do item, it's not going to do that until there's actually a transition made. That transition is called prepareForSegue, and we have some stubbed out code here that Xcode made for us. prepareForSegue is called right before you switch to that detailed sender line. And so what we want to do is, we want to, in this code, do the work of passing our managed object context down. So it's an example of doing it in a different way. Rather than doing it in our received MOC context, we're going to do it here. All right. Let's see what we're going to do. All right. So the sender is who is sending it. And let's see. It is going to be the segue that we just received, the segue's destination view controller, so that's view controller that we're going to. What we're going to do is we're going to cast it assuming that it implements our DPHandlesMOC implementation. We will then assign that to a local variable, which we'll call the child. And then as soon, so as we're transitioning, we're going to pass our managed object context to the view controller. All right, so as we transition, the view controller is going to get it. So the last thing in this train of passing the view controller down is to go into the view controller itself and implement these same things. So we're going to come here, this is the table view controller that we just implemented, we're going to get the interface for it. And finally we're going to go to the view controller, we're going to say, okay, the view controller is going to implement that handles protocol. And we need to make sure that the compiler knows about it. We're good. Now we're going to go back to the table view controller and going to get the same code. We're going to put it in the view controller. Same place, going to go back to our TableViewController. We're going to get the local variable, going to go to our ViewController, we're going to put our local variable up here, which is where we're going to keep track of our managed object context. All right. So that is passing our managed object context down through our storyboard, starting with our application, which isn't on our storyboard. Passing it to our navigation controller, which immediately passes it to our table view controller. Which waits until the segue is invoked, at which point it passes it down to our to-do element. All right, so it should run, we shouldn't have any trouble. Let's just check what our warnings are. Okay, these are all warnings associated with our table view implementation, which we haven't gotten to yet. Let's make sure we got everything on this section that we wanted to do. Yep, so we're good to go. So that's, it should run, we shouldn't have any problem. Let's make sure it runs before we wrap up this video. All right. We don't have any errors. We hit our plus button. And when we hit our plus button, that's when that segue was invoked. And just before the segue was invoked, this view controller that has the to-do element in it received the managed object context. So there was no error. So everything went fine. We can go back. And we're good to go. So that's everything we wanted to accomplish in this video. We'll pick up again in a second. Well, in a second if you watch repeatedly. Otherwise it'll be as long as you wait until the next video. You have the locus of control. See you next video. [MUSIC]