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