0 1 00:00:01,070 --> 00:00:01,400 All right. 1 2 00:00:01,400 --> 00:00:10,160 So, now that we've looked at create, read, update, and delete, it's time to look at how we can carry query 2 3 00:00:10,170 --> 00:00:11,460 our Realm database. 3 4 00:00:11,480 --> 00:00:15,550 And so we're going to be working within the search bar methods. 4 5 00:00:15,590 --> 00:00:21,500 So let's go ahead and uncomment our extension and we're going to remove the parts that are Core Data 5 6 00:00:21,860 --> 00:00:28,430 and we're going to, instead, make it work using Realm. So let's comment out all of these parts that use 6 7 00:00:28,460 --> 00:00:31,810 NSFetchRequest or NSPredicate, NSSortDescriptor, 7 8 00:00:31,890 --> 00:00:35,420 all of those NSs come from our Core Aata framework. 8 9 00:00:35,420 --> 00:00:43,660 So instead, what we want to happen when the search bar gets clicked is we're going to filter our to-do 9 10 00:00:43,670 --> 00:00:45,350 list items. 10 11 00:00:45,350 --> 00:00:53,440 So we have to do items which is the array of results that consist of items and we're going to set its 11 12 00:00:53,570 --> 00:01:00,120 new value to be equal to its previous value dot filter. 12 13 00:01:00,440 --> 00:01:07,630 And you can see that this filter method from Realm takes an NSPredicate as an input, 13 14 00:01:07,820 --> 00:01:16,310 so all we're saying here is that update todoItems = todoItems filtered by this predicate. 14 15 00:01:16,310 --> 00:01:23,210 And we can specify the predicate format and arguments that we want to use for our filter. 15 16 00:01:23,270 --> 00:01:29,900 So if we hit enter, then the format is going to be the same as this format which is, of course, the fact 16 17 00:01:29,900 --> 00:01:40,400 that the title of the items CONTAINS, in big case,and diacritic insensitive, to the argument that we're 17 18 00:01:40,400 --> 00:01:45,600 going to parse in, and the argument is going to be the searchBar.text, 18 19 00:01:46,610 --> 00:01:50,630 and that is basically the equivalent of these two lines. 19 20 00:01:50,900 --> 00:02:01,880 And we can tag on this sort by simply adding a dot and write sorted by KeyPath and ascending. 20 21 00:02:01,880 --> 00:02:04,060 KeyPath is going to be title, 21 22 00:02:04,070 --> 00:02:08,750 so that's what we're going to sort our results by and ascending will set to be true. 22 23 00:02:08,930 --> 00:02:17,450 So it's alphabetical order, and that replaces all of this code. And we don't even need to call loadItems 23 24 00:02:17,870 --> 00:02:24,860 because we've already loaded our to-do list items from the selectedCategory. And we're now just simply 24 25 00:02:24,860 --> 00:02:30,420 filtering those items based on our search criteria and sort criteria. 25 26 00:02:30,800 --> 00:02:33,820 So we can go ahead and delete all of that. 26 27 00:02:33,830 --> 00:02:39,260 Now, the other part we need to fix is what should happen when we dismiss the searchBar? 27 28 00:02:39,530 --> 00:02:48,260 So when the searchBar.text goes down to zero, we want to simply call loaditems, and loaditems, again, 28 29 00:02:48,320 --> 00:02:55,900 looks at the current selectedCategory and pulls out the items sorted by the title in ascending order. 29 30 00:02:55,910 --> 00:02:58,170 So there's actually nothing to change here. 30 31 00:02:58,400 --> 00:03:03,590 So that is how easy it is to query our Realm database. 31 32 00:03:03,650 --> 00:03:09,470 We can simply take a list of items and filter them based on a predicate. 32 33 00:03:09,590 --> 00:03:15,110 And as we said in the core data module, you can take a look at the Realm NSPredicate Cheatsheet 33 34 00:03:15,470 --> 00:03:23,030 and look at some of the tips and tricks and examples as to how you can query your Realm database using these 34 35 00:03:23,090 --> 00:03:24,410 formatted strings. 35 36 00:03:24,410 --> 00:03:27,320 So, now here's a challenge for you. 36 37 00:03:27,560 --> 00:03:34,000 What if I don't want to sort my to-do list items by the title, instead, 37 38 00:03:34,070 --> 00:03:42,350 I want it to be sorted by something called the "dateCreated" and I want the items that were created earlier 38 39 00:03:42,650 --> 00:03:46,780 to show up at the top of the to-do list? 39 40 00:03:46,820 --> 00:03:50,350 So can you fix this line of code? 40 41 00:03:50,600 --> 00:03:58,880 But also, you'll need to add a new property inside our Item model in order to store that data, and that 41 42 00:03:58,880 --> 00:04:04,010 data is going to be saved when we create a new item. 42 43 00:04:04,040 --> 00:04:07,970 And finally, we're going to apply the sort over here. 43 44 00:04:07,970 --> 00:04:14,300 Pause the video and see if everything that we've done makes sense to you, so that you can create this 44 45 00:04:14,300 --> 00:04:16,350 new property and set it. 45 46 00:04:16,370 --> 00:04:22,280 Now, you might need to look up stack overflow here and there, especially when you're trying to grab the 46 47 00:04:22,280 --> 00:04:25,740 current date, but it's all very, very easy to find. 47 48 00:04:25,850 --> 00:04:30,490 And I have faith that you will be able to work it out without a problem. 48 49 00:04:30,500 --> 00:04:32,770 So pause the video and give it a go. 49 50 00:04:36,770 --> 00:04:37,270 All right. 50 51 00:04:37,290 --> 00:04:39,730 So how did that go? 51 52 00:04:40,100 --> 00:04:47,490 So the first thing that we said is that we wanted it to be sorted by the KeyPath called "dateCreated." 52 53 00:04:47,690 --> 00:04:58,000 So we have to go inside our Item data model and create a new dynamic variable that's called dateCreated 53 54 00:04:58,630 --> 00:05:06,820 and it's going to be of type date, not data, and it's going to-- And I'm going to make it an optional. 54 55 00:05:06,860 --> 00:05:12,070 So once we've done that, and then we have to go into our TodoListViewController and look at the place 55 56 00:05:12,100 --> 00:05:14,500 where we create newItems. 56 57 00:05:14,560 --> 00:05:21,760 Not only does our newItem get a title, but it's also going to get a new date. 57 58 00:05:22,100 --> 00:05:29,680 And this is going to be set to equal the current dateat the time when this block of code gets called. 58 59 00:05:29,770 --> 00:05:33,600 So let's go over to Google and let's try and see if we can figure out this problem. 59 60 00:05:33,790 --> 00:05:42,880 So the problem I want is how to get current date in Swift, maybe Swift 3, because it's not a lot 60 61 00:05:42,880 --> 00:05:45,170 of difference between Swift 3 and Swift 4. 61 62 00:05:45,190 --> 00:05:52,700 So let's hit enter. And let's have a look at the first answer that we get back from StackOverflow. 62 63 00:05:52,750 --> 00:05:59,010 How can I set a label's text to current date in Swift 3? 63 64 00:05:59,110 --> 00:06:01,900 Sounds pretty much like what we wanted, 64 65 00:06:01,900 --> 00:06:02,910 right? 65 66 00:06:02,980 --> 00:06:11,570 And you can see that the top answer with 122 votes and also ticked off as the selected answer has 66 67 00:06:11,620 --> 00:06:13,270 let date equal 67 68 00:06:13,330 --> 00:06:20,710 new instance of date, and you can format it by specifying a particular date, month, year format. 68 69 00:06:20,710 --> 00:06:23,840 Now, we don't actually care about the format, 69 70 00:06:23,890 --> 00:06:30,430 all we want is just the date. So we can use that line right here, 70 71 00:06:30,490 --> 00:06:36,220 newItem.dateCreated equals a new instance of Date. 71 72 00:06:36,610 --> 00:06:42,190 And now every new item we create gets stamped with the current date and time. 72 73 00:06:42,340 --> 00:06:49,960 So, now when we sort our to-do list items that are filtered, we can say sort by KeyPath "dateCreated." 73 74 00:06:50,440 --> 00:06:57,160 And if we want the most recent items to show up at the bottom of the to-do list, then we have to keep 74 75 00:06:57,400 --> 00:06:59,200 ascending as true. 75 76 00:06:59,560 --> 00:07:07,450 And the last thing I need to do is to simply write tableView.reloadData. 76 77 00:07:07,510 --> 00:07:08,180 That's it. 77 78 00:07:08,350 --> 00:07:12,730 So, now let's run the app and see what happens. 78 79 00:07:14,940 --> 00:07:21,540 So when you run your app, you might get this error, and you can see it's green which means that it's not 79 80 00:07:21,630 --> 00:07:23,100 quite a crash. 80 81 00:07:23,250 --> 00:07:30,800 And if you read it, it says something like 'try!' expression unexpectedly raised an error: an Error Domain 81 82 00:07:30,870 --> 00:07:32,110 Code=10. 82 83 00:07:32,280 --> 00:07:38,060 Migration is required you to the following errors. Item.dateCreated has been added." 83 84 00:07:38,100 --> 00:07:40,240 Migration is required. 84 85 00:07:40,290 --> 00:07:47,930 So to translate this what it's telling you is that you are adding this new property chordate created. 85 86 00:07:48,000 --> 00:07:56,610 But remember, if you have a look at your previous items, they don't have that property, so Xcode and Realm 86 87 00:07:56,700 --> 00:08:02,760 are both confused as to what they should do with this new property and what they should do with the 87 88 00:08:02,760 --> 00:08:05,040 items that don't have that property. 88 89 00:08:05,370 --> 00:08:10,170 And the solution to this is simply what they call migration. 89 90 00:08:10,260 --> 00:08:18,450 And in terms of Xcode, all you need to do is go to the home, click and hold your Todoey app until it starts 90 91 00:08:18,450 --> 00:08:25,140 jiggling, and then you click the cross to delete this instance of your app, and then you come back here 91 92 00:08:25,230 --> 00:08:27,910 and you run your app afresh. 92 93 00:08:28,080 --> 00:08:35,040 So, now if we go to this new Realm location, so remember we need the first forward slash, 93 94 00:08:35,220 --> 00:08:43,380 and let's go over to our Realm Browser open, and we're going to command shift G, type in the path, hit 94 95 00:08:43,380 --> 00:08:52,410 Go, click Open, click Allow. And now we find our new Realm. So you can see that this new Realm that we're 95 96 00:08:52,410 --> 00:08:56,940 using for this instance of our app is completely empty. 96 97 00:08:56,940 --> 00:08:59,610 There's no categories and there's no items. 97 98 00:08:59,610 --> 00:09:04,420 So let's go ahead and add some, Home and Work. 98 99 00:09:05,190 --> 00:09:08,230 And now we have two new categories: Home and Work, 99 100 00:09:08,340 --> 00:09:10,270 but they have no items associated. 100 101 00:09:10,410 --> 00:09:17,280 So let's go to Home and add some new items, Mop Floors, Buy Food. 101 102 00:09:17,400 --> 00:09:19,020 This is always on my mind. 102 103 00:09:19,020 --> 00:09:22,380 Not so much mop floors, but buy food is very important. 103 104 00:09:22,380 --> 00:09:27,990 So we now have two items associated with our Home category and we can view them by clicking on this 104 105 00:09:27,990 --> 00:09:28,560 link. 105 106 00:09:28,620 --> 00:09:37,230 You can see now they both have this dateCreated property associated with them, and you can see that 106 107 00:09:37,290 --> 00:09:45,690 I created Mop Floors on the 12th of December, 2017, at 14:21:01 seconds, and then four seconds later, 107 108 00:09:45,690 --> 00:09:47,240 created Buy Food. 108 109 00:09:47,460 --> 00:09:52,850 So, now if we add another one that contains the word "Food," so that we'll be able to sort it, 109 110 00:09:52,860 --> 00:09:55,950 so maybe Buy Food and Eat Food. 110 111 00:09:55,950 --> 00:09:57,600 Seems pretty logical, right? 111 112 00:09:57,600 --> 00:10:00,910 Why would you buy the food if you're not going to eat it? 112 113 00:10:01,690 --> 00:10:04,580 No, I don't actually have these items on my to-do list, 113 114 00:10:04,620 --> 00:10:07,170 even though I'm so quick at coming up with them. 114 115 00:10:07,230 --> 00:10:09,140 So, now we have Buy Food and Eat Food. 115 116 00:10:09,150 --> 00:10:12,440 So I'm going to search for the word "Food." 116 117 00:10:12,540 --> 00:10:19,860 And when I hit Search, then I end up with all of the items that contain the word "Food," but it's also sorted 117 118 00:10:19,980 --> 00:10:25,240 so that the ones I created earlier gets shown at the top of the table view. 118 119 00:10:25,260 --> 00:10:31,160 Now, if you didn't want that, then you can simply reverse the order by changing ascending to false. 119 120 00:10:31,350 --> 00:10:36,800 But essentially, it's now looking at the time stamps of each of my items and applying the sort order 120 121 00:10:37,110 --> 00:10:40,120 according to that dateCreated variable. 121 122 00:10:40,380 --> 00:10:44,430 So, now if I hit the cross button, then I go back to the main table view, 122 123 00:10:44,880 --> 00:10:51,540 and I have everything sorted here by alphabetical order. So feel free to have a play around with your 123 124 00:10:51,540 --> 00:10:59,280 code and make your app do whatever it is that you wanted to do and familiarize yourself with how Realm 124 125 00:10:59,340 --> 00:11:04,470 works with regards to CRUD and also how you can query the database.