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