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.
