0
1
00:00:00,800 --> 00:00:01,200
All right.
1

2
00:00:01,220 --> 00:00:08,370
So in the last lesson, we looked at how you can install, setup, and configure Realm to be our method of
2

3
00:00:08,460 --> 00:00:10,260
persisting data.
3

4
00:00:10,260 --> 00:00:16,650
Now, in this lesson, I'm going to delete all of this so that we don't keep adding the same piece of data
4

5
00:00:16,980 --> 00:00:18,780
into our Realm.
5

6
00:00:18,930 --> 00:00:23,420
And I'm also going to delete this try realm.write.
6

7
00:00:23,430 --> 00:00:29,790
Now, I'm going to leave this do-catch block where we initialize our brand-new Realm. And let's not worry too
7

8
00:00:29,790 --> 00:00:32,270
much about these warnings for now.
8

9
00:00:32,310 --> 00:00:40,780
So I'm going to go ahead and delete this Data class that we created that we use as just as an example,
9

10
00:00:40,920 --> 00:00:48,150
and I'm going to replace this Core Data data model with a class called Category and a class called Item.
10

11
00:00:48,150 --> 00:00:53,910
So let's go into our Data Model folder, hit command Nto create a new Swift file
11

12
00:00:53,910 --> 00:00:58,750
and this is going to be called Item and we're going to hit Create,
12

13
00:00:59,100 --> 00:01:05,050
and then I'm going to create another one called Category and hit Create.
13

14
00:01:06,270 --> 00:01:13,440
So now we have both of our entities, or in this case, classes and we're going to use them to represent
14

15
00:01:13,590 --> 00:01:19,140
all the properties and relationships that we've specified inside Core Data.
15

16
00:01:19,140 --> 00:01:28,470
So inside Item, I first have to import Realm Swift in order to use it, and then I'm gonna create a new
16

17
00:01:28,470 --> 00:01:37,050
class called Item and the superclass is going to be a Realm Object. And it's going to have two properties.
17

18
00:01:37,260 --> 00:01:45,030
one which is the title, which is going to be a String, that's going to start off as empty.
18

19
00:01:45,360 --> 00:01:51,440
And the other one is going to be the property done which is going to be a Boolean and this is going
19

20
00:01:51,440 --> 00:01:53,390
to start off as false.
20

21
00:01:53,550 --> 00:02:01,290
And, remember, in order to create properties using Realm, we have to add the @objc modifier and
21

22
00:02:01,380 --> 00:02:04,590
also the dynamic keyword.
22

23
00:02:04,590 --> 00:02:08,600
So let's go ahead and add that to both of our properties.
23

24
00:02:08,640 --> 00:02:15,990
And now this is a complete representation of our item entity using properties instead of attributes.
24

25
00:02:15,990 --> 00:02:23,760
Now,  you'll see that it gives you an error saying that this is an invalid redeclaration of Item.
25

26
00:02:23,790 --> 00:02:26,170
So it's saying that there's already a class called Item,
26

27
00:02:26,190 --> 00:02:27,630
but where where is it?
27

28
00:02:27,630 --> 00:02:29,450
I don't see another class called Item.
28

29
00:02:29,610 --> 00:02:31,050
What's going on here?
29

30
00:02:31,050 --> 00:02:35,430
Well, do you remember that we said when you create a new data model using Core Data,
30

31
00:02:35,700 --> 00:02:43,140
If you select the entity and you select Coadegen as Class Definition, then it's going to create a class
31

32
00:02:43,230 --> 00:02:49,440
called Item with these properties, or much the equivalent to that?
32

33
00:02:49,440 --> 00:02:56,370
So you could either select Codegen Manual/None in order to not generate those Class Definitions, or in
33

34
00:02:56,370 --> 00:03:02,220
our case, we're actually just going to delete our Data Model because not going to be the one that we're
34

35
00:03:02,220 --> 00:03:04,370
going to use from now on.
35

36
00:03:04,380 --> 00:03:07,170
So I'm going to right click and hit Delete.
36

