0 1 00:00:00,540 --> 00:00:00,880 All right. 1 2 00:00:00,900 --> 00:00:07,380 So in this module, we're going to look at how we can use Realm to persist our data, instead of using Core 2 3 00:00:07,380 --> 00:00:07,830 Data. 3 4 00:00:08,790 --> 00:00:15,450 If you have never come across Realm, then it's a good idea to familiarize yourself with it by going to 4 5 00:00:15,450 --> 00:00:23,280 realm.io. And they've got a whole bunch of educational resources, as well as tutorials, example apps, 5 6 00:00:23,400 --> 00:00:26,210 and also a really, really good documentation. 6 7 00:00:26,220 --> 00:00:32,610 So what we're going to be using is the Realm database which is an alternative to SQLite 7 8 00:00:32,610 --> 00:00:39,420 and Core Data, and it's also open source which is great because if you wanted to dig in and look at how they implemented 8 9 00:00:39,690 --> 00:00:41,920 their core, then you can do that. 9 10 00:00:41,940 --> 00:00:48,870 So we're going to head over to Products, Realm Database, and we're going to pick our language as Swift, 10 11 00:00:48,960 --> 00:00:52,080 and this takes us to the Swift documentation. 11 12 00:00:52,410 --> 00:00:59,550 So if you wanted to look at the source code, then you can go to Realm Swift and you can dig through all 12 13 00:00:59,550 --> 00:01:03,420 of these files. But I'm going to show you how to get started. 13 14 00:01:03,480 --> 00:01:10,620 So in order to install Realm, there's three ways. You can either download the Framework or use CocoaPods, 14 15 00:01:10,740 --> 00:01:12,160 or use Carthage. 15 16 00:01:12,300 --> 00:01:15,150 And I, as always, favor CocoaPods. 16 17 00:01:15,150 --> 00:01:17,420 Look at how short it is compared to everything else. 17 18 00:01:17,460 --> 00:01:19,350 And so this is what we're gonna be using. 18 19 00:01:19,410 --> 00:01:22,080 So let's head over to our project. 19 20 00:01:22,080 --> 00:01:23,520 We're going to close it. 20 21 00:01:23,590 --> 00:01:28,710 Going to open up Terminal and we're going to locate our Todoey folder, 21 22 00:01:28,740 --> 00:01:35,310 so the one that, of course, contained the Todoey.xcode project, and then we're going to cd to it. 22 23 00:01:36,900 --> 00:01:42,270 And if you're interested in speeding up your workflow, you can actually change commands in the Terminal 23 24 00:01:42,270 --> 00:01:44,920 together by just using a semicolon. 24 25 00:01:44,940 --> 00:01:53,610 So we're going to change directory to the Todoey folder, and then we're going to perform "pot init" at 25 26 00:01:53,610 --> 00:02:02,300 that location, and then we're going to say open Podfile in the application code Xcode, and we're gonna 26 27 00:02:02,310 --> 00:02:10,940 hit enter. And now it should go through and perform all of those things bringing us to our Pod file. 27 28 00:02:10,950 --> 00:02:18,120 o now I'm going to uncomment this line, so that we're targeting platform iOS 9.0 and above 28 29 00:02:18,210 --> 00:02:26,280 and we are going to use frameworks. And the Pods that we're going to incorporate is one called 29 30 00:02:26,820 --> 00:02:32,290 pod 'RealmSwift' and this has dependencies 30 31 00:02:32,300 --> 00:02:35,380 so we'll also pull in the Realm framework as well. 31 32 00:02:35,580 --> 00:02:43,290 So we're going to hit save, close that down, and go back in here, and say "pod install." All right. 32 33 00:02:43,320 --> 00:02:49,650 So after a little bit of waiting, you can see it's now done, and it's installed the latest versions of 33 34 00:02:49,650 --> 00:02:56,760 Realm and Realm Swift by just simply saying Pod Realm Swift. Now, currently, the latest version of Realm Swift 34 35 00:02:56,850 --> 00:03:04,030 is 3.0.2 and that is the version that we're pulling in through CocoaPods as well. 35 36 00:03:04,410 --> 00:03:10,770 So just check and confirm, and then we can close down Terminal and we're going to go back into Finder 36 37 00:03:10,860 --> 00:03:14,640 and open up our text code workspace file. 37 38 00:03:14,640 --> 00:03:14,970 All right. 38 39 00:03:15,000 --> 00:03:20,760 So here's our brand new Xcode project with those pods incorporated 39 40 00:03:20,760 --> 00:03:25,860 and let's just expand all of our folders so that we can see it clearly. 40 41 00:03:25,890 --> 00:03:33,900 And as you can see, as soon as we install Realm, we've got this warning in our status bar here. 41 42 00:03:33,930 --> 00:03:40,710 And it says that your pods including the Realm and Realm Swift need to be updated to recommend settings. 42 43 00:03:40,710 --> 00:03:46,890 This is not a problem though because if we just click on this warning, then it will update all of these 43 44 00:03:46,890 --> 00:03:52,270 things automatically for us. I'm going to hit perform changes and it's all good to go. 44 45 00:03:52,350 --> 00:03:53,460 And that's it. 45 46 00:03:53,460 --> 00:03:54,030 All right cool. 46 47 00:03:54,360 --> 00:04:00,450 Okay, so the first thing that we're going to do is we're going to go over to our AppDelegate and we're 47 48 00:04:00,450 --> 00:04:06,110 going to try and create a brand-new data entry in our Realm database. 48 49 00:04:06,180 --> 00:04:15,030 So inside here the first thing that we need to do is we're going to have to import RealmSwift, and as 49 50 00:04:15,030 --> 00:04:22,200 always, usually, with CocoaPods. It might not recognize your modules when you first open up your Xcode 50 51 00:04:22,200 --> 00:04:23,370 workspace. 51 52 00:04:23,370 --> 00:04:30,660 So if it does this, and you can see, for sure, that there it is, then you can simply go and hit command 52 53 00:04:30,720 --> 00:04:36,660 B to build and it should get rid of that error for you once build complete. 53 54 00:04:36,660 --> 00:04:42,900 Now, we're going to write our code inside the application didFinishLaunchingWithOptions delegate 54 55 00:04:42,900 --> 00:04:43,340 method. 55 56 00:04:43,770 --> 00:04:52,350 And here we're going to first create a brand-new Realm. So you can imagine Realms as almost like different 56 57 00:04:52,350 --> 00:04:53,950 persistent containers. 57 58 00:04:54,060 --> 00:04:57,460 And we're going to call it realm, 58 59 00:04:57,600 --> 00:05:03,420 so let realm equals a new object from the Realm class. 59 60 00:05:03,420 --> 00:05:06,630 Now that would be great if that just worked as is. 60 61 00:05:06,630 --> 00:05:12,090 But unfortunately, the initialization of a new realm is actually marked with throw, 61 62 00:05:12,180 --> 00:05:14,950 so it can, in fact, throw an error. 62 63 00:05:14,970 --> 00:05:21,600 So we have to market with a try which means that we probably need a do catch block. 63 64 00:05:27,470 --> 00:05:29,700 So, now that's a little bit safer. 64 65 00:05:29,720 --> 00:05:33,100 We're going to use it to save a new piece of data. 65 66 00:05:33,140 --> 00:05:39,560 So Realm allows us to use object-oriented programming and persist objects. 66 67 00:05:39,590 --> 00:05:47,660 So let's go ahead and create a new Swift File and let's call it just Data and it's going to be grouped 67 68 00:05:47,690 --> 00:05:53,000 inside the Data Model folder. And inside Data, we're going to be using Realm, 68 69 00:05:53,000 --> 00:05:57,670 so I'm going to import RealmSwift, and then I'm going to create a new class. 69 70 00:05:57,710 --> 00:06:04,400 The class is, of course, going to be called Data and it's going to subclass something called Object. 70 71 00:06:04,490 --> 00:06:09,530 An Object is a class that's used to define Realm model objects. 71 72 00:06:09,560 --> 00:06:17,480 So it's a superclass that we're going to use to enable us to persist our Data class. And the code inside 72 73 00:06:17,630 --> 00:06:22,180 is going to be where we're going to declare our properties for the Data class. 73 74 00:06:22,190 --> 00:06:28,910 So, say, if the data that we needed was a variable code name and it was of type String and it starts off 74 75 00:06:28,910 --> 00:06:36,710 with a value of an empty string, and another one called age and it's of type Int and it starts off being 75 76 00:06:36,800 --> 00:06:37,690 0. 76 77 00:06:37,790 --> 00:06:45,140 So under any normal conditions if we weren't subclassing object and we were just creating a new class 77 78 00:06:45,710 --> 00:06:49,610 to represent our data, then this would be fine. 78 79 00:06:49,670 --> 00:06:57,740 However, because we're using Realm, we actually need to mark our variables with the keyword "dynamic." And 79 80 00:06:57,740 --> 00:07:01,910 there's a long and short answer as to what dynamic means. 80 81 00:07:02,090 --> 00:07:08,060 So the complex answer is that dynamic is what's called a declaration modifier. 81 82 00:07:08,060 --> 00:07:16,460 It basically tells the runtime to use dynamic dispatch over the standard which is a static dispatch. 82 83 00:07:16,520 --> 00:07:25,370 And this basically allows this property name to be monitored for change at runtime, i.e., while your app 83 84 00:07:25,400 --> 00:07:26,270 is running. 84 85 00:07:26,300 --> 00:07:30,350 So that means if the user changes the value of name, 85 86 00:07:30,350 --> 00:07:38,840 for example, while the app is running, then that allows Realm to dynamically update those changes in the 86 87 00:07:38,840 --> 00:07:45,720 database. But dynamic dispatch is something that actually comes from the Objective-C APIs. 87 88 00:07:46,040 --> 00:07:55,670 So that means that we have to mark dynamic with at Objective-C to be explicit that we are using the 88 89 00:07:55,670 --> 00:07:57,850 Objective-C runtime. 89 90 00:07:57,860 --> 00:08:03,770 Now, the simple answer as to why we just added these two keywords in there is that we need to add these 90 91 00:08:03,770 --> 00:08:09,780 two modifiers, basically, so that Realm can monitor for changes in the value of this property, 91 92 00:08:09,830 --> 00:08:13,900 and this is what we'll allow us to do it while the app is running. 92 93 00:08:14,150 --> 00:08:17,960 So let's go ahead and add that to our second variable as well, 93 94 00:08:17,960 --> 00:08:23,390 so they are now both compliant with how Realm properties should be declared. 94 95 00:08:23,390 --> 00:08:29,240 So whenever you're declaring a new property that's any of the basic data types, you will need these two 95 96 00:08:29,240 --> 00:08:30,290 keywords in front of it. 96 97 00:08:31,270 --> 00:08:31,730 Okay. 97 98 00:08:31,730 --> 00:08:39,740 So, now we can go into our AppDelegate and we can create a new piece of data that is going to be an 98 99 00:08:39,800 --> 00:08:45,950 object of the Data class and we can set its properties by saying data.name 99 100 00:08:46,010 --> 00:08:54,320 = "Angela" data.age equals-- I'm not going to say my real age here, 100 101 00:08:54,310 --> 00:08:54,630 right? 101 102 00:08:54,950 --> 00:08:56,100 Let's say, I'm 12. 102 103 00:08:56,300 --> 00:08:56,560 All right. 103 104 00:08:56,630 --> 00:09:05,450 So let's go ahead and add our new item, i.e., create in CRUD, and we're going to commit the current state 104 105 00:09:05,540 --> 00:09:06,600 of our Realm. 105 106 00:09:06,680 --> 00:09:11,740 So just as we did with Core Data, we basically created a new piece of data, 106 107 00:09:11,840 --> 00:09:20,150 then we used the context to commit the current state to our persistent container, or in this case, it's 107 108 00:09:20,150 --> 00:09:21,200 our Realm database. 108 109 00:09:21,260 --> 00:09:25,330 So in order to do that, we can move this down here. 109 110 00:09:25,730 --> 00:09:33,130 And after we've created this brand-new Realm, we can then say realm.write 110 111 00:09:33,290 --> 00:09:39,890 which means commit the current state persistent storage or to our Realm database, and then we can say 111 112 00:09:39,950 --> 00:09:48,760 realm.add a new object, and a new object is going to be our data. 112 113 00:09:48,860 --> 00:09:54,600 So as with initializing a new Realm, realm.write can also throw. 113 114 00:09:55,040 --> 00:10:02,360 So we have to also market with the "try" keyword which is why they're both kept inside this do block underneath 114 115 00:10:02,420 --> 00:10:03,860 where we created our data. 115 116 00:10:04,130 --> 00:10:11,870 So, now all we have to do is run our app so that our application didFinishLaunching gets called and 116 117 00:10:11,930 --> 00:10:18,530 all of this gets implemented so that we'll be able to save our data to our Realm database. 117 118 00:10:18,530 --> 00:10:18,810 All right. 118 119 00:10:18,830 --> 00:10:20,930 So that worked without any issue. 119 120 00:10:21,140 --> 00:10:27,980 But how do we view our data because we're not using it to populate any of our table views? This is still 120 121 00:10:27,980 --> 00:10:29,060 using Core Data, 121 122 00:10:29,060 --> 00:10:32,820 remember? And all of our code is inside the aapp Delegate. 122 123 00:10:32,960 --> 00:10:37,840 But if we have a look in our debug log, we didn't get any errors coming back, right? 123 124 00:10:37,870 --> 00:10:41,800 So that means our process probably completed successfully. 124 125 00:10:41,960 --> 00:10:45,160 So our data did get saved into our Realm. 125 126 00:10:45,260 --> 00:10:52,690 So in order to locate where our data is stored or where our Realm database is, we can use a print statement. 126 127 00:10:52,730 --> 00:10:57,830 We can say print (Realm.Configuration. 127 128 00:11:00,250 --> 00:11:10,660 defaultConfiguration.fileURL. And this is the location of the Realm file. 128 129 00:11:10,930 --> 00:11:18,010 And now, if we print that out, we'll be able to locate where our Realm database exists. Now, because we're 129 130 00:11:18,010 --> 00:11:19,120 not unwrapping it, 130 131 00:11:19,180 --> 00:11:21,820 it's gonna get printed as an optional. 131 132 00:11:22,090 --> 00:11:23,410 And there it is. 132 133 00:11:23,410 --> 00:11:26,080 So that's our file location. 133 134 00:11:26,200 --> 00:11:32,260 But before we can view this file, you can see that the file is actually something called 134 135 00:11:32,260 --> 00:11:32,820 default.realm. 135 136 00:11:32,830 --> 00:11:34,840 So it's a Realm file. 136 137 00:11:34,840 --> 00:11:41,280 So in order to see the data that exists inside, we need to download a piece of software from the App 137 138 00:11:41,280 --> 00:11:41,910 Store. 138 139 00:11:42,160 --> 00:11:47,090 And it's a free Mac app called the Realm Browser. 139 140 00:11:47,500 --> 00:11:50,840 So if you search for Realm Browser inside your App Store, 140 141 00:11:50,860 --> 00:11:56,640 then you'll come across this Mac app made by the round team and it's free to download, 141 142 00:11:56,710 --> 00:11:59,060 and it's quite a small piece of software. 142 143 00:11:59,590 --> 00:12:05,810 Only, what, 5.9 megabytes. And you can simply download it onto your local machine. 143 144 00:12:05,890 --> 00:12:14,260 But once you have done so, then you can open up your Realm Browser and you can click on the open realm 144 145 00:12:14,260 --> 00:12:14,810 file. 145 146 00:12:14,830 --> 00:12:21,640 So, now it's going to take you into your file browser and we're going to have to navigate to that location 146 147 00:12:21,670 --> 00:12:23,330 that we printed out earlier on. 147 148 00:12:23,350 --> 00:12:30,490 Now, previously, I've always shown you the sort of bog-standard way of navigating to a location in your 148 149 00:12:30,490 --> 00:12:33,690 file directory which is chasing the directories, 149 150 00:12:33,700 --> 00:12:33,970 right? 150 151 00:12:34,270 --> 00:12:35,880 But it's a little bit painful. 151 152 00:12:35,890 --> 00:12:38,950 So let me show you how you would do it as a shortcut. 152 153 00:12:39,580 --> 00:12:47,650 So if you hit command shift G, then you can actually go straight to the folder or the document. And all 153 154 00:12:47,650 --> 00:12:55,060 you have to do is take this string that says a file something, and all the way down to Realm without copying 154 155 00:12:55,150 --> 00:13:01,540 any of the Realm brackets, hit command C to copy, and then we're going to hit command V to paste. 155 156 00:13:01,540 --> 00:13:10,480 Now, if you navigate to the front of this string, if you delete the file, colon, dash, dash, so you only end 156 157 00:13:10,480 --> 00:13:13,060 up with a forward slash, user, slash, 157 158 00:13:13,060 --> 00:13:21,430 angelayu, this is your file path that will help the Finder to navigate to this location. And then you can go 158 159 00:13:21,430 --> 00:13:26,890 ahead and simply hit Go, and it takes you straight to that location. 159 160 00:13:26,890 --> 00:13:33,400 Now, you might think I'm a little bit sadistic for making you guys go through this process many times 160 161 00:13:33,460 --> 00:13:40,210 previously, but it's always good to know how it's done manually before you learn about shortcuts because 161 162 00:13:40,210 --> 00:13:44,470 a lot of people learn the shortcuts first, and then when you get stuck or when something doesn't work, 162 163 00:13:44,770 --> 00:13:46,420 then it's always very confusing. 163 164 00:13:46,450 --> 00:13:52,640 So there's always the long path to fall back on, but to save your sanity and your precious life, then 164 165 00:13:52,810 --> 00:13:58,300 it's a good idea to use the file path to navigate. And you can do this in any Finder, not just in the Realm 165 166 00:13:58,300 --> 00:13:58,710 browser, 166 167 00:13:58,720 --> 00:14:04,090 by the way. So if you're inside any sort of Finder window and you're trying to locate something, you can 167 168 00:14:04,090 --> 00:14:08,530 simply hit command shift G and you can go straight to that location. 168 169 00:14:08,590 --> 00:14:15,400 Now that we're here inside the Realm browser, we can simply select our default.realm database and 169 170 00:14:15,400 --> 00:14:19,660 we can hit Open. And Realm will need access to this path, 170 171 00:14:19,720 --> 00:14:24,650 so we're going to have to click Allow and you might even have to enter a password every now and then. 171 172 00:14:24,670 --> 00:14:28,690 So we run our app twice, first time to check that it worked, 172 173 00:14:28,690 --> 00:14:31,910 and the second time, to get this file path. 173 174 00:14:32,170 --> 00:14:37,480 And that means that our application didFinishLaunchingWithOptions got called twice which means that 174 175 00:14:37,480 --> 00:14:42,330 we saved two pieces of data both with name Angela and age 12. 175 176 00:14:42,520 --> 00:14:48,400 And you can see that the Realm browser is this really, really simple interface where you can see your 176 177 00:14:48,400 --> 00:14:49,390 models, 177 178 00:14:49,480 --> 00:14:56,920 so our Data Model, and you can see your properties: name which is a string, age which is an integer. 178 179 00:14:57,130 --> 00:15:04,480 And we've got our pieces of data and it even shows you the minimum, average, maximum, the sum, and some 179 180 00:15:04,480 --> 00:15:07,600 simple bits of analysis on your data. 180 181 00:15:07,600 --> 00:15:10,590 So that was pretty pain free, right? 181 182 00:15:10,720 --> 00:15:16,890 And compared to how much work we needed to do in order to set up our Data Model using Core Data, 182 183 00:15:17,110 --> 00:15:24,700 I hope you can see that this is a very, very useful tool. And we're going to dive deeper into Realm in 183 184 00:15:24,700 --> 00:15:31,630 the next lesson, so that we can start working on how to do CRUD using Realm, instead of Core Data. 184 185 00:15:31,630 --> 00:15:36,940 And you're going to see all of the ease and the shortness of the code and all of the beauty of this new 185 186 00:15:36,940 --> 00:15:38,110 way of doing things. 186 187 00:15:38,110 --> 00:15:40,930 So for all of that and more, see you on the next lesson.