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.