37
00:03:08,160 --> 00:03:10,230
So, now it no longer exists,
37

38
00:03:10,320 --> 00:03:16,950
and if we hit command B to build and, essentially, refresh, then that will get rid of that error where it
38

39
00:03:16,950 --> 00:03:20,640
says that this item class is a redeclaration.
39

40
00:03:20,640 --> 00:03:26,520
Now, we'll end up with more errors because, remember, for most of our view controllers, we're using our
40

41
00:03:26,520 --> 00:03:31,890
Core Data NSManagedObjects, and now we're switching it to Realm objects,
41

42
00:03:31,890 --> 00:03:34,550
so there's going to be a little bit of fixing in there.
42

43
00:03:34,710 --> 00:03:38,880
But let's first finish creating our Data Models.
43

44
00:03:38,970 --> 00:03:43,330
So we've done that for item, and now we have to move on to category.
44

45
00:03:43,600 --> 00:03:48,810
And I'm actually going to just change the order here because it's Category then Items, and that makes
45

46
00:03:48,810 --> 00:03:50,460
a little bit more sense to my brain.
46

47
00:03:50,460 --> 00:03:59,850
So as a challenge, I'd like you to set up your Category data model to include a property called name which
47

48
00:03:59,850 --> 00:04:06,930
is going to be of data type string and it's going to start off with the value of an empty string.
48

49
00:04:06,990 --> 00:04:09,140
So go ahead and pause the video and give it a go.
49

50
00:04:11,170 --> 00:04:11,530
All right.
50

51
00:04:11,540 --> 00:04:14,210
So that is pretty simple task.
51

52
00:04:14,210 --> 00:04:20,870
All we have to do in order to use Realm is, of course, import Realm Swift, and then we're going to create
52

53
00:04:20,900 --> 00:04:29,930
a new class that's called Category and it's going to inherit the Object class, and the code in here is
53

54
00:04:29,930 --> 00:04:36,140
going to be an Objective-C modifier and the dynamic keyword,
54

55
00:04:36,140 --> 00:04:39,110
and then we're going to say var name,
55

56
00:04:39,110 --> 00:04:41,680
name of the category, which is going to be a string,
56

57
00:04:41,710 --> 00:04:44,500
and it's going to start off being an empty string.
57

58
00:04:44,540 --> 00:04:44,780
All right.
58

59
00:04:44,810 --> 00:04:45,580
So that's it.
59

60
00:04:45,620 --> 00:04:46,460
That was done.
60

61
00:04:46,460 --> 00:04:47,710
Did you manage to get that?
61

62
00:04:47,810 --> 00:04:56,150
Now, in addition to having these properties, if you remember, our Data model using Core Data also had relationships
62

63
00:04:56,450 --> 00:05:03,350
where we could specify that categories point towards items and items point back to categories.
63

64
00:05:03,350 --> 00:05:07,400
So let's go ahead and see how we can do that using Realm.
64

65
00:05:07,430 --> 00:05:15,890
Now, the forward relationship is the easiest, and it's as simple as creating a constant called items and
65

66
00:05:15,890 --> 00:05:20,510
it's going to be set to a collection type called List.
66

67
00:05:20,510 --> 00:05:22,460
And this is something that comes from Realm.
67

68
00:05:22,550 --> 00:05:28,250
And it's basically a container type just as array or dictionaries are container types.
68

69
00:05:28,310 --> 00:05:33,370
But this is something that they decide called List which is very, very similar to a raise.
69

70
00:05:33,370 --> 00:05:40,580
Now, if we create a new list, we also have to specify what is the data type of the items inside the List
70

71
00:05:40,580 --> 00:05:42,380
or inside the array.
71

72
00:05:42,620 --> 00:05:46,910
And in our case, it's going to be a whole bunch of Item objects.
72

73
00:05:47,030 --> 00:05:54,260
So this syntax may or may not be familiar to you, but when we create new arrays, so let's say, let's create
73

74
00:05:54,290 --> 00:05:58,430
let array equals, I don't know, 1, 2, 3.
74

