2.3 Display Data With Fetch Requests
Fetch requests are made on table views. They are very easy to set up, and they interact well with row-based data. In this lesson we will hook a fetch request up to our quiz view controller.
1.Introduction2 lessons, 04:06
2.Core Data9 lessons, 1:04:07
3.Conclusion1 lesson, 00:53
2.3 Display Data With Fetch Requests
Hi, and welcome back to get started with Core Data. In this lesson, we are going to hook up a table view controller to our Core Data stack. Before we start, we have to create a Core Data stack in our application delegate. I'm creating it here so we can hand it over to all controllers in our application, starting with the root controller. I'm going to set an internal variable on the class and add the initialization in application that finish loading. There I'm creating an escalated state, then I can set it on the controller. In the controller class, I'm going to import Core Data at the top, and add another internal variable to it of type Core Data stack, which is an optional, as it won't be set during initialization. Now it's time to do the Core Data integration. We are going to use a fetched results controller for this. It handles fetching requests from the context and returns them in a table a few compatible formats, meaning it has sections and rows. Let's create an initializer for the fetched results controller. And let me make a little bit more room here. First, we need a fetch requests. If you will, this is like a query object. A fetch request needs the entity name it wants to fetch. Then we can have one or more sort descriptors. In our case, we want to sort by date, newest first. Since the request always expects an array, we have to wrap a single sort descriptor. Now we can initialize the fetched results controller with the fetch request. It also needs to managed object context. We can get that from the Core Data stack. Since this could be reset, I'm not going to start a context in a variable. I'm using the main queue context, since we are interacting with the user interface. I don't need a section key path since we don't have any sections. But if you, for instance, show a list of cities, you could group them by counties and use this as the section key. I'm also using a cache name here. But we will talk about performance in a later lesson in detail. I'm also making this table view controller the delegate of the fetched results controller, since we want to update the user interface when the values change. Now it's time to execute the fetch by calling perform fetch on the controller. It can throw, so I'm wrapping it in a do catch block. Again, you should handle the arrow gracefully here. Since we set the delegate, you must ensure that the controller conforms to the protocol. The delegate can implement a few functions. The first one is controller will change content, here we can tell the table view, hey, I'm going to update you. The matching functions we'll change is control of the change. Here we tell the table view, that we have finished updating by calling the endUpdates on it. There are two more functions, one where we did change section, which we don't need, and it change object. When an object gets changed, there are four possible cases that can happen. When inserting a new row, we can call insert rows at index path and put the unwrapped new index path variable in an array. It also takes zero animation. I'm always going to use fade in our class project. The next case is delete. It is almost the same, delete rows at the index path, but this time, we are using the index path variable. This one is present when there are already is a row. Then we have update, which we'll call configure cell function. I'm going to create to configure a cell of a quiz entity. Finally, we have move. I'm going to delete and insert again, but there would also be a move row at index path function. Those three functions and the initialization is all it takes to implement a successful connection between core data and a table field. We just have to change some functions that are already present. Number of sections in table view returns the section count of all data sets. We could return one, but I'm going to do this dynamically. Let's grab the sections from the fetched results controller and get the count. The number of rows and section function is a bit more difficult. We can get the sections as a fetched result section in full array and pick the section we are requesting. It has the number of objects property we can return. Finally, we need to configure the cell. In cell for all at index path, we can just call configure cell like in a delegate method. There we fetched a quiz object, And set the text label to name. Since the date is optional, I'm wrapping it, and then if let close and set detail text label there. To properly format it, I'm going to use an instance wired and a state formatter object. I can set the date and time styles and view that load. Back in our configure cell function, I can call string from date, and it will format the date properly. One thing I forgot and yet delegate, is to make the core data stack optional as well. By the way, if you ever get an error saying that there's no initializer for the class, you're probably forgot to set a variable. Let's compile and run. There is an error because I didn't call the initialize fetched results controller function. Let's do that and view will appear. Well, the list is blank, but we don't have any data yet. Since we didn't get an error at any point, I'm sure it will work. We'll find out about that in the next lesson. There, we will implement the create screen for a quiz and store the data in our database. See you there.