0 1 00:00:00,300 --> 00:00:07,130 So, let's quickly refresh ourselves by going through how our app works when it's using Realm. 1 2 00:00:07,350 --> 00:00:14,550 So let's first go into our AppDelegate.Swift class and we can delete Core Data now and we can also 2 3 00:00:14,580 --> 00:00:19,070 delete all of these Core Data saving related code 3 4 00:00:19,290 --> 00:00:22,830 and I'm also going to get rid of my applicationWillTerminate. 4 5 00:00:22,980 --> 00:00:30,240 Now, I'm going to leave my realm initialization here just to catch to see if there's any errors when 5 6 00:00:30,240 --> 00:00:32,350 I initialize a new Realm. 6 7 00:00:32,460 --> 00:00:39,030 And because we're not really using it here, we can simply make this an underscore, and delete that let 7 8 00:00:39,030 --> 00:00:40,020 keyword as well, 8 9 00:00:40,140 --> 00:00:43,520 and this print statement is also giving us a warning. 9 10 00:00:43,590 --> 00:00:49,200 And in the future, we might need to find out where our Realm file is, so I'm not going to delete it, but instead, 10 11 00:00:49,200 --> 00:00:51,100 I'm just going to comment it out. 11 12 00:00:51,120 --> 00:00:55,400 So, now we have no warnings and we can safely save our AppDelegate. 12 13 00:00:55,650 --> 00:00:58,200 Now, nothing really happens inside our AppDelegate. 13 14 00:00:58,230 --> 00:01:00,700 So let's go and have a look at our Data Models. 14 15 00:01:00,750 --> 00:01:06,260 The Category data model is the first one that we created and it is a Realm object, 15 16 00:01:06,420 --> 00:01:16,290 so by subclassing this Object class, we're able to save our data using Realm, and we can specify for our 16 17 00:01:16,290 --> 00:01:23,130 classes what properties it should have. And for the Category, it has a name property. It's going to be the 17 18 00:01:23,130 --> 00:01:24,910 name of the Category. 18 19 00:01:25,110 --> 00:01:33,480 And this is a dynamic variable. So we can monitor for changes in this property while the app is running, 19 20 00:01:33,570 --> 00:01:35,880 i.e., during runtime. 20 21 00:01:35,880 --> 00:01:41,360 Even if you look at the error's pane, you can see that the Buildtime errors and there's Runtime errors. 21 22 00:01:41,370 --> 00:01:44,830 So this is before you compile and this is while your app is running. 22 23 00:01:45,030 --> 00:01:52,830 And we've also got this relationship. And it specifies that each category can have a number of items 23 24 00:01:53,400 --> 00:02:02,460 and that is a list of item objects. And Item objects are also subclassing the Realm Object and that allows 24 25 00:02:02,460 --> 00:02:09,780 them to be saved using Realm as well. And the item is a little bit more fancy, it has three properties: 25 26 00:02:10,130 --> 00:02:13,200 a title whether if it was done or not, 26 27 00:02:13,200 --> 00:02:18,070 and also now it has a dateCreated property, 27 28 00:02:18,300 --> 00:02:27,540 and finally, we specify the inverse relationship that links each item back to a parentCategory and we 28 29 00:02:27,540 --> 00:02:31,210 specify the type of the destination of the link, 29 30 00:02:31,500 --> 00:02:40,110 and we also specify the property name of the inverse relationship., and that relates to this property. 30 31 00:02:40,200 --> 00:02:46,710 So, now we can go inside our CategoryViewController, and we can see that the first thing we did is we initialize 31 32 00:02:47,040 --> 00:02:55,050 a new access point to our Realm database, and then we changed our categories from an array of category 32 33 00:02:55,050 --> 00:03:04,520 items to this new collection type which is a collection of results that our Category objects. 33 34 00:03:04,620 --> 00:03:07,920 And this is an optional so that we can be safe. 34 35 00:03:08,010 --> 00:03:14,380 And when our view first gets loaded up, we load up all of the categories that we currently own. 35 36 00:03:14,670 --> 00:03:23,040 So inside loadCategories, we set that property categories to look inside our realm and fetch all of 36 37 00:03:23,040 --> 00:03:27,090 the objects that belong to the Category data type. 37 38 00:03:27,210 --> 00:03:30,620 And then we reload our tableView with the new data. 38 39 00:03:30,900 --> 00:03:39,720 And that reloadData calls all of these data source methods again and it returns the number of categories 39 40 00:03:40,170 --> 00:03:42,110 as the number of rows. 40 41 00:03:42,210 --> 00:03:51,300 And if this is nil, i.e., if we have no categories, then we simply return one cell, and that cell is going 41 42 00:03:51,300 --> 00:03:53,880 to have a textLabel depending on whether, 42 43 00:03:53,880 --> 00:04:02,040 again, if we have any categories. If we do, then we look at the categories results collection and we pick 43 44 00:04:02,040 --> 00:04:04,880 out the one for the current indexPath.row, 44 45 00:04:05,190 --> 00:04:10,150 and we use the name property to fill up that textLabel. 45 46 00:04:10,410 --> 00:04:17,820 But if this is nil, i.e., if we didn't have any categories at all, then we simply fill that single cell 46 47 00:04:18,330 --> 00:04:22,990 with the words "No Categories Added yet," and we return the cell. 47 48 00:04:23,070 --> 00:04:32,160 Now, when we add a new item by clicking on the Add button, then we create an alert and the alert has a 48 49 00:04:32,160 --> 00:04:36,490 text field and also an Add button. When we click on that Add button, 49 50 00:04:36,510 --> 00:04:44,340 we create a newCategory that is a new Category object and we give the newCategory the name based on 50 51 00:04:44,340 --> 00:04:46,800 what the user typed into the textField. 51 52 00:04:46,920 --> 00:04:54,260 And then we call the save method to save this newCategory to our Realm database. And inside the save category, 52 53 00:04:54,660 --> 00:05:03,020 we pass in that newCategory that we created here and we call this function called realm.write to commit 53 54 00:05:03,140 --> 00:05:10,550 some changes to our Realm. And the changes we want to make is we want to add a newCategory to our Realm 54 55 00:05:10,610 --> 00:05:13,560 database and we log if there are any errors. 55 56 00:05:13,580 --> 00:05:18,320 Now, the next part is, what happens when we click on any of our cells? 56 57 00:05:18,320 --> 00:05:25,900 Well, when we click on the cells, we fire didSeletRowAt indexPath and it performs a segue the withIdentifier 57 58 00:05:25,940 --> 00:05:28,900 that takes us to the TodoListViewController. 58 59 00:05:29,330 --> 00:05:36,830 But before we do so, we create a new instance of our destinationVC and we set the destinationVC's 59 60 00:05:36,920 --> 00:05:45,830 selectedCategory property to the category at the indexPath.row that was selected which triggered 60 61 00:05:46,010 --> 00:05:47,790 this particular segue. 61 62 00:05:48,230 --> 00:05:51,410 Now, that takes us onto the TodoListViewController. 62 63 00:05:51,500 --> 00:06:01,070 And when we set this selectedCategory, i.e., during that didSet block, we call loadItems which loads 63 64 00:06:01,070 --> 00:06:09,590 up all of the to-do list items which, again, is a collection of results that are Item objects. 64 65 00:06:10,190 --> 00:06:17,660 And this gets set to be equal to the selectedCategory?.items. 65 66 00:06:17,810 --> 00:06:21,800 So remember that list of items inside Category? 66 67 00:06:22,250 --> 00:06:29,950 Well, in the selectedCategory object, it also has a bunch of items associated with it. And those items, 67 68 00:06:30,020 --> 00:06:38,420 then in turn get sorted by their title, and they are listed in alphabetical order. And then we reload 68 69 00:06:38,420 --> 00:06:46,430 the tableView to call our Datasource Methods which specifies that we should have as many cells as we 69 70 00:06:46,430 --> 00:06:50,550 have todoItems for our current selectedCategory. 70 71 00:06:50,660 --> 00:06:57,290 But if there are no items for our current selectedCategory, then we just return one cell, and that cell is 71 72 00:06:57,290 --> 00:07:06,560 going to have a textLabel based on the current item's title. And if the item.done property is true, 72 73 00:07:06,950 --> 00:07:09,080 then we give that cell a checkmark, 73 74 00:07:09,110 --> 00:07:10,780 otherwise, we give it nothing. 74 75 00:07:10,940 --> 00:07:18,650 But if there are todoItems, i.e., this is nil, then the else block triggers, and that single cell 75 76 00:07:19,070 --> 00:07:24,940 that we created up here gets populated with the text "No Items Added." 76 77 00:07:24,950 --> 00:07:32,030 Now, in the TodoListViewContoller, when we press the Add Item Button inside our UIAlert, then we 77 78 00:07:32,030 --> 00:07:38,640 look to see if our selectedCategory is nil or not, because it's an optional, remember? 78 79 00:07:38,900 --> 00:07:46,310 And if it's not nil, then we set it to have this name called currentCategory. And then we try to update 79 80 00:07:46,400 --> 00:07:54,830 our realm by creating a new item, setting the newItem's title, setting the dateCreated for the new item 80 81 00:07:54,860 --> 00:07:57,660 to be the current date and time, 81 82 00:07:57,830 --> 00:08:06,710 and then we set the currentCategory's item property to append this newItem to the end of that list. 82 83 00:08:07,100 --> 00:08:14,120 And we commit all of that to our REalm database, and then we reload our tableView with all of that new data 83 84 00:08:14,120 --> 00:08:14,930 that we added. 84 85 00:08:14,960 --> 00:08:21,320 And when we select any of the cells, then we grab a reference to the item by looking into that collection 85 86 00:08:21,320 --> 00:08:29,210 of results called todoItems, and we grab the item at the current selected indexPath.row, and then we try 86 87 00:08:29,210 --> 00:08:32,980 to update its value by using 87 88 00:08:32,990 --> 00:08:33,840 realm.write, 88 89 00:08:34,130 --> 00:08:40,830 and we toggle the item.done property to be the opposite of whatever it used to be. 89 90 00:08:41,300 --> 00:08:46,390 And then we, again, reload the data and deselect our cell. 90 91 00:08:46,490 --> 00:08:54,380 Now, finally, when we select the search bar and we type something, and we click on the searchBarSearchButton, 91 92 00:08:54,380 --> 00:09:04,730 then we update our collection of results called todoItems to a filtered version based on a predicate 92 93 00:09:05,150 --> 00:09:12,860 which says that the title of the items must CONTAIN this argument, and the argument is whatever the user 93 94 00:09:12,920 --> 00:09:14,950 entered into the searchBar, 94 95 00:09:15,200 --> 00:09:21,430 and then we sort the items by the date that they were created in ascending order, 95 96 00:09:21,590 --> 00:09:30,650 and then we reload our data. And if we dismiss our searchBar, then we call loadItems all over again. 96 97 00:09:30,650 --> 00:09:37,640 And that basically resets todoItems to all of the items inside the current selectedCategory and it's 97 98 00:09:37,640 --> 00:09:40,420 now sorted by alphabetical order. 98 99 00:09:40,430 --> 00:09:47,560 So as you can see, by using Realm, instead of Core Data, we actually vastly simplified our code. 99 100 00:09:47,780 --> 00:09:53,210 And I don't know if you'll agree with me, but I think the logic is also simpler. 100 101 00:09:53,240 --> 00:09:57,180 There is no extra classes, there's no hidden classes. 101 102 00:09:57,200 --> 00:10:04,670 All the lines of code are more human-readable like .filter, .sort, and it makes a lot more sense 102 103 00:10:04,760 --> 00:10:07,390 when you're just glancing through the code. 103 104 00:10:07,490 --> 00:10:14,060 So have a play around with Realm and it's completely your choice how you want to persist your data. And 104 105 00:10:14,150 --> 00:10:18,140 if you prefer Core Data, then that's an equally valid solution. 105 106 00:10:18,140 --> 00:10:24,290 Don't let me put you off it. But personally, I really, really like using Realm, and a lot of my colleagues 106 107 00:10:24,680 --> 00:10:25,980 also feel the same. 107 108 00:10:26,030 --> 00:10:32,810 And Realm has other benefits other than just ease of use. And you can have a look through the blog for 108 109 00:10:32,870 --> 00:10:34,920 a lot of these reasons on why. 109 110 00:10:35,120 --> 00:10:42,210 But, you know, in addition to its simplicity, it's also a lot faster than Core Data or SQLite. 110 111 00:10:42,470 --> 00:10:47,690 So if you have a look at the number of queries you can make per second to your database, you can see 111 112 00:10:47,690 --> 00:10:54,830 that Realm is almost double SQLite and it's way more than Core Data. So it has a lot of other benefits 112 113 00:10:55,160 --> 00:11:00,800 as well and it's well worth looking through the documentation, seeing what other things can you do with 113 114 00:11:00,800 --> 00:11:08,790 Realm. And, also, look at their example projects and see how far you can go with it. 114 115 00:11:08,870 --> 00:11:14,180 So that's all from me for now. In the next few lessons, we'll be styling it up for our 115 116 00:11:14,190 --> 00:11:14,630 Todoey app. 116 117 00:11:14,660 --> 00:11:19,070 Now, those lessons are completely optional because we're only going to be dealing with front-end and UI stuff, 117 118 00:11:19,250 --> 00:11:24,710 but we will be coding up and adding some libraries in order to make our app look beautiful as well as 118 119 00:11:24,710 --> 00:11:25,600 work well. 119 120 00:11:25,610 --> 00:11:28,500 So if you're interested, I'll see you for that on the next lesson.