75
00:05:58,430 --> 00:06:00,650
This is one way of declaring the array,
75

76
00:06:00,680 --> 00:06:03,370
so this uses type inference,
76

77
00:06:03,380 --> 00:06:04,050
right?
77

78
00:06:04,190 --> 00:06:05,660
But the other way of doing it.
78

79
00:06:05,690 --> 00:06:12,040
We could also say that this is an array of integers and we're going to initialize it as an empty array.
79

80
00:06:12,140 --> 00:06:19,070
And the other way still is that we can simply say, the array is going to be of type an array of integers,
80

81
00:06:19,310 --> 00:06:22,000
and it's going to be equal to one two three.
81

82
00:06:22,010 --> 00:06:23,470
That's perfectly valid.
82

83
00:06:23,540 --> 00:06:33,530
Now, a method that we haven't seen so far is we can also declare this as the type Array and say that
83

84
00:06:33,740 --> 00:06:36,650
it is going to contain an array of integers.
84

85
00:06:36,650 --> 00:06:40,220
Now, this and the previous syntax are both valid.
85

86
00:06:40,250 --> 00:06:50,570
So if you wanted to declare a empty array of integers, you could also do it like so by simply initializing
86

87
00:06:50,570 --> 00:06:53,540
it as an empty array of integers.
87

88
00:06:53,540 --> 00:06:56,570
Now, this is exactly what we're going to do here.
88

89
00:06:56,570 --> 00:07:03,530
We're going to create this constant called Items and it's going to hold a list of item objects and we're
89

90
00:07:03,530 --> 00:07:06,600
going to initialize it as an empty list.
90

91
00:07:06,800 --> 00:07:11,510
So I'm just trying to show that this is not some foreign sort of syntax.
91

92
00:07:11,660 --> 00:07:14,000
It's actually something that's perfectly Swifty.
92

93
00:07:14,300 --> 00:07:20,900
And the only thing that's foreign is this class List which is something that comes from our Realm framework.
93

94
00:07:20,900 --> 00:07:28,430
So this, essentially, defines the forward relationship, i.e., inside each Category,
94

95
00:07:28,430 --> 00:07:36,060
there's this thing called items that's going to point to a list of Item objects.
95

96
00:07:36,260 --> 00:07:41,750
Now in Realm, the inverse relationship is not defined automatically.
96

97
00:07:41,750 --> 00:07:46,840
Instead, you actually have to go inside the Item class and create it yourself.
97

98
00:07:46,850 --> 00:07:48,380
So let's do that now.
98

99
00:07:48,410 --> 00:07:56,840
So we called our inverse relationship parentCategory and it's going to be set to an object of the class
99

100
00:07:56,960 --> 00:08:06,260
LinkingObjects. And LinkingObjects are auto-updating containers that represent zero or more objects
100

101
00:08:06,380 --> 00:08:11,090
that are linked to its owning model object through a property relationship.
101

102
00:08:11,090 --> 00:08:17,360
Now that sounds really, really complicated, but it's actually not. It's simply defining the inverse relationship
102

103
00:08:17,510 --> 00:08:18,410
of items.
103

104
00:08:18,410 --> 00:08:27,920
So each category has a one to many relationship with a List of I tems and each item has an inverse relationship
104

105
00:08:28,010 --> 00:08:31,160
to a category called the parentCategory.
105

106
00:08:31,160 --> 00:08:38,000
And we have to initialize LinkingObjects with a type and a property name.
106

107
00:08:38,000 --> 00:08:43,430
So the type is going to be whatever object that we have .type.
107

108
00:08:43,430 --> 00:08:48,100
So if we simply wrote Category, then this is just the class.
108

109
00:08:48,140 --> 00:08:49,910
It's not actually the type.
109

110
00:08:49,910 --> 00:08:54,100
In order to make it the type of Category, we have to say .self.
110

111
00:08:54,170 --> 00:08:56,720
And that becomes the Category type.
111

112
00:08:56,990 --> 00:09:04,580
And then the property that we need to specify is what is the name of that forward relationship which
112

