0 1 00:00:01,420 --> 00:00:01,710 All right. 1 2 00:00:01,710 --> 00:00:07,600 So in the previous lesson, we managed get our calculators start accumulating numbers and were able to 2 3 00:00:07,600 --> 00:00:09,130 use any of these buttons, say, 3 4 00:00:09,160 --> 00:00:11,840 plus, minus, times, or divide 4 5 00:00:11,860 --> 00:00:14,740 to start accumulating a different number. 5 6 00:00:14,740 --> 00:00:18,460 So we're ready on our way to building our calculator. 6 7 00:00:18,460 --> 00:00:24,310 Now, in this lesson, I just want to show you there's one thing that we could do to make our code a little 7 8 00:00:24,310 --> 00:00:29,050 bit more secure and less prone to unexpected errors, 8 9 00:00:29,380 --> 00:00:36,160 and that is by making this variable which we're using to track whether if the user is finish typing number 9 10 00:00:36,530 --> 00:00:44,350 to a private variable. And in order to make it private, we just add the keyword private in front of the 10 11 00:00:44,350 --> 00:00:51,720 keyword var and this variable is now private to its current scope. 11 12 00:00:51,730 --> 00:01:00,610 So what that means is that if you look inside the parent block, so this variable is only accessible between 12 13 00:01:00,700 --> 00:01:02,360 these two curly braces. 13 14 00:01:02,410 --> 00:01:05,190 And if you try to access it from anywhere else, 14 15 00:01:05,290 --> 00:01:13,450 so, say, for example, if I was to go and create a new file, let's create a new Swift File and let's just call 15 16 00:01:13,450 --> 00:01:21,950 it Test because we're going to delete it very soon. And inside Test, I'm going to create a new class and 16 17 00:01:21,960 --> 00:01:26,850 this class is going to be called Test and we're not going to inherit from a superclass. We'll delete 17 18 00:01:26,880 --> 00:01:35,610 that. And inside test, I'm going to create a new object of our viewController 18 19 00:01:36,210 --> 00:01:40,260 and this is going to be equal to viewController. 19 20 00:01:40,290 --> 00:01:47,960 So in the init of this class, I'm going to tap into that brand-new viewController with the lowercase "v" 20 21 00:01:48,050 --> 00:01:54,520 and I'm going to try and tap into its isFinish, 21 22 00:01:54,740 --> 00:01:56,540 so you can see it doesn't exist, right? 22 23 00:01:56,540 --> 00:02:00,450 It's not letting me get into that private var at all. 23 24 00:02:00,650 --> 00:02:07,850 But let's see if I delete that Keywood "private," and make sure that you save this viewController file 24 25 00:02:07,850 --> 00:02:10,310 while your cursor is inside the file. 25 26 00:02:10,310 --> 00:02:17,030 And now, if I head over to my Test.swift, then I can say viewController.isFinishedTypingNumber, 26 27 00:02:17,030 --> 00:02:19,730 and you can see it's now accessible. 27 28 00:02:19,820 --> 00:02:26,440 And, again, if I just go ahead and add this private over here and hit save again, 28 29 00:02:26,510 --> 00:02:31,840 then over here, you'll see that this will soon turn into black. 29 30 00:02:31,880 --> 00:02:37,310 Then if I hit command B to force it to build, then you can see that it says, "'isFinishedTypingNumber' 30 31 00:02:37,310 --> 00:02:41,360 is inaccessible due to 'private' protection level." 31 32 00:02:41,360 --> 00:02:45,550 So what exactly is this whole private protection level anyways? 32 33 00:02:45,620 --> 00:02:52,040 So Swift has something called Access Levels. And a good analogy for access levels is kind of like the 33 34 00:02:52,040 --> 00:02:57,260 clearance level that people working in the government, for example, have. 34 35 00:02:57,410 --> 00:03:04,100 I don't know about you, but I watch a lot of shows that involve the CIA or the FBI or, of course, 35 36 00:03:04,100 --> 00:03:04,800 Jack Bauer. 36 37 00:03:05,060 --> 00:03:11,940 And what you hear very often is something like, "You don't have clearance to view this file," 37 38 00:03:11,960 --> 00:03:12,480 right? 38 39 00:03:12,740 --> 00:03:20,780 And there are certain things that our top secret and only a select number of people can have access 39 40 00:03:20,780 --> 00:03:22,490 to it and see it. 40 41 00:03:22,490 --> 00:03:25,700 So you know common things are: are there aliens? 41 42 00:03:25,700 --> 00:03:28,790 Did we actually land on the moon? And all of these things. 42 43 00:03:28,940 --> 00:03:32,950 But this is exactly what Swift Access Levels do. 43 44 00:03:32,990 --> 00:03:38,900 Now, while most programming languages have different access levels, they are slightly different from language 44 45 00:03:38,900 --> 00:03:39,850 to language. 45 46 00:03:39,890 --> 00:03:48,080 Now, Swift 4.2 and above have five different access levels or five different tiers of clearance if you 46 47 00:03:48,080 --> 00:03:48,730 will. 47 48 00:03:48,950 --> 00:03:52,270 And the first here is private. 48 49 00:03:52,370 --> 00:03:59,990 This is, as the name suggests, very, very limiting in scope and it means that when you create a property 49 50 00:04:00,050 --> 00:04:08,870 or method inside a block of code, then that property or method is only accessible in between the curly 50 51 00:04:08,870 --> 00:04:11,210 braces of that block of code. 51 52 00:04:11,210 --> 00:04:18,470 Now, the next least restrictive is something called fileprivate, and as it suggests, it means that your 52 53 00:04:18,470 --> 00:04:24,170 property or your method is only accessible inside the file that it was declared. 53 54 00:04:24,170 --> 00:04:30,390 So this will be your ViewController.swift or your Test.swift, and you can access a property or 54 55 00:04:30,390 --> 00:04:33,140 a method from a different file. 55 56 00:04:33,140 --> 00:04:40,820 Now, the third one is what's called internal and this means that your property or methods are accessible 56 57 00:04:41,210 --> 00:04:44,640 anywhere inside your current app module. 57 58 00:04:44,810 --> 00:04:51,230 So this is also the default level of access that all properties and methods are given. 58 59 00:04:51,410 --> 00:04:52,820 And it means that if you don't 59 60 00:04:52,820 --> 00:04:57,850 add the key keyword "private" or "fileprivate" in front of your "var' or your "let," then 60 61 00:04:57,860 --> 00:05:02,960 this is exactly what it will be, it will be internal access. And it kind of makes sense, 61 62 00:05:02,960 --> 00:05:10,850 right? By default, Xcode lets all the files in the app access all of the other properties and methods 62 63 00:05:10,940 --> 00:05:12,550 in the app. 63 64 00:05:12,560 --> 00:05:14,890 Now, the next level is public. 64 65 00:05:15,200 --> 00:05:20,300 And this means that access is granted to other modules. 65 66 00:05:20,330 --> 00:05:27,490 Now, when we were working with CocoaPods, you saw that we had a pod module and we also had our app module. 66 67 00:05:27,720 --> 00:05:31,950 And this is exactly what the public access level was created for. 67 68 00:05:31,970 --> 00:05:38,480 It's when you're creating frameworks or APIs, or SDKs, or libraries, basically, a bunch of code which 68 69 00:05:38,480 --> 00:05:42,220 you want other modules to be able to tap into and use. 69 70 00:05:42,230 --> 00:05:49,610 Now, the final one and the least restrictive access level is called open, and this is basically like public 70 71 00:05:49,820 --> 00:05:50,410 plus, 71 72 00:05:50,420 --> 00:05:50,800 right? 72 73 00:05:50,810 --> 00:05:56,720 This is everything that you get in the public access level, namely the properties and methods, and everything 73 74 00:05:56,720 --> 00:05:59,370 can be accessed by other modules. 74 75 00:05:59,540 --> 00:06:05,950 But also it allows your classes and functions to be subclassed and overridden. 75 76 00:06:05,960 --> 00:06:09,320 So it basically means that anybody can do anything they want 76 77 00:06:09,320 --> 00:06:17,900 when you label something as open. Now, for your standard app development, you will only use one to three. 77 78 00:06:17,930 --> 00:06:21,260 That's the only ones that we concern ourselves with. 78 79 00:06:21,380 --> 00:06:26,960 But for developers who are working on frameworks, library, SDK development, then they will be looking into 79 80 00:06:26,960 --> 00:06:29,020 using four and five. 80 81 00:06:29,410 --> 00:06:35,780 And this is because their module that they're working on their library or their framework is going to 81 82 00:06:35,780 --> 00:06:39,360 need to be exposed to other developers. 82 83 00:06:39,440 --> 00:06:47,090 And the only difference between these last two levels is that public doesn't allow the class or the 83 84 00:06:47,090 --> 00:06:50,600 function to be subclassed or overridden while open, 84 85 00:06:50,600 --> 00:06:53,620 basically, lets you do whatever it is that you want. 85 86 00:06:53,720 --> 00:07:00,230 So if you take a look at, for example, the Clima project that we built previously, and you look inside 86 87 00:07:00,290 --> 00:07:06,430 the Pods modules, so everything that has a blue icon is its own module. 87 88 00:07:06,500 --> 00:07:14,240 And remember, we mentioned that the internal or rather the default level of access, everything gets, is 88 89 00:07:14,330 --> 00:07:15,550 module white, 89 90 00:07:15,560 --> 00:07:15,860 right? 90 91 00:07:15,860 --> 00:07:22,280 So that means everything that you declare within Clima will have access to everything else that is 91 92 00:07:22,280 --> 00:07:23,780 inside Clima. 92 93 00:07:23,780 --> 00:07:28,460 Now, in this case, when we're using pods, we actually have two modules now, right? 93 94 00:07:28,490 --> 00:07:30,170 Pods and Clima. 94 95 00:07:30,350 --> 00:07:34,600 And inside the Pods, one of the ones that we've incorporated is Alamofire. 95 96 00:07:34,850 --> 00:07:41,970 And if you look inside the Alamofire code, you can see that there's public all over the place. 96 97 00:07:41,990 --> 00:07:49,130 Literally, all of the methods that are needed when somebody incorporates the Alamofire pod is going 97 98 00:07:49,130 --> 00:07:55,330 to be marked with public to allow this module to tap into this file 98 99 00:07:55,440 --> 00:07:56,990 and these methods. 99 100 00:07:56,990 --> 00:08:05,300 So coming back to our code, the best practice when you're thinking about access levels is to by default 100 101 00:08:05,630 --> 00:08:12,010 just give everything a private keyword whenever you write a var or let or func, 101 102 00:08:12,080 --> 00:08:17,470 so any of your own properties and methods, just write a private in front of it as well. 102 103 00:08:17,480 --> 00:08:25,280 Now, in a lot of cases, it can't be private because you need to use it somewhere else outside its current 103 104 00:08:25,280 --> 00:08:25,950 scope. 104 105 00:08:26,000 --> 00:08:33,740 But if you start off with private and you level up to file private or to internal, then that means that 105 106 00:08:33,740 --> 00:08:39,360 you are starting out by being extremely restrictive and extremely safe, 106 107 00:08:39,530 --> 00:08:45,360 and you'll only expose your properties and your methods a little bit more as and when necessary. 107 108 00:08:45,560 --> 00:08:49,490 So what are the advantages of marking something private anyways? 108 109 00:08:49,670 --> 00:08:56,960 Well, it means that you can't accidentally modify something that is not meant to be modified by a different 109 110 00:08:56,960 --> 00:08:59,620 class or from a different place. 110 111 00:08:59,630 --> 00:09:08,220 So inside Test that I created earlier on, let's say that I tried to change is typing number to 111 112 00:09:08,600 --> 00:09:09,200 true, 112 113 00:09:09,350 --> 00:09:17,000 so now if we didn't have this variable marked as private, then this other class Test could legitimately 113 114 00:09:17,270 --> 00:09:23,040 modify this property isFinishedTypingNumber to true when it's initialized. 114 115 00:09:23,060 --> 00:09:25,870 And this is definitely not what you want, right? 115 116 00:09:25,880 --> 00:09:33,830 We don't want this tracker to be modified by anybody else because nobody has any business in messing around 116 117 00:09:33,890 --> 00:09:37,490 with the state of this Boolean. 117 118 00:09:37,580 --> 00:09:45,470 It should only be accessed by this current class and only when the typing is indeed done, 118 119 00:09:45,470 --> 00:09:53,690 so, for example, when the calc button is pressed or when the calculator is initialized from scratch. 119 120 00:09:53,810 --> 00:09:57,850 So this should be something that is completely private to this class. 120 121 00:09:58,040 --> 00:10:05,990 And so we should, in fact, market with a private to prevent accidental modification by other classes. 121 122 00:10:05,990 --> 00:10:08,670 Now, this can happen accidentally. 122 123 00:10:08,780 --> 00:10:15,540 So, say, you forget that, you know, what was the purpose of isFinishedTypingNumber, or in another case, 123 124 00:10:15,560 --> 00:10:21,890 if you're working and you're collaborating with other developers, they might have used this name for 124 125 00:10:21,890 --> 00:10:28,120 something else in a different class, and they accidentally modify the one in the ViewController class. 125 126 00:10:28,130 --> 00:10:30,480 All of this can happen accidentally. 126 127 00:10:30,620 --> 00:10:37,130 So to prevent that and to make your code safer, try to use access levels by starting out with private 127 128 00:10:37,130 --> 00:10:43,400 for all of you "vars" and "lets," and methods, and leveling it up only when it's necessary. 128 129 00:10:43,670 --> 00:10:48,080 All right, so let's go ahead and delete that test file because we won't need it from here onwards. 129 130 00:10:48,260 --> 00:10:53,450 And I've got a challenge for you just so that you can play around with the code, so that you can better 130 131 00:10:53,450 --> 00:10:58,800 understand these ideas that we've talked about in this lesson on Swift access levels. 131 132 00:10:58,820 --> 00:11:05,720 So this is a Mac command line tool that I've created and it's got simply two files. 132 133 00:11:05,720 --> 00:11:13,460 One is called AFile and inside AFile, there is a class, and there is also another class in the same 133 134 00:11:13,460 --> 00:11:13,900 file. 134 135 00:11:14,060 --> 00:11:16,270 You can see where what I'm getting at. 135 136 00:11:16,310 --> 00:11:21,800 Now, there's also another file which has a class called AnotherClassInAnotherFile. 136 137 00:11:21,980 --> 00:11:30,650 And inside AFile, I've created a private var, fileprivate var, and a normal var which remember is going 137 138 00:11:30,650 --> 00:11:32,990 to default to internal. 138 139 00:11:33,050 --> 00:11:39,050 Now, just for comparison, I've also created aLocalVariable because, remember, when we're adding access 139 140 00:11:39,050 --> 00:11:39,620 levels, 140 141 00:11:39,680 --> 00:11:45,550 we're only able to add it to our class properties which are, in fact, Global variables. 141 142 00:11:45,560 --> 00:11:47,640 They're not the same as local variables. 142 143 00:11:47,840 --> 00:11:54,760 So I want you to go through these steps 1 through to 10 and try to complete all of the instructions. 143 144 00:11:54,870 --> 00:11:59,790 Now, in order to do this, you're going to need to initialize some objects, you're going to need to call 144 145 00:11:59,790 --> 00:12:05,610 some methods. But, essentially, through completing these 10 steps, I want you to be able to see for yourself 145 146 00:12:05,880 --> 00:12:08,710 just what these access levels do. 146 147 00:12:08,820 --> 00:12:14,430 And the ones that we're going to be exploring are the ones that you're actually going to use as a app developer. 147 148 00:12:14,430 --> 00:12:17,920 So from private, fileprivate, internal, and local. 148 149 00:12:18,030 --> 00:12:23,280 And once you've completed this exercise, you should have dissected the differences between all of these 149 150 00:12:23,550 --> 00:12:27,820 and understand exactly how they work and what their scopes are. 150 151 00:12:27,990 --> 00:12:32,580 So let's go through Step 1 together, just so I can show you how to do this. 151 152 00:12:32,640 --> 00:12:37,380 So Step1 the instruction is "Try to print aLocalVariable Here." 152 153 00:12:37,560 --> 00:12:42,780 So you can see I've already created aLocalVariable as a var inside methodA 153 154 00:12:42,810 --> 00:12:44,640 inside a class. 154 155 00:12:44,640 --> 00:12:51,120 So in order to print it here, all I have to do is say "print." Now, in my print statement, that's going to get sent 155 156 00:12:51,180 --> 00:12:53,520 to the bottom of my debug console. 156 157 00:12:53,700 --> 00:12:56,130 I want to know where it came from. 157 158 00:12:56,130 --> 00:13:04,130 So in addition to simply printing my aLocalVariable, I also want to say aLocalVariable printed from 158 159 00:13:04,230 --> 00:13:06,930 methodA in AClass. 159 160 00:13:06,930 --> 00:13:10,680 So, now here's my print statement and I have to make it work. 160 161 00:13:10,680 --> 00:13:12,800 Now, I have to make it actually run. 161 162 00:13:12,840 --> 00:13:18,630 So if you remember from previous lessons when we dug into intermediate Swift, we can use the Mac command 162 163 00:13:18,630 --> 00:13:20,900 line tool by calling commands 163 164 00:13:20,900 --> 00:13:22,800 inside this main.swift. 164 165 00:13:22,890 --> 00:13:30,270 So in order for this methodA to be carried out, I have to initialize a new object from the class AClass, 165 166 00:13:30,360 --> 00:13:32,910 and then call the methodA on that object. 166 167 00:13:33,060 --> 00:13:43,050 So I can do that by saying let aClass = AClass and we'll initialize a new object from that, and then 167 168 00:13:43,080 --> 00:13:48,810 I'm going to tap into that lower case aClass object that I just created and I'm going to call the method 168 169 00:13:48,900 --> 00:13:50,510 methodA on it. 169 170 00:13:50,520 --> 00:13:57,750 So, now what should happen is once I run this command line tool, it should go in and try to create a new 170 171 00:13:57,750 --> 00:14:04,650 object from this class, and then it will run all the code inside methodA which should, hopefully, print 171 172 00:14:04,770 --> 00:14:07,510 on a local variable to the debug console. 172 173 00:14:07,650 --> 00:14:08,890 So let's give it a go. 173 174 00:14:11,910 --> 00:14:12,570 All right. Great. 174 175 00:14:12,580 --> 00:14:18,520 So it says local variable printed from methodA in AClass program ended with exit code. 175 176 00:14:18,520 --> 00:14:21,320 So that's the end of our execution 176 177 00:14:21,490 --> 00:14:24,190 and that is exactly what we wanted to happen. 177 178 00:14:24,190 --> 00:14:26,200 So step one succeeds. 178 179 00:14:26,350 --> 00:14:34,040 So next to it will mark that it is possible to print aLocalVariable within methodA within AClass. 179 180 00:14:34,120 --> 00:14:40,300 And now I'm going to go ahead and either delete or just commented out so that you take it out of the 180 181 00:14:40,300 --> 00:14:45,400 functioning code because if we get loads of these print statements, as you can see we've got Steps 1 181 182 00:14:45,400 --> 00:14:46,190 through 10, 182 183 00:14:46,270 --> 00:14:49,330 it'll get very confusing in the debug console. 183 184 00:14:49,330 --> 00:14:52,720 Now, this is completely up to you whichever way you find easier, 184 185 00:14:52,750 --> 00:14:58,180 but I find through testing that shouldn't get a bit confused when there's like 10 print statements. 185 186 00:14:58,270 --> 00:15:00,720 So just go ahead and comment this out 186 187 00:15:00,730 --> 00:15:01,920 if that helps you. 187 188 00:15:02,180 --> 00:15:08,890 Now, in the next lesson, there is a quiz where we will test to see whether you've actually managed to 188 189 00:15:08,890 --> 00:15:15,550 make all of these work because some of these steps are indeed possible, and some of the other ones, because 189 190 00:15:15,610 --> 00:15:19,390 of the restrictions in access levels, are not possible. 190 191 00:15:19,390 --> 00:15:25,540 So the idea here is that before you start executing the code and running it to prove to yourself whether 191 192 00:15:25,630 --> 00:15:32,080 if it's possible or not, I want you to go through this step by step and try to predict whether if they should 192 193 00:15:32,080 --> 00:15:33,300 be possible or not. 193 194 00:15:33,340 --> 00:15:40,210 Because as always,, I think the best way to learn programming, especially, is to predict what should happen, 194 195 00:15:40,540 --> 00:15:43,790 and then run the code and see what actually happens. 195 196 00:15:43,900 --> 00:15:50,050 And that difference between your prediction and the actual reality narrowing that gap and trying to 196 197 00:15:50,050 --> 00:15:55,420 make it so that there is no difference between your prediction and reality is how you really level up 197 198 00:15:55,600 --> 00:15:56,820 as a programmer. 198 199 00:15:56,980 --> 00:16:02,620 So Step 1 of completing this challenge is go through these Steps 1 through 10 and see what they're 199 200 00:16:02,620 --> 00:16:04,120 trying to ask you to do, 200 201 00:16:04,360 --> 00:16:10,720 and then using your knowledge of Swift access levels, try to predict whether if they are possible or not 201 202 00:16:10,980 --> 00:16:14,280 in the locations that they have been specified in. 202 203 00:16:14,290 --> 00:16:21,280 And then the next step is to go through Steps 1 through 10 and try to carry out the instructions to print 203 204 00:16:21,370 --> 00:16:27,250 whatever it is that you need to print at the location where you're asked to print it. And then you might 204 205 00:16:27,250 --> 00:16:34,460 need to initialize objects or call methods in order to make it show up in the debug console. 205 206 00:16:34,570 --> 00:16:40,570 So as we're in the advance Swift section, I'm not going to give away any more solutions, and it's time 206 207 00:16:40,570 --> 00:16:44,420 for you to mess around with the code and really learn through doing. 207 208 00:16:44,420 --> 00:16:51,160 So pause the video now and download this file from the Course Resources List and go ahead and try to complete it. 208 209 00:16:51,160 --> 00:16:52,150 Once you are done, 209 210 00:16:52,150 --> 00:16:57,430 head over to the next lesson and complete the quiz, so that you can check to see if you've got all the 210 211 00:16:57,490 --> 00:16:58,780 answers right. 211 212 00:16:59,020 --> 00:16:59,290 All right. 212 213 00:16:59,290 --> 00:17:00,130 So have fun. 213 214 00:17:00,190 --> 00:17:01,520 Go ahead and do that now.