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.