113
00:09:04,580 --> 00:09:06,670
is, of course, items.
113

114
00:09:06,680 --> 00:09:15,310
So all we have to say here is specify a string called "items" that points to the forward relationship.
114

115
00:09:15,310 --> 00:09:18,610
So, now we have the forward relationship,
115

116
00:09:18,730 --> 00:09:25,870
each Category having a list of items. And the reverse category, each item has a parentCategory that is
116

117
00:09:25,870 --> 00:09:27,880
of the type Category
117

118
00:09:27,880 --> 00:09:29,900
and it comes from that property
118

119
00:09:29,910 --> 00:09:30,900
called "items."
119

120
00:09:30,910 --> 00:09:38,350
So now we're ready to go and fix all of these errors and use our Realm data model, instead of our Core
120

121
00:09:38,350 --> 00:09:39,670
Data data model.
121

122
00:09:39,670 --> 00:09:46,220
So let's head over to CategoryViewController and we're going to, first, initialize a new Realm.
122

123
00:09:46,270 --> 00:09:52,300
So we're gonna say let realm = try! to initialize a new Realm.
123

124
00:09:52,300 --> 00:10:00,040
Now I know that we've always been cautious with the exclamation marks, as you should be, but not all cases
124

125
00:10:00,100 --> 00:10:02,710
of try exclamation mark are bad.
125

126
00:10:02,740 --> 00:10:09,940
So this is what you would call a code smell or bad smell, and it's something that indicates or hints
126

127
00:10:10,000 --> 00:10:16,360
at possibly bad code, and maybe a deeper problem, but not always.
127

128
00:10:16,360 --> 00:10:21,610
So just as while you're walking around and you smell something that smells really bad, it could be a dead
128

129
00:10:21,610 --> 00:10:24,490
body or it could be just the trash,
129

130
00:10:24,490 --> 00:10:25,260
right?
130

131
00:10:25,300 --> 00:10:28,320
And in this case, it's actually not an issue.
131

132
00:10:28,360 --> 00:10:36,370
The reason why this initialization throws or can throw an error is because according to Realm, the first
132

133
00:10:36,370 --> 00:10:42,030
time when you're creating a new Realm instance, it can fail if your resources are constrained.
133

134
00:10:42,160 --> 00:10:48,070
But in practice, this can only happen the first time a Realm instance is created on a given thread.
134

135
00:10:48,070 --> 00:10:55,840
So if you look at the Realm documentation, then this is a perfectly valid way of declaring and creating
135

136
00:10:55,900 --> 00:10:56,910
a new Realm.
136

137
00:10:56,920 --> 00:11:02,290
So if you're interested in that, then I'll link to the documentation and you can have a deeper read.
137

138
00:11:03,010 --> 00:11:09,190
Xcode is still giving us this error saying "Use of unresolved identify 'Realm,'" and that is because,
138

139
00:11:09,190 --> 00:11:13,640
of course, that we've got to use Realm, instead of Core Data.
139

140
00:11:13,810 --> 00:11:18,610
So I'm just going to replace that which is going to create more errors for me,
140

141
00:11:18,910 --> 00:11:22,540
but we're going to go and fix those steadily one by one.
141

142
00:11:22,540 --> 00:11:31,870
Let's go into the parts of our code where we create a new piece of data inside our database and that
142

143
00:11:31,870 --> 00:11:38,800
is, of course, inside the addButtonPressed and it's--and more specifically, it's in this closure when
143

144
00:11:38,800 --> 00:11:42,520
we press the Add button in that UIAlert.
144

145
00:11:42,580 --> 00:11:49,450
So whereas currently, we're creating this new category which was initialized using a context because
145

146
00:11:49,450 --> 00:11:54,010
we were using Category as a NSManagedObject.
146

147
00:11:54,010 --> 00:12:01,840
But now our category is just going to be a straight up object from the Category data model.
147

148
00:12:01,840 --> 00:12:07,870
And the new category also has a property code name because we defined it over here, and that's going
148

