0 1 00:00:00,690 --> 00:00:07,500 Now, in the past few lessons, we've already massively improved some of our user interface, and it's starting 1 2 00:00:07,500 --> 00:00:09,750 to really come along and look really nice. 2 3 00:00:09,750 --> 00:00:13,530 So in this lesson, we're going to tie up all the loose ends and we're gonna do a little bit more 3 4 00:00:13,530 --> 00:00:19,310 front-end stuff to make our app feel really cohesive and look like it's a real app on the App Store. 4 5 00:00:19,320 --> 00:00:25,260 So the first thing that I want to do is I want to change the nav bar. Instead of having this small nav 5 6 00:00:25,290 --> 00:00:25,650 bar, 6 7 00:00:25,680 --> 00:00:32,270 I want to make it a large title. And in order to do that, there's only one checkbox that we need to check 7 8 00:00:32,270 --> 00:00:32,550 off. 8 9 00:00:32,880 --> 00:00:40,260 So if you go into your Main.storyboard and select, not the nav bars for your individual view controllers, 9 10 00:00:40,560 --> 00:00:46,620 but the actual navigation controller's nav bar. And you can also select it inside the document outline 10 11 00:00:46,620 --> 00:00:47,150 as well, 11 12 00:00:47,160 --> 00:00:49,500 it's this particular one that you're interested, 12 13 00:00:49,500 --> 00:00:54,740 the actual bar rather than the controller. If you head over to the attributes Inspector, 13 14 00:00:54,840 --> 00:01:02,040 then there's this particular Boolean called Prefers Large Titles. And if you tick it, then you can see that 14 15 00:01:02,330 --> 00:01:05,610 our navigation bars become a lot bigger 15 16 00:01:05,610 --> 00:01:07,680 and the titles get bigger as well. 16 17 00:01:07,860 --> 00:01:11,100 And it looks a lot more like an actual todoList. 17 18 00:01:11,100 --> 00:01:15,900 And if we run our app, you'll see that it looks a lot nicer 18 19 00:01:15,900 --> 00:01:20,730 in this particular format. It works much better as the heading. 19 20 00:01:20,730 --> 00:01:26,640 So the next thing I want to change is that I want to change the nav bar to be consistent, also with the 20 21 00:01:26,640 --> 00:01:32,910 background color of the category, so that everything on this screen is green. And the place where you're 21 22 00:01:32,910 --> 00:01:36,140 going to set this is inside viewDidLoad. 22 23 00:01:36,150 --> 00:01:43,530 So inside the TodoListViewController, go into the viewDidLoad and we are going to tap into our 23 24 00:01:43,590 --> 00:01:51,720 navigationController.navigationBar. And then we're going to set, not it's background color, because this only 24 25 00:01:51,720 --> 00:01:54,150 changes the background color of the bar, 25 26 00:01:54,270 --> 00:02:00,360 but we're going to set the barTintColor. And this will apply it both to the navigation bar as well 26 27 00:02:00,360 --> 00:02:07,160 as the status bar. And we're going to set this equal to the color based on the selected category. 27 28 00:02:07,200 --> 00:02:14,730 So it'll be selectedCategory.colour. And, of course, remember, this is a hex string that describes a 28 29 00:02:14,730 --> 00:02:15,250 color. 29 30 00:02:15,300 --> 00:02:24,270 So we're going to have to use that UIColor method from Chameleon called UIcolor with hexString, 30 31 00:02:25,140 --> 00:02:30,300 and then we're going to put that hexString inside here. 31 32 00:02:30,300 --> 00:02:35,580 Now, as soon as you do that, Xcode is going to complain because we're using optional chaining here. 32 33 00:02:35,580 --> 00:02:43,470 This value is an optional. And this UIColor using hexString method needs a nonoptional string in order 33 34 00:02:43,470 --> 00:02:44,280 for this to work. 34 35 00:02:44,880 --> 00:02:51,270 So you have the option of either explicitly unwrapping selectedCategory, which is not all that safe, 35 36 00:02:51,870 --> 00:02:54,780 or you can use optional binding. 36 37 00:02:54,780 --> 00:03:06,570 So we can say if let colourHex = selectedCategory?.colour. If this is not nil, then 37 38 00:03:06,660 --> 00:03:15,140 we will proceed with this method and we can replace this part here with colourHex. 38 39 00:03:15,150 --> 00:03:23,940 Now, the other assumption that we're making here, by using this question mark is we're saying if the 39 40 00:03:23,940 --> 00:03:31,950 navigationController is not nil, then in that case, we're going to set the bar color for the navigation bar. 40 41 00:03:31,950 --> 00:03:37,650 Now, this assumption is a little bit problematic ,and I'm going to show you why by using a "guard" statement. 41 42 00:03:37,650 --> 00:03:48,900 So I'm going to say guard let navBar = navigationController.navigationBar, and then else, i.e., if it 42 43 00:03:48,900 --> 00:03:52,080 is nil, then we're going to throw a fatalError 43 44 00:03:52,350 --> 00:04:00,160 and I'm going to pass the message for that fatalError as "Navigation controller does not exist." 44 45 00:04:00,870 --> 00:04:08,550 So what this line is going to do is it's going to create this constant called navBar and assign that 45 46 00:04:08,580 --> 00:04:13,240 the value of the current navigationBar in the current navigationController. 46 47 00:04:13,350 --> 00:04:21,720 But if this is nil, i.e., then navigationController does not yet exist, then we're going to throw this 47 48 00:04:21,810 --> 00:04:27,510 fatalError and we're going to inform ourselves of this problem. And our app is going to crash and we're 48 49 00:04:27,510 --> 00:04:28,730 going to see this message. 49 50 00:04:28,740 --> 00:04:32,350 So let's run our app and see what happens. 50 51 00:04:32,360 --> 00:04:32,720 Okay. 51 52 00:04:32,740 --> 00:04:35,140 So let's go into our 52 53 00:04:35,150 --> 00:04:43,740 TodoListViewController. And you can see that our app is right now crashing. And if we click on this error, then it says, 53 54 00:04:43,830 --> 00:04:48,270 "Fatal error: Navigation controller does not exist." 54 55 00:04:48,270 --> 00:04:53,190 So the thing is when you start off learning how to develop apps for iOS, people tend to be very afraid 55 56 00:04:53,280 --> 00:04:55,170 of app crashes. 56 57 00:04:55,260 --> 00:05:01,780 But as you get more and more experience, you should start to learn that crashes are not bad. They're not 57 58 00:05:01,780 --> 00:05:03,170 a bad thing. 58 59 00:05:03,190 --> 00:05:09,040 What you don't want is for your app to fail silently in the background, and your variables and property 59 60 00:05:09,040 --> 00:05:13,090 is having values that are unexpected and undesired. 60 61 00:05:13,180 --> 00:05:15,790 But it's not giving you a warning in any sort of way. 61 62 00:05:15,850 --> 00:05:22,720 So don't be afraid of throwing fatal errors when you have a situation where you definitely don't expect 62 63 00:05:22,720 --> 00:05:29,140 it to break so that you can catch these problems during testing, rather than in the live deployment app 63 64 00:05:29,440 --> 00:05:32,840 on the App Store when your app is not behaving the way it should be 64 65 00:05:32,980 --> 00:05:36,090 and the user has no clue how to report this. 65 66 00:05:36,100 --> 00:05:40,250 So, now let's stop our app and figure out what's going on. 66 67 00:05:40,270 --> 00:05:46,030 Why is our navigationController nil at this point? 67 68 00:05:46,030 --> 00:05:49,150 Why are we getting this fatal error being thrown? 68 69 00:05:49,150 --> 00:05:58,180 Well, the problem is that we know that viewDidLoad is the time point at which our view for our current 69 70 00:05:58,270 --> 00:06:01,770 view controller has been loaded up. 70 71 00:06:01,810 --> 00:06:09,340 Now, the problem is that just because the view has been loaded up, it does not mean that your view has been 71 72 00:06:09,400 --> 00:06:12,770 inserted into the navigation controller, 72 73 00:06:12,850 --> 00:06:16,520 it might not yet be in that navigation stack. 73 74 00:06:16,570 --> 00:06:23,800 So during the process of pushing this TodoListViewController onto the navigation stack to be managed 74 75 00:06:23,800 --> 00:06:27,940 by the navigation controller, viewDidLoad will get cold. 75 76 00:06:28,060 --> 00:06:35,440 But the thing that you cannot be sure of is whether if the TodoListViewController is already inside 76 77 00:06:35,440 --> 00:06:41,290 the navigation stack, i.e., if that process has completed before viewDidLoad gets called. 77 78 00:06:41,350 --> 00:06:48,430 So in our case, it's clear that viewDidLoad is actually being called before the navigationController 78 79 00:06:48,700 --> 00:06:53,630 property has been updated, because at this point, it is still nil. 79 80 00:06:54,160 --> 00:06:55,510 So what can we do? 80 81 00:06:55,630 --> 00:07:04,480 Well, maybe consider that viewDidLoad might not be the right place to place this code. And if we think 81 82 00:07:04,480 --> 00:07:11,170 back to the lesson on view controller life cycles, then you might remember that there's another access 82 83 00:07:11,170 --> 00:07:19,400 point that we can use which was called viewWillAppear. And viewWillAppear gets called later than 83 84 00:07:19,400 --> 00:07:26,700 viewDidLoad and it's actually at the point just right before the view is going to show up on the screen. 84 85 00:07:26,740 --> 00:07:33,160 So after the view has been loaded up after the navigation stack has been established, and just before the 85 86 00:07:33,160 --> 00:07:40,360 user sees anything on screen, this is the time point that we can access using viewWillAppear. 86 87 00:07:40,360 --> 00:07:49,870 And so I'm going to transplant my code here into viewWillAppear, and it's probably also a good time 87 88 00:07:49,870 --> 00:07:53,840 to delete this stray bit of code here if you haven't done already 88 89 00:07:53,950 --> 00:07:55,930 because we no longer need that. 89 90 00:07:56,080 --> 00:07:56,400 Okay. 90 91 00:07:56,410 --> 00:08:04,630 So inside our viewWillAppear, we're still going to use our guard let navigationBar. And Xcode is complaining 91 92 00:08:04,630 --> 00:08:10,280 and giving as a warning at the moment that you've guarded and you've created this constant called 92 93 00:08:10,530 --> 00:08:12,080 navBar. We're not really using it anyway. 93 94 00:08:12,100 --> 00:08:18,250 So let's use it. Let's replace this navigationBar that's uses optional chaining. 94 95 00:08:18,250 --> 00:08:23,740 So this is why our barTintColor didn't change at all previously because navigationController is nil 95 96 00:08:24,010 --> 00:08:30,160 and the way that optional chaining works is that if this is nil, then this code is not going to be continued. 96 97 00:08:30,160 --> 00:08:32,170 So this gets skipped over. 97 98 00:08:32,170 --> 00:08:40,210 So instead, what we want to do is we want to use navBar and we're guarding against scenarios where navBar 98 99 00:08:40,210 --> 00:08:43,950 is nil by using this guard statement 99 100 00:08:43,990 --> 00:08:47,180 So let's go ahead and run our app and see if that worked. 100 101 00:08:47,430 --> 00:08:47,690 Okay. 101 102 00:08:47,710 --> 00:08:55,300 So we're going to go into the Home screen and you can see that our status bar, our navigation bar, everything 102 103 00:08:55,300 --> 00:09:03,700 gets changed just by moving our code to a different life cycle time point. And our app doesn't crash, 103 104 00:09:04,120 --> 00:09:10,480 our fatal error is not being thrown. Because at this point, the navigation property has a value, it's not 104 105 00:09:10,480 --> 00:09:16,120 nil. And our current view controller is firmly inside the navigation stack. 105 106 00:09:16,210 --> 00:09:23,020 So the other things that we might want to do here is maybe change the title of our 106 107 00:09:23,020 --> 00:09:24,040 TodoItemsViewController. 107 108 00:09:24,070 --> 00:09:29,770 It would be nice if this title reflected the category that we selected, 108 109 00:09:29,770 --> 00:09:30,070 right? 109 110 00:09:30,390 --> 00:09:35,580 And it's pretty easy to tap in to because we have this selectedCategory property here. 110 111 00:09:35,740 --> 00:09:43,120 So we can simply say something like title, which is a string that represents the view that this controller 111 112 00:09:43,120 --> 00:09:43,910 manages, 112 113 00:09:44,020 --> 00:09:50,410 and this is basically what the navigationController will tap into to populate the title in the 113 114 00:09:50,410 --> 00:09:50,710 navBar. 114 115 00:09:51,220 --> 00:09:56,380 So we can say title = selectedCategory. 115 116 00:09:56,380 --> 00:10:02,500 And because we're inside an optional binding block where we've already access the selectedCategory's 116 117 00:10:02,500 --> 00:10:08,020 color through optional binding, then we can be pretty sure that selectedCategory does in fact exist 117 118 00:10:08,080 --> 00:10:09,340 and it's not nil. 118 119 00:10:09,340 --> 00:10:13,970 So title will become selected category.name. 119 120 00:10:14,050 --> 00:10:22,030 So as you progress, you're going to be more flexible with these optionals and figure out ways of being 120 121 00:10:22,030 --> 00:10:28,450 safe while being constantly aware of what it is that your code is doing, and the places where it can 121 122 00:10:28,450 --> 00:10:29,110 fall down. 122 123 00:10:29,620 --> 00:10:36,040 So let's run our app and see if our title gets populated. And if we go inside Home, you can see that our 123 124 00:10:36,040 --> 00:10:40,850 title used to be Item, but it now is the title of the Category. 124 125 00:10:40,870 --> 00:10:46,660 So looking pretty sweet, right? Now, there's just one other thing that's bugging me which is, what about 125 126 00:10:46,660 --> 00:10:48,240 the background of the search bar, 126 127 00:10:48,250 --> 00:10:51,200 it looks so out of place with that grey background. 127 128 00:10:51,250 --> 00:10:52,230 Let's change it. 128 129 00:10:52,270 --> 00:10:57,640 So for us to be able to do that, we first have to create an outlet from the search bar into our 129 130 00:10:57,640 --> 00:11:03,220 TodoListViewController. So you can either click and drag from the search bar just making sure that you've 130 131 00:11:03,220 --> 00:11:06,530 actually selected the search bar and not a table view. 131 132 00:11:06,560 --> 00:11:12,610 Alternatively and probably a much better way is to go from the document outline and drag it into your 132 133 00:11:12,610 --> 00:11:14,110 TodoListViewController. 133 134 00:11:14,110 --> 00:11:20,200 And I'm just going to call it searchBar and hit enter to create that IBOutlet, and then we can go inside 134 135 00:11:20,200 --> 00:11:23,580 viewWillAppear just underneath the line that we wrote previously. 135 136 00:11:23,590 --> 00:11:28,770 So, we'll tap into searchBar.tint Color 136 137 00:11:29,260 --> 00:11:32,640 and this applies the tint color to the search bar background 137 138 00:11:32,800 --> 00:11:38,170 and we're going to set it to equal the same color that we've specified for our navigationBar. 138 139 00:11:38,440 --> 00:11:43,540 So let's go ahead and hit run and see if that worked. 139 140 00:11:43,540 --> 00:11:50,050 So we're going to go into Home and you can see everything is now more or less green. 140 141 00:11:50,050 --> 00:11:55,890 Now, another thing that you might want to change is the color of these buttons. 141 142 00:11:55,900 --> 00:12:01,210 So, for example, this button currently is sort of a light blue which doesn't look that great. 142 143 00:12:01,240 --> 00:12:03,660 We manually set this button to be white. 143 144 00:12:03,730 --> 00:12:09,610 But what if our navigation bar was set to a really light color, for example, white or something like that, 144 145 00:12:10,060 --> 00:12:13,540 then in that case we might not be able to see these buttons, 145 146 00:12:13,550 --> 00:12:13,870 right? 146 147 00:12:14,080 --> 00:12:20,680 So we should do what we've done here which is set these buttons to contrast the color of the navigation 147 148 00:12:20,680 --> 00:12:27,880 bar and we can do that just below where we set the barTintColor because there's another property in 148 149 00:12:27,880 --> 00:12:31,190 the navigation bar called the tintColor. 149 150 00:12:31,330 --> 00:12:35,920 And this applies to all of the navigation items and bar button items. 150 151 00:12:35,920 --> 00:12:38,120 So that is the one that we want to change. 151 152 00:12:38,230 --> 00:12:44,710 We're going to set it to the contrasting color of the color of the navBar and we're going to return 152 153 00:12:44,710 --> 00:12:48,640 it as flat which basically means a low contrast color. 153 154 00:12:48,640 --> 00:12:56,260 Now, we have a problem here because the output of this particular method is a optional UIColor and that's 154 155 00:12:56,260 --> 00:13:02,080 fine over here because barTintColor takes a optional UIColor. 155 156 00:13:02,080 --> 00:13:08,320 But in this case, the contrasting color method requires a nonoptional UIColor. 156 157 00:13:08,320 --> 00:13:15,860 So we either have to force unwrap it which is unsafe or we will have to create another if let. 157 158 00:13:16,180 --> 00:13:25,170 So if let fnavBarColour = UIColor created with the colourHex code. 158 159 00:13:25,540 --> 00:13:32,710 And if that is not nil, then we will set the navBar background the tintColor as well as the search 159 160 00:13:32,710 --> 00:13:33,400 bar colors. 160 161 00:13:33,940 --> 00:13:41,620 So we're going to paste that inside this optional binding statement, and then we can change this to 161 162 00:13:41,650 --> 00:13:51,570 navBarColour, and change this to navBarColour, and also we can change this to navBarColour because it's gonna 162 163 00:13:51,610 --> 00:13:52,520 be the same. 163 164 00:13:54,590 --> 00:13:59,670 Now, the next thing that we want to change is the color of the title. 164 165 00:13:59,810 --> 00:14:05,570 And if we have a look through the UINavigationBar Documentation, then you can see that there's a section 165 166 00:14:05,570 --> 00:14:09,080 called Customizing the Appearance of a Navigation Bar, 166 167 00:14:09,080 --> 00:14:15,650 and it talks about how you would change the title text differently from the rest of the controls, so 167 168 00:14:15,650 --> 00:14:22,490 the bar button items, for example. And you need to change this titleTextAttributes property by setting 168 169 00:14:22,550 --> 00:14:24,640 the foregroundColor key. 169 170 00:14:24,740 --> 00:14:27,220 So let's go ahead and do that here. 170 171 00:14:27,230 --> 00:14:31,040 Now, we're gonna say navigationBar to tap into the current bar. 171 172 00:14:31,040 --> 00:14:34,880 Then we're going to look for the titleTextAttributes. 172 173 00:14:34,880 --> 00:14:42,680 Now, it's important that because we're using the large title, we have to change the properties for the 173 174 00:14:42,680 --> 00:14:48,020 largeTitleTextAttributes, rather than just the regular titleTextAttributes which is the smaller 174 175 00:14:48,020 --> 00:14:49,660 one that shows up in the middle. 175 176 00:14:49,700 --> 00:14:55,940 So let's select largeTitleTextAttribute property, and it's expecting a dictionary where it takes a 176 177 00:14:55,940 --> 00:14:59,070 key which is an NSAttributedStringKey 177 178 00:14:59,240 --> 00:15:03,890 and it takes a value which is going to be the value for whichever key you choose. 178 179 00:15:03,890 --> 00:15:07,070 So we're going to create a new dictionary and we're going to tap into that 179 180 00:15:07,130 --> 00:15:14,970 NSAttributedStringKey. And we're going to use the dot notation to find the key that we want. 180 181 00:15:15,110 --> 00:15:21,440 And this is a bit like an enum where we're looking through and trying to find the value that we want 181 182 00:15:21,440 --> 00:15:22,220 to change. 182 183 00:15:22,400 --> 00:15:28,460 And in our case, it's actually the foreground color that we're interested in changing, the foregroundColor 183 184 00:15:28,460 --> 00:15:30,800 for the large text title. 184 185 00:15:30,800 --> 00:15:38,990 And this is going to be set to our contrast color contrasting the navBarColor returning a flat color. 185 186 00:15:39,170 --> 00:15:41,620 And now, we're almost ready to run our app. 186 187 00:15:41,630 --> 00:15:47,570 The last thing that we need to do before we can do that is we need to go into our Main.storyboard and 187 188 00:15:47,570 --> 00:15:51,880 click on that plus button which we manually set to be white 188 189 00:15:51,950 --> 00:15:53,870 and we need to change it back to default. 189 190 00:15:54,170 --> 00:16:00,200 And now if we run our app and we go into Home, you can see that everything gets colored correctly, and 190 191 00:16:00,200 --> 00:16:08,690 also the background color looks exactly as we want it to.. Now, there's just one problem, the navigation 191 192 00:16:08,690 --> 00:16:14,230 bar and the category view controller is not behaving as expected. In order to fix this, 192 193 00:16:14,270 --> 00:16:19,930 let's change the navigation bar's background color to blue in the CategoryViewController. 193 194 00:16:20,090 --> 00:16:23,930 I'm gonna do this in the viewWilllAppear lifecycle method. 194 195 00:16:23,930 --> 00:16:30,170 So the part where it says override function viewWillApear or add the same guard let as in the 195 196 00:16:30,170 --> 00:16:32,200 TodoListViewController. 196 197 00:16:32,330 --> 00:16:37,860 So guard let navBar equals navigationController.navigationBar 197 198 00:16:37,940 --> 00:16:44,480 else through a fatalError that "Navigation controller does not exist." Except for this time, I'll change 198 199 00:16:44,480 --> 00:16:54,580 the background color to the UIColor with the hex code pound sign 1D9BF6. So navBar. backgroundColour 199 200 00:16:54,580 --> 00:17:05,290 = UIColor with hexString pound sign "1D9BF6." And if we run our app, you'll see that it works 200 201 00:17:05,410 --> 00:17:08,860 exactly as it did before. 201 202 00:17:08,920 --> 00:17:16,800 Now, the very, very, very last thing that I want to fix is the text color inside the cell for the 202 203 00:17:16,810 --> 00:17:21,580 CategoryViewController here, because I can barely read it off that dark background. 203 204 00:17:21,580 --> 00:17:24,860 So we know how to do that. Inside our TodoListViewController, 204 205 00:17:25,060 --> 00:17:31,870 when we did cellForRowAt indexPath, we had this line of code where we contrasted the color of the background 205 206 00:17:31,870 --> 00:17:32,200 color. 206 207 00:17:32,470 --> 00:17:39,460 So I'm gonna go into the CategoryViewController and go into its selfForRowAt indexPath and I'm going 207 208 00:17:39,460 --> 00:17:52,900 to set the cell's textLabel.textColor to be the contrasting color of this color which came from 208 209 00:17:52,900 --> 00:17:59,220 the category and returning as a flat color. 209 210 00:17:59,220 --> 00:18:09,990 Now, of course, if you wanted to, you can either use if let or guard let categoryColour to be equal to this 210 211 00:18:10,220 --> 00:18:17,810 UIColor created using that category. colour hexString. And if that doesn't work, then I'm gonna 211 212 00:18:17,820 --> 00:18:21,670 throw a fatalError because it really should. 212 213 00:18:21,700 --> 00:18:29,900 Now, I can set the cell's backgroundColor to categoryColour, and I can contrast the color, instead of this 213 214 00:18:29,900 --> 00:18:34,340 long string to categoryColour as well. 214 215 00:18:34,340 --> 00:18:36,810 And let's run our up and see if that worked. 215 216 00:18:36,890 --> 00:18:37,190 All right. 216 217 00:18:37,220 --> 00:18:38,030 Nice. 217 218 00:18:38,030 --> 00:18:41,660 That's looking a lot better than before. 218 219 00:18:41,900 --> 00:18:48,180 As you can see, there's so much that you can do with the front-end and the UI. 219 220 00:18:48,360 --> 00:18:51,750 You can really go to town if you wanted to. 220 221 00:18:51,840 --> 00:18:57,270 And off the top of my head, I can probably think of even more UI improvements, but we have achieved most 221 222 00:18:57,270 --> 00:18:58,530 of our design aims. 222 223 00:18:58,650 --> 00:19:05,100 We wanted to have different colors for each category and that we wanted that color to be carried over when 223 224 00:19:05,100 --> 00:19:07,690 we go into the TodoListViewController. 224 225 00:19:07,710 --> 00:19:13,350 We have the category as the title of this TodoListViewController and we've created this gradient 225 226 00:19:13,380 --> 00:19:18,240 effect for each of our cells, and we've contrasted the text with that background. 226 227 00:19:18,270 --> 00:19:25,200 So if you do decide to add even more front-end code and make this even more fancy and even prettier, 227 228 00:19:25,470 --> 00:19:32,070 then be sure to post a video of it or a GIF of it to the Q-and-A section so that we can all admire your beautiful 228 229 00:19:32,070 --> 00:19:32,360 work. 229 230 00:19:32,610 --> 00:19:38,610 So I hope you enjoyed making this app with me and learning all about, oh, my gosh, so many things in this 230 231 00:19:38,610 --> 00:19:39,600 module. 231 232 00:19:39,600 --> 00:19:45,600 The main reason why I created this module was to teach you all of the different ways that you can persist 232 233 00:19:45,600 --> 00:19:47,340 this data locally. 233 234 00:19:47,340 --> 00:19:49,120 And we covered user default, 234 235 00:19:49,170 --> 00:19:51,420 we covered the quotable protocol. 235 236 00:19:51,420 --> 00:19:58,770 We covered file storage locally as well as Core Data and Realm which we've used to create relational 236 237 00:19:58,770 --> 00:19:59,940 databases. 237 238 00:19:59,970 --> 00:20:08,070 And finally, we've wrapped it all up using a nice UI, and we now have this beautiful to-do list app which 238 239 00:20:08,130 --> 00:20:15,840 you will no doubtedly use to add new to-do items like other new iOS codes that you're going to learn 239 240 00:20:15,840 --> 00:20:16,080 about. 240 241 00:20:16,620 --> 00:20:21,120 That's all for me for this module and I will see you on the next module.