This workshop will be retired on May 31, 2020.
Relationships Between Objects17:10 with Amit Bijlani
Learn to create to-one or to-many relationships between objects.
So oftentimes in applications, 0:00 we need to create a relationship between one object and the other. 0:02 Many times where you have data that you need to persist, 0:06 there has to be relationships created. 0:10 So in our case, we want to create a relationship between a category and 0:12 an item object, or rather we want to categorize our items. 0:17 And for that reason, we would have to create a category model object and 0:22 then create that relationship, between that item and the category. 0:26 So before we create these relationships, let's go over to the Realm Swift 0:32 documentation and under Swift. 0:36 I am going to click on models. 0:44 And under models, we have these various kinds of relationships. 0:51 We have the To-One Relationship. 0:56 So according to this documentation, it says a dog Is related to a single person. 0:58 So that's that To-One Relationship, where the dog is related to a person. 1:06 And in our case, an item is related to a category, or it belongs to a category. 1:11 So that's that To-One Relationship. 1:17 That To-Many Relationship, where a person can have many dogs, 1:20 or where it category can have many items. 1:26 So that's that To- Many Relationship. 1:30 And in this case, you need to define a list off types or 1:33 in our case, a list of items within our categories model object. 1:38 So, first let's define this category model object, 1:44 before we can create these relationships. 1:48 So let's do that. 1:50 We'll say a new file. 1:51 That's a Swift file. 1:55 We'll call it category. 1:58 And just like items, this is going to import RealmSwift. 2:03 It's going to subclass object, 2:09 if you remember when we created the item. 2:14 We subclassed object which creates a Realm model object. 2:19 And that instructs realm that these objects need to be persisted, 2:22 or can be persisted to the realm database. 2:28 So let's say dynamic var, will have a title for our category. 2:32 I'll give it the default title. 2:37 So in the case of item, we'll create another property, we'll call it category. 2:40 Which is going to be off type category and this is going to be an optional. 2:47 And this will be our To-One Relationship to category. 2:52 And just in case you have a category object and 2:59 you need to get back, the number of items within that category object. 3:02 Well, we'll create our To- Many Relationship here, 3:08 so let say let items = List <item>. 3:13 And we're basically going to. 3:21 Initialize that list and it's automatically going to assign them, 3:22 all the items that belong to that category. 3:27 So this is are To-Many Relationship to items. 3:30 So a category can have many items and an item, 3:36 can belong only to a single category. 3:39 Great. 3:43 So I have taken the liberty of creating this, CategoryTableViewController. 3:44 Which essentially will basically display all the categories, 3:50 when you click on the DetailViewController. 3:54 Let me try running this and see, I'm getting a few compiler errors here. 3:59 It's saying Category unwrapped. 4:04 So in my DetailViewController, I also added a prepare for a segue method. 4:11 Where I'm assigning it the category. 4:18 And we'll come back to this, so let me run the application and 4:22 see if we have all the nuts and bolts, for category functionality. 4:29 So, what's going on here? 4:35 While we added a new model and we added this model called category. 4:37 And we created that relationship between item and 4:42 category, so Realm knows that something is up. 4:44 Our schema, our database schema has changed. 4:49 Now we have a relationship with another entity, or another table technically. 4:52 So it needs to migrate this data. 4:58 Since we're in the early development stages of our application. 5:01 The easiest solution is to delete the app from the simulator and 5:06 then, just run it again and we should be fine. 5:10 Now if this is a production version of an app and if you have all ready deployed, 5:12 the app to the App Store. 5:17 Then what you have to do is create a migration, 5:19 just to show you how that will be done, we're not gonna be covering that. 5:23 But if you go back to the Swift documentation, 5:27 there's a link for migrations. 5:29 And this is going to explain you exactly, how you perform. 5:32 Migrations. 5:35 This is, perform your migration, defining migrations. 5:37 And how you can create different schema versions, so 5:41 that when your new version of your app is deployed. 5:44 Your users don't lose the old data that they had, 5:48 with the previous version of the schema. 5:52 So in our case, I'm just going to stop the simulator, go back here. 5:56 I don't need any of these apps, so I'm just going to reset my simulator. 6:01 And let's run our app once again. 6:09 But it didn't erase anything, I wonder why. 6:13 Well we can just long press and delete, our shopping app. 6:16 And I'll run my app once again and there we are, there it works. 6:21 So now if I add and I click on category, 6:27 it's gonna show me my category table view controller. 6:31 Now, we have a couple of problems here. 6:35 We still haven't figured out exactly, how to pre-populate the data. 6:37 We have to category. 6:44 But we have not seeded our database with any categories, 6:46 that's why that category table view controller, was showing blank. 6:50 So, we can quickly create a function, 6:56 let's say func loadCategories (in realm). 7:00 So we'll actually taking the realm database. 7:06 As a parameter and 7:09 while we're in the right transaction, will just throw it back. 7:12 We're not going to handle any errors that come along, 7:17 while writing to the realm database. 7:21 So say let categories, so we'll create an array of categories, and 7:25 we'll create an instance of category. 7:30 So one of the initializers is value, which takes in a dictionary. 7:36 So we'll say title. 7:43 Since this is a grocery shopping app, 7:49 we'll pass it all the grocery aisle or grocery categories. 7:52 I'll just copy a few categories so you don't have to sit and 7:57 watch me, type over here. 8:00 So this is an array of categories. 8:03 And then we'll begin a write transaction. 8:09 Before I do that, let me just see what these errors are about. 8:13 Says cannot invoke initializer of type category with an argument list. 8:17 I'm missing a parentheses, over here, so there we go. 8:23 So that solves that problem. 8:29 We'll say realm.beginwrite. 8:30 We're going to batch our write transactions, so 8:37 instead of just putting everything inside a write block. 8:40 We'll loop through our categories array, so we'll say for 8:43 category in the categories. 8:48 And we'll add those objects, to our realm database. 8:52 And then, once we have finished adding everything, 8:59 we're going to commit our write transaction. 9:02 Note that, this right here throws an error. 9:05 It says call can throw, but not marked with try. 9:09 So we're going to add try. 9:14 And note that we had put throws over here in our function, so 9:16 we're basically re-throwing. 9:20 Any errors that are thrown by the committing to write. 9:22 So we're not catching any errors in our method load categories, 9:26 we're just gonna take them and throw it back. 9:30 To whoever is calling this methods, or this static function. 9:33 So going back into our app delegates, 9:37 we'll create a function called seedCategories. 9:40 So in our did finish launching, let's create this method call seedCategories. 9:46 So inside seedCategories, we need to get an instance off realm try realm. 9:58 Once again, we're going to put it inside a do catch block. 10:10 And then we'll say if realm.objects 10:23 of type (category.self).count == 0. 10:30 So if there are no category objects in our realm database, 10:40 then please try and load some categories. 10:46 Calling this static function that we just wrote. 10:51 Perfect. 10:55 Compiler's complaining, that unresolved identifier. 10:59 So, we need to import RealmSwift over here. 11:04 So this is how you seed data, into your realm database. 11:13 You need to first check, if there are any objects in that database. 11:17 If not, then you load them. 11:20 So let's run our application and see, if we have any categories. 11:23 It'll say apples and we'll have six of those. 11:32 And then category, there we go. 11:38 All our categories and so the produce. 11:40 And it does select it, but nothing really happens. 11:43 So let's see what's going on. 11:48 We go to our CategoryTableViewController and in the did select row, 11:50 we're calling a protocol on our delegates. 11:57 So in our DetailViewController, I created a DetailViewControllerProtocol. 12:04 And I have a function called here as selected. 12:09 So once you selected, 12:12 it should assign that SelectedCategory to our selectedCategory property. 12:14 But it's not doing that. 12:21 So let's see what's going on. 12:23 I haven't really implemented that protocol. 12:26 So let's look at it quick implementation of this protocol. 12:30 I create an extension off DetailViewController. 12:34 And we're going to implement the DetailViewControllerProtocol. 12:40 And we're going to implement that selected method. 12:46 So we'll say selectedCategory = category. 12:50 And then, categoryButton.setTitle 12:56 (category.title for 13:04 state normal). 13:08 And then finally, we're going to call dismiss. 13:13 Yet another reason why creating this method, was helpful. 13:20 We can call it from several different places and 13:26 the way you dismissed this, ViewCcontroller is useful. 13:29 Where actually in this case, we're dismissing the CategoryViewController. 13:33 But the code is exactly the same, 13:37 you're popping the view controller from the navigation controller, perfect. 13:39 All right so let's run and see, hopefully this works. 13:46 We have apples, six apples, and I wanna categorize it as produce. 13:52 So it still didn't work and I think I know what the problem is. 14:01 Because we're not setting the delegate. 14:05 So it doesn't know that we have set the delegate and it cannot be call, 14:07 this function that we. 14:11 Just implemented. 14:13 So these are all the problems that you encounter, when you're coding. 14:23 So there we go we selected a category, produce, then I hit done. 14:27 What about it saving that category? 14:35 So we haven't done that yet. 14:40 So let's go back to our DetailViewController and 14:42 in our updateItem and insertItem, let's make sure that we. 14:47 Are assigning our selectedCategory. 14:56 So now when we select a category, 15:06 it should assign that as a property to our item. 15:09 I have to hit done and there we go. 15:19 It shows produce and if I insert something new. 15:23 Lets say an item that we wanted to add previously, clorox. 15:28 Now we'll just put that under miscellaneous. 15:36 And there we go. 15:40 It did assign that category, called miscellaneous. 15:42 So we were successfully able to create relationships, between our model objects. 15:46 And display those relationships. 15:51 Now you can take this assignment a step further and 15:53 displayed these categories, in your TableViewController. 15:56 Figure out how you would go about doing that. 16:02 Maybe you would display all the categories and then, using this. 16:06 Too many relationship, you could display all of the items, 16:11 within that particular category. 16:15 So maybe that is an assignment, that you can easily achieve. 16:19 In your MasterViewController. 16:22 Instead of items, you would have categories and 16:26 then, you would display section titles. 16:29 Which would be the names of the categories. 16:32 And within those categories, you would display all the items, 16:34 within those categories. 16:37 Think this is a great exercise to take your knowledge another step further. 16:39 So that you can apply what you have learned, throughout this workshop. 16:43 >> Realm is a fast modern database, made specifically for mobile devices. 16:47 You can use it either with Swift or Objective C to work with it. 16:53 If you're unhappy, with the unnecessary complexity core data provides. 16:58 Or the rigidity of SQLite, then I recommend using Realm for 17:01 your next project. 17:05 It's easier to learn and easier to maintain in the long run. 17:07
You need to sign up for Treehouse in order to download course files.Sign up