149
00:12:07,870 --> 00:12:12,610
to be set to equal the text that's currently inside the textField of the UIAlert.
149

150
00:12:12,610 --> 00:12:18,640
And finally, all we have to do is change this saveCategories method, because at the moment, it tries to
150

151
00:12:18,640 --> 00:12:28,690
save the context. Whereas what we need to do is to try to write to our Realm, so try realm.write
151

152
00:12:28,750 --> 00:12:37,300
and we're going to try to say realm.add category, and that is going to be the new category,
152

153
00:12:37,300 --> 00:12:37,540
right?
153

154
00:12:37,600 --> 00:12:41,050
So that will need to be passed in to this method.
154

155
00:12:41,050 --> 00:12:48,610
So let's replace this method to be called save and it's going to take something called a Category, and
155

156
00:12:48,610 --> 00:12:54,370
that is going to be of type Category, and that will then get passed in here,
156

157
00:12:54,370 --> 00:13:02,110
and we now have to fix the part where we call that method. And we're going to say save category is going
157

158
00:13:02,110 --> 00:13:06,580
to be the newCategory that we just created over here.
158

159
00:13:06,580 --> 00:13:12,220
So, now if we hit command B to refresh and try to get rid of some of the errors that don't actually belong
159

160
00:13:12,220 --> 00:13:15,530
here, then our IBAction is looking pretty clean.
160

161
00:13:15,640 --> 00:13:22,690
Now, we've still got some other errors in this code and also in our TodoListViewController. But I'm
161

162
00:13:22,690 --> 00:13:29,470
going to simply comment out all of this and I'm gonna go into the TodoListViewController and find
162

163
00:13:29,950 --> 00:13:38,740
those errors, and we're also going to comment that out, and I'm going to comment out this particular function,
163

164
00:13:39,040 --> 00:13:41,910
as well as this entire extension.
164

165
00:13:41,950 --> 00:13:48,640
And finally, we're going to also come on out the loaItems and I'm going to hit run to see if we can
165

166
00:13:48,970 --> 00:13:50,110
build our app.
166

167
00:13:50,200 --> 00:13:50,580
Okay.
167

168
00:13:50,590 --> 00:13:59,380
So currently, all that our code should be able to do is when we press the addButtonPressed, we should
168

169
00:13:59,380 --> 00:14:06,820
get a UIAlert, and if we type some text into the UIAlert, then it should create a new object from the
169

170
00:14:06,820 --> 00:14:15,620
class Category, and we should be able to save that category into our Realm container by using realm.write
170

171
00:14:15,670 --> 00:14:16,850
and realm.add.
171

172
00:14:16,920 --> 00:14:18,130
So let's give it a go.
172

173
00:14:18,190 --> 00:14:29,270
Let's press Add and let's create a new category called Home and add one called Work. And if we have a look
173

174
00:14:29,300 --> 00:14:35,270
inside our Realm Browser, then you can see that we've got three data models now. So Data is a little bit
174

175
00:14:35,270 --> 00:14:42,290
of a relic back from when we created it in our App Delegate. An item is empty because we've yet to implement
175

176
00:14:42,290 --> 00:14:44,630
any code inside the TodoListViewController.
176

177
00:14:45,320 --> 00:14:54,680
But our Category model has two new objects, one with the name Home, one with the name Work, and they have
177

178
00:14:54,680 --> 00:14:58,140
an associated list of items.
178

179
00:14:58,160 --> 00:15:06,320
Now, the list currently is zero, but as soon as we start assigning some items to that list, then these will
179

180
00:15:06,320 --> 00:15:08,780
be populated as we'll see a little bit later on.
180

181
00:15:08,840 --> 00:15:15,680
But what we can confirm is that our code worked and we were able to save and persist our categories.
181

182
00:15:15,710 --> 00:15:24,980
So now all that's left to do is to load our data, not from our context or Core Data, but from our realm.
182

183
00:15:24,980 --> 00:15:28,850
So for all of that and more, I'll see you on the next lesson.
