0
1
00:00:00,840 --> 00:00:09,600
Hey, guys. Before we proceed onwards and start using Firebase Firestore to save our messages and send
1

2
00:00:09,600 --> 00:00:16,800
messages over for storage, I wanted to quickly take a moment to do a Swift Deep Dive on something that
2

3
00:00:16,800 --> 00:00:21,860
you might have seen in the last lesson that might still yet be a little bit confusing.
3

4
00:00:21,900 --> 00:00:24,790
So notice how in this line here,
4

5
00:00:24,810 --> 00:00:26,030
line 54,
5

6
00:00:26,190 --> 00:00:31,930
we created a cell by calling this method at dequeueReusableCell withIdentifier.
6

7
00:00:32,130 --> 00:00:38,310
We provided the identifier that comes from that cell that we created in the custom xib and we were
7

8
00:00:38,310 --> 00:00:46,080
hoping that our table view would just create this cell and slot it in. But right at the end here,
8

9
00:00:46,080 --> 00:00:50,250
we used this syntax "as!" 
9

10
00:00:50,280 --> 00:00:50,830
MessageCell.
10

11
00:00:50,830 --> 00:00:56,760
What exactly does this do and what does it mean anyways?
11

12
00:00:56,850 --> 00:01:01,470
So in this Swift Deep Dive, I want to talk about exactly this.
12

13
00:01:01,470 --> 00:01:08,550
I want to talk about Type Casting because that's pretty much what that "as!" keyword does.
13

14
00:01:08,550 --> 00:01:18,540
Now, recently, I went to this workshop in Wales in the UK where we were casting sword from stone. So adding
14

15
00:01:18,540 --> 00:01:26,580
copper and tin into a crucible that was heated really hot, and then it was poured into this soapstone mold.
15

16
00:01:26,580 --> 00:01:35,900
And after the metal cools down, you end up creating a completely different shape, right?
16

17
00:01:35,940 --> 00:01:38,190
The shape of a bronze sword.
17

18
00:01:38,190 --> 00:01:43,980
Now, there's a lot more to creating a bronze sword including two days of polishing the sword in Wales
18

19
00:01:44,730 --> 00:01:51,900
which is freezing. But by the end, you create this beautifully, shiny mirror-like surface of a sword and
19

20
00:01:51,900 --> 00:01:53,540
it was really really cool.
20

21
00:01:53,610 --> 00:01:59,130
So how does this relate to what we're trying to learn? Now, as your coding and as you're looking at other
21

22
00:01:59,130 --> 00:02:07,420
people's code, you might notice these keywords as, as question mark, as exclamation mark, and is.
22

23
00:02:07,620 --> 00:02:14,470
And in this lesson, I want to explain to you what all of these keywords do, and when we would use them.
23

24
00:02:14,590 --> 00:02:20,830
So here I've set up a playgrounds which has something that you should already be familiar with from
24

25
00:02:20,830 --> 00:02:24,530
learning about classes and object-oriented programming
25

26
00:02:24,550 --> 00:02:31,360
in previous lessons. Here we've got three classes created, one called Animal, one called Human, and one
26

27
00:02:31,360 --> 00:02:32,980
called Fish.
27

28
00:02:32,980 --> 00:02:40,810
The animals all have a name and when you create any new animal, you initialize that new object with a
28

29
00:02:40,810 --> 00:02:42,150
name.
29

30
00:02:42,160 --> 00:02:47,560
Now, we've also created our Human class to be a subclass of Animal.
30

31
00:02:47,560 --> 00:02:49,730
It's inheriting from the Animal class.
31

32
00:02:49,750 --> 00:02:53,070
So, that means all humans also get to have a name.
32

33
00:02:53,110 --> 00:02:57,200
And, similarly, our Fish class is also inheriting from the Animal class.
33

34
00:02:57,220 --> 00:03:01,600
So these are what you would call subclasses and this is the superclass.
34

35
00:03:01,720 --> 00:03:08,140
Now, humans and fish can do all the things that animal can do which is why it inherits.
35

36
00:03:08,140 --> 00:03:14,050
But it can also do some specialized things like humans might be able to code and fish might be able
36

37
00:03:14,050 --> 00:03:16,040
to breathe underwater,
37

38
00:03:16,120 --> 00:03:18,890
so there's really nothing new in this code here.
38

39
00:03:18,940 --> 00:03:26,260
And if any of this looks unfamiliar, then I recommend having a quick revision of the lessons that we
39

40
00:03:26,260 --> 00:03:31,470
did on classes and objects and object-oriented programming.
40

41
00:03:31,570 --> 00:03:37,930
So, now that we've created our classes, let's go ahead and create some objects or instances from these
41

42
00:03:37,930 --> 00:03:38,920
classes.
42

43
00:03:38,920 --> 00:03:41,210
So let's say that I decide to create me,
43

44
00:03:41,230 --> 00:03:49,930
so Angela as a human, and we automatically get this initializer from the superclass Animal class, because
44

45
00:03:49,990 --> 00:03:56,260
human inherits from animal, and the name is going to be my name, of course.
45

46
00:03:56,260 --> 00:04:04,270
And then let's create another human, let's create Jack who's also a human and his name is Jack Bauer.
46

47
00:04:05,260 --> 00:04:09,500
And then, let's create somebody called Nemo.
47

48
00:04:09,520 --> 00:04:11,170
Nemo is a fish.
48

49
00:04:11,710 --> 00:04:14,830
And his name is Nemo.
49

50
00:04:14,830 --> 00:04:15,130
Great.
50

51
00:04:15,190 --> 00:04:21,700
So we've got three objects created from our classes, two humans and one fish.
51

52
00:04:21,790 --> 00:04:29,170
So let's say that we decided to create a array called neighbours, and these neighbours who live really
52

53
00:04:29,170 --> 00:04:36,740
close together are me, Jack, and Nemo. At this point,
53

54
00:04:36,850 --> 00:04:42,240
we've created an array using objects of different types, right?
54

55
00:04:42,520 --> 00:04:49,690
We've got Angela who has a type of human, Jack type of human, but Nemo has a type of fish, and they're
55

56
00:04:49,690 --> 00:04:57,520
allowed to fit into the same array because they have a common superclass Animal.
56

57
00:04:57,640 --> 00:05:03,220
So this neighbour's array is an array of Animal objects.
57

58
00:05:03,220 --> 00:05:12,280
That means if I was to pull out an item, say, the item at index 0 from this neighbour's array, you'll see
58

59
00:05:12,280 --> 00:05:15,010
that it still is an animal class.
59

60
00:05:15,040 --> 00:05:21,370
It doesn't revert back to the human class, even though we know that this is definitely of type Human
60

61
00:05:22,000 --> 00:05:27,420
because the array has mixed types. In order to store them in this mixed array,
61

62
00:05:27,490 --> 00:05:32,720
they have to find some commonality and that is, of course, the Animal superclass.
62

63
00:05:32,860 --> 00:05:38,680
So, now is where some of those type casting keywords come in handy.
63

64
00:05:38,770 --> 00:05:45,340
Previously, we've seen type casting in the sense that we've able to create a double, let's say, 
64

65
00:05:45,340 --> 00:05:51,550
myDouble = 0.0, and let's just  do a quick old option click check, you can see this is definitely a
65

66
00:05:51,550 --> 00:05:59,620
double data type. But if I wanted to create myDoubleAsAnInt, then I would use the int data type,
66

67
00:06:00,100 --> 00:06:07,500
open up a set of parentheses, and inside here, I get to put in myDouble,
67

68
00:06:07,900 --> 00:06:16,600
and it's able to cast this myDouble which has type double into something that has type int.
68

69
00:06:16,630 --> 00:06:25,270
Now, this is not really quite type casting, even though it does, in fact, change the type of myDouble into
69

70
00:06:25,390 --> 00:06:26,440
an Int.
70

71
00:06:26,620 --> 00:06:33,940
This is actually achieved through initialization. So if we take a look at the documentation
71

72
00:06:33,940 --> 00:06:35,260
for the Swift standard library,
72

73
00:06:35,260 --> 00:06:43,070
you can see that under the document for int it has a whole bunch of initializers. And one of these initializers
73

74
00:06:43,070 --> 00:06:48,110
is used for converting floating-point values such as doubles and floats.
74

75
00:06:48,340 --> 00:06:55,150
And this particular initializer is the one that's responsible for creating a new integer object from
75

76
00:06:55,360 --> 00:07:04,560
the double value, and it rounds towards zero. So without this initializer being created for Int, 
76

77
00:07:04,620 --> 00:07:08,220
then we wouldn't be able to do this and change the data type.
77

78
00:07:09,150 --> 00:07:18,060
But in our case, if we wanted this neighbour1 to be treated as the human that it is, we have to do something
78

79
00:07:18,090 --> 00:07:19,380
different.
79

80
00:07:19,410 --> 00:07:23,630
So first thing we can do is we can check what data type it is.
80

81
00:07:23,640 --> 00:07:33,780
So, for example, we can say if neighbour 0, which is this one, is of data type Human,
81

82
00:07:33,810 --> 00:07:45,300
well, then we can print "First Neighbour is a Human." And if I go ahead and run this code, you'll see that
82

83
00:07:45,300 --> 00:07:52,000
what I get printed is, in fact, this because neighbour 0 is indeed a human.
83

84
00:07:52,020 --> 00:07:57,410
So we could perform this check and it tells us what data type it is.
84

85
00:07:57,510 --> 00:08:03,900
And you can do this if you wanted to, say, you could check if Jack is human.
85

86
00:08:03,900 --> 00:08:09,300
And the thing is we already know that Jack is human, and this is why when you try to write this code
86

87
00:08:09,330 --> 00:08:15,810
which is extremely obvious already without any sort of checking the Xcode compiler, it will actually tell
87

88
00:08:15,810 --> 00:08:22,830
you that this particular test is always going to be true, because there is no uncertainty about the data
88

89
00:08:22,830 --> 00:08:28,920
type of Jack. Whereas in this case, when we're tapping into the neighbour's array where everything is of
89

90
00:08:28,920 --> 00:08:38,550
type animal and we said, let's say, try to get the item at index 2, so 0, 1, 2, and we said, well, what if neighbours
90

91
00:08:38,600 --> 00:08:40,420
at index 2 is human.
91

92
00:08:40,440 --> 00:08:46,800
And then, in this case, we actually get nothing printed because neighbours at index 2 is in fact of type
92

93
00:08:46,890 --> 00:08:48,630
fish.
93

94
00:08:48,630 --> 00:08:57,270
So this "is" keyword, basically, allows us to have a object from a certain data type, and then check whether
94

95
00:08:57,270 --> 00:09:03,600
if that object is of that data type. So in this case, if we had a cell created from a UITableVieCell,
95

96
00:09:03,600 --> 00:09:09,420
and we check, if it is indeed that data type between the left-hand side of the "is" 
96

97
00:09:09,420 --> 00:09:11,030
and the right-hand side of the "is."
97

98
00:09:11,070 --> 00:09:19,690
So this keyword is used for type checking. So let's say that I decided to go and create a function,
98

99
00:09:19,690 --> 00:09:22,020
let's call it find Nemo.
99

100
00:09:22,270 --> 00:09:28,870
And this function takes a input in the form of an array of Animal objects.
100

101
00:09:28,870 --> 00:09:34,020
So we're going to say findNemo, from, as the external parameter name,
101

102
00:09:34,180 --> 00:09:40,930
and then inside the function, we're going to refer to it as the animals.
102

103
00:09:40,930 --> 00:09:48,230
So, now we've got our function created and we're going to go ahead and loop through our Animal's array.
103

104
00:09:48,250 --> 00:09:52,740
So let's say for animal in animals.
104

105
00:09:52,780 --> 00:09:58,900
So in this case, we're looping through the array animals and for every single animal in that array, 
105

106
00:09:58,900 --> 00:10:01,200
we're going to run the code in here.
106

107
00:10:01,270 --> 00:10:05,410
We can either simply just print animal.name.
107

108
00:10:05,410 --> 00:10:11,810
So this is pretty bog-standard sort of "for loop" kind of functionality that you've already learned about.
108

109
00:10:12,160 --> 00:10:20,380
And in this case, when the code runs, when I call findNemo from our neighbours array, go ahead and hit
109

110
00:10:20,380 --> 00:10:21,020
run,
110

111
00:10:21,200 --> 00:10:27,440
then you can see that we've got all the names of our animals in our neighbours array being printed out.
111

112
00:10:27,520 --> 00:10:29,420
So that's just a simple for loop.
112

113
00:10:29,440 --> 00:10:34,900
But what if I actually wanted to find Nemo inside this array of animals?
113

114
00:10:34,900 --> 00:10:44,440
Well, I could say that if the animal that we're currently looping on is of type fish, then that seems pretty
114

115
00:10:44,440 --> 00:10:45,100
suspicious,
115

116
00:10:45,100 --> 00:10:45,450
right?
116

117
00:10:45,460 --> 00:10:46,820
Maybe that's going to be Nemo.
117

118
00:10:47,200 --> 00:10:52,570
So let's go ahead and print that animal's name property.
118

119
00:10:52,630 --> 00:11:01,540
So, now what will happen if I run findNemo from neighbours is that we're going to get Nemo printed out
119

120
00:11:01,870 --> 00:11:08,320
because it's looping through all of the animals and checking each of them to see if they match the data
120

121
00:11:08,320 --> 00:11:14,740
type of fish. And when it does, then it prints out the animal name.
121

122
00:11:14,740 --> 00:11:21,850
Now, notice how, in this case, inside this set of curly braces, we're pretty certain that this particular animal
122

123
00:11:21,850 --> 00:11:25,420
that we've currently got access to is definitely a fish,
123

124
00:11:25,420 --> 00:11:25,720
right?
124

125
00:11:25,720 --> 00:11:32,050
Because we've checked if this animal is a fish before we actually trigger this block. But notice how
125

126
00:11:32,050 --> 00:11:37,900
in here, even though we're certain of that data type, we can't say something like, well, this a
126

127
00:11:38,260 --> 00:11:43,150
nimal.breatheUnderWater because that's what all fish data types can do,
127

128
00:11:43,160 --> 00:11:43,390
right?
128

129
00:11:43,390 --> 00:11:46,450
They have this functionality breatheUnderWater.
129

130
00:11:46,450 --> 00:11:51,190
But in fact it says, "Value of type 'Animal' has no member 'breatheUnderWater.'"
130

131
00:11:51,580 --> 00:11:58,150
So in this case, what's happening is that this particular animal, even though we know it is a fish, we've
131

132
00:11:58,150 --> 00:12:05,110
checked it. It still has that data type animal. So we're not able to tap into the specialized functionality
132

133
00:12:05,290 --> 00:12:07,150
of the fish.
133

134
00:12:07,150 --> 00:12:09,460
So what can we do in this case?
134

135
00:12:09,460 --> 00:12:16,990
Well, we can use something called forced down casting where we cast from the Animal class down to one
135

136
00:12:16,990 --> 00:12:18,460
of its subclasses.
136

137
00:12:18,550 --> 00:12:20,290
Like in this case, fish.
137

138
00:12:20,530 --> 00:12:29,700
So we could write something like let fish = animal as! Fish.
138

139
00:12:29,740 --> 00:12:35,980
So what this now does is it takes that animal which we've already checked and made sure is definitely
139

140
00:12:35,980 --> 00:12:44,590
of type fish, and we use the "as exclamation mark" to cast it down to one of the animals subclasses namely
140

141
00:12:44,590 --> 00:12:45,370
the Fish class.
141

142
00:12:45,940 --> 00:12:51,170
So, now with this fish created, we can now go ahead and tap into that method
142

143
00:12:51,190 --> 00:12:52,840
breathUnderWater.
143

144
00:12:52,930 --> 00:13:01,780
And when we run our code, you can see that Nemo is breathing underwater. So the "as exclamation mark" is
144

145
00:13:01,780 --> 00:13:07,630
used when, let's say, we've created a cell which is still the UI Table of your cell which, remember,
145

146
00:13:07,630 --> 00:13:09,100
is the superclass.
146

147
00:13:09,100 --> 00:13:16,480
And then we wanted to turn it into a subclass, for example, on message cell that you saw in our code earlier
147

148
00:13:16,480 --> 00:13:17,290
on.
148

149
00:13:17,350 --> 00:13:20,590
Well, in this case, we can use the "as exclamation mark."
149

150
00:13:20,590 --> 00:13:28,710
And now, this message cell object has converted or cast its data type into a subclass,
150

151
00:13:28,780 --> 00:13:34,150
so going down, and this is called forced downcast.
151

152
00:13:34,150 --> 00:13:39,720
Now, the problem with a forced downcast is that unless you're sure,
152

153
00:13:39,730 --> 00:13:45,130
say, for example, in this case, we're pretty sure that this particular animal that matches the Fish data
153

154
00:13:45,130 --> 00:13:48,090
type can be cast down into a Fish data type.
154

155
00:13:48,370 --> 00:14:00,280
But let's say that you decided to cast the neighbour at index 1, which is Jack, to a fish.
155

156
00:14:00,730 --> 00:14:02,780
So Jack's not going to like that very much.
156

157
00:14:02,950 --> 00:14:05,980
But let's go ahead and try it.
157

158
00:14:06,010 --> 00:14:08,240
Let's see what actually happens.
158

159
00:14:08,260 --> 00:14:10,770
So, you'll notice that I'm not getting any warnings,
159

160
00:14:11,020 --> 00:14:13,360
any problems, any errors at all
160

161
00:14:13,360 --> 00:14:15,930
because this is perfectly valid code.
161

162
00:14:16,120 --> 00:14:20,920
This is pretty much the same as if we did this, right?
162

163
00:14:20,920 --> 00:14:23,700
The compiler can't tell that it's going to fail.
163

164
00:14:23,740 --> 00:14:28,610
Now, we know because we can see right now what is at index 1,
164

165
00:14:28,660 --> 00:14:31,860
but let me just show you what happens when I try to run this code.
165

166
00:14:32,050 --> 00:14:37,450
You can see that it's at runtime, when your app is actually running in the user's hands,
166

167
00:14:37,570 --> 00:14:44,680
when this line of code is going to crash. And it tells us that it could not cast value of type Human
167

168
00:14:44,980 --> 00:14:46,920
to Fish.
168

169
00:14:47,110 --> 00:14:48,760
So that's the problem.
169

170
00:14:48,940 --> 00:14:54,280
Now, very often what happens is when we're dealing with data that we're getting back from the internet
170

171
00:14:54,370 --> 00:15:01,720
or from APIs, they often have a JSON or some sort of array where we're not really quite sure what's
171

172
00:15:01,720 --> 00:15:02,550
actually in it,
172

173
00:15:02,560 --> 00:15:02,940
right?
173

174
00:15:02,950 --> 00:15:04,780
Otherwise, we wouldn't be fetching it.
174

175
00:15:04,780 --> 00:15:12,940
So in these cases, unless you're certain that this cast is going to work, then a better option is to add
175

176
00:15:13,270 --> 00:15:17,200
a question mark, instead of an exclamation mark.
176

177
00:15:17,290 --> 00:15:26,020
But what this does is it turns this object that's cast from this object to a Fish data type into an
177

178
00:15:26,050 --> 00:15:27,080
optional.
178

179
00:15:27,080 --> 00:15:31,640
So, now if I check this data type, you can see it's a fish question mark.
179

180
00:15:32,080 --> 00:15:38,290
So that means if you wanted to be able to do something like a fish.breatheUnderWater, then you
180

181
00:15:38,290 --> 00:15:44,710
will either have to use the optional chaining, like how it's inserted this question mark here which says,
181

182
00:15:44,710 --> 00:15:48,310
basically, if fish is not nil, then call this method.
182

183
00:15:48,310 --> 00:15:57,370
Alternatively, you would have to use a optional bind, say, if let the neighbour at index 1 can be cast as
183

184
00:15:57,370 --> 00:16:00,590
a fish, well then go ahead and run this code.
184

185
00:16:00,610 --> 00:16:07,750
Now, if I run this code again, you'll notice that it doesn't actually crash anymore because this is actually
185

186
00:16:07,750 --> 00:16:14,130
being skipped. And in fact, I can add an 'else" statement to print that "Casting has failed."
186

187
00:16:15,090 --> 00:16:21,750
So let's run that code and you can see that it's the "else" case that gets triggered in this block of
187

188
00:16:21,750 --> 00:16:32,270
code. So the "as" keyword is a slightly safer way of performing this down casting capability, instead of
188

189
00:16:32,270 --> 00:16:36,860
simply just saying, "Yeah, yeah, you know cell is definitely gonna be convertible to message sell in all cases"
189

190
00:16:36,860 --> 00:16:43,400
when you're not sure it's better to actually use a "as" question mark.
190

191
00:16:43,400 --> 00:16:52,370
So this way, we only actually do the casting if it actually can be cast as the subclass. Whereas in this
191

192
00:16:52,370 --> 00:16:59,610
case, we can be pretty certain to downcast because we know that the animal is definitely a fish.
192

193
00:16:59,660 --> 00:17:05,270
Now, in other cases where you've written the code, say, you've created the array, you know what each of
193

194
00:17:05,270 --> 00:17:14,030
the items are, then you can also make the case that a forced downcast, in this case, is probably okay.
194

195
00:17:14,030 --> 00:17:21,950
So, the last keyword I want to show you is this thing called "as." For example, in this case, we know that this
195

196
00:17:22,040 --> 00:17:26,440
fish object has data type fish, right?
196

197
00:17:26,660 --> 00:17:32,090
But what if we wanted to turn it back into the data type of its superclass?
197

198
00:17:32,570 --> 00:17:43,160
Well, we can say, let animalFish = fish as, with no question mark or no exclamation mark,
198

199
00:17:43,160 --> 00:17:46,770
and then we can cast that to one of its superclasses.
199

200
00:17:46,790 --> 00:17:53,670
So in this case, we could say, turn it into an animal. And this takes the object which has the class Fish
200

201
00:17:54,270 --> 00:17:57,390
and raises up to the animal superclass.
201

202
00:17:57,390 --> 00:18:04,890
So now this animalFish has type animal, whereas it came from this object fish which had the subclass
202

203
00:18:04,980 --> 00:18:07,350
fish data type.
203

204
00:18:07,350 --> 00:18:15,630
So the "as" keyword by itself is simply used to raise a object to its superclasses type.
204

205
00:18:15,660 --> 00:18:20,530
So it's another form of casting but it's, perhaps, use a little bit less frequently.
205

206
00:18:20,700 --> 00:18:25,950
And the reason why it doesn't need to have an exclamation mark or a question mark is because when you
206

207
00:18:25,950 --> 00:18:31,530
take a subclass object and you convert it into a superclass, it's never going to fail.
207

208
00:18:31,530 --> 00:18:38,640
This is always going to work as long as this particular object that you're trying to cast is, indeed,
208

209
00:18:38,670 --> 00:18:42,780
inheriting from the data type that you're trying to cast it to.
209

210
00:18:42,780 --> 00:18:47,340
In other words, the "as" keyword is used to perform an Upcast.
210

211
00:18:47,460 --> 00:18:53,460
That said of casting is performed a lot less frequently than down casting, but it belongs in the set
211

212
00:18:53,520 --> 00:18:54,970
of as, as, as,
212

213
00:18:54,990 --> 00:18:57,430
so it's a good idea to talk about it.
213

214
00:18:57,690 --> 00:19:02,850
Now, the very last thing I want to talk to you about is some of these strange data types that you
214

215
00:19:02,850 --> 00:19:04,540
might have come across.
215

216
00:19:04,590 --> 00:19:10,710
This is a topic that's closely related type casting and working with types in general.
216

217
00:19:10,710 --> 00:19:14,890
Sometimes you don't want to be specific about the data type that you're working with.
217

218
00:19:14,940 --> 00:19:20,970
Sometimes you'll want flexibility and you'll want your code to accept a range of different data types.
218

219
00:19:21,810 --> 00:19:31,470
And in Swift, we have something called "any" which encompasses all objects, so objects derived from classes,
219

220
00:19:31,530 --> 00:19:36,490
from structs. Basically, it can be any data type just like the name.
220

221
00:19:36,720 --> 00:19:46,710
Now, within that group of any data type, there is a subclass of AnyObject data types, and these are object
221

222
00:19:46,800 --> 00:19:49,800
that have to be derived from classes.
222

223
00:19:49,800 --> 00:19:57,390
So sometimes you'll see certain protocols that have a requirement where only an object created from
223

224
00:19:57,390 --> 00:20:00,510
a class can actually conform to that protocol,
224

225
00:20:00,540 --> 00:20:08,550
so they might use this data type "AnyObject" in that way to limit things to work with classes. And then
225

226
00:20:08,670 --> 00:20:14,700
even more specialized are these "NSObjects" which are the objects that are created from the foundation
226

227
00:20:14,700 --> 00:20:15,570
classes.
227

228
00:20:15,630 --> 00:20:22,860
So remember how we often import foundation. Well, inside that foundation module, we get access to NSNumber,
228

229
00:20:22,920 --> 00:20:29,730
and as dates, file manager, and a whole bunch of other objects that Apple has created.
229

230
00:20:29,730 --> 00:20:36,910
So if we were to head back to our code and where we've got this array of objects, right?
230

231
00:20:36,990 --> 00:20:43,980
If I was to create, say, just like an integer, right? Let's call it num and let's make it equal to 12,
231

232
00:20:44,330 --> 00:20:50,460
and I tried to add this number to our array of neighbours, then you'll see that it's not really going
232

233
00:20:50,460 --> 00:20:56,660
to allow me to do that because there's absolutely no commonality between all of these guys.
233

234
00:20:56,700 --> 00:21:03,210
The only way that I can do this is actually by making my array of type Any.
234

235
00:21:03,300 --> 00:21:10,920
So if I had an array of type Any, then this is gonna be fine. "Any" allows us to mix any type, literally.
235

236
00:21:11,640 --> 00:21:19,020
In this example, we're mixing the human type, the fish type, and an integer type because Angela and Nemo
236

237
00:21:19,230 --> 00:21:25,910
are instances created from classes, whereas the integer is created from a structure.
237

238
00:21:26,010 --> 00:21:35,020
So this keyword "any" allows us to mix classes and structures or any other data type. So what happens when
238

239
00:21:35,020 --> 00:21:38,110
I change Any to AnyObject?
239

240
00:21:38,110 --> 00:21:39,620
Now, we get an error.
240

241
00:21:39,640 --> 00:21:40,060
Why.
241

242
00:21:40,510 --> 00:21:46,060
Well, the reason is that AnyObject restricts the types to those that come from classes.
242

243
00:21:46,060 --> 00:21:51,580
So in other words, structures are no longer allowed to play and they're no longer allowed to be part
243

244
00:21:51,640 --> 00:21:56,140
of our collection. And integers, strings, and doubles,
244

245
00:21:56,140 --> 00:22:02,740
these are all structures which is why we get this error. And I can show this to you in another way.
245

246
00:22:03,320 --> 00:22:10,210
Let's say there our fish Class was instead a structure and structures, of course, don't have inheritance,
246

247
00:22:10,220 --> 00:22:12,980
so I have to delete all of this. But there we go,
247

248
00:22:12,980 --> 00:22:18,650
we've got our Nemo which is created from fish. But right now, if I try to run this, this also gives me an
248

249
00:22:18,650 --> 00:22:19,140
error.
249

250
00:22:19,160 --> 00:22:27,470
It says that Nemo which has type 'Fish' can't be converted to AnyObject because AnyObject requires that
250

251
00:22:27,470 --> 00:22:35,900
the object be created from a class, like the Human class, where Angela and Jack are created from. But Nemo
251

252
00:22:35,900 --> 00:22:40,610
is created from the Fish struct which is not an AnyObject.
252

253
00:22:40,610 --> 00:22:47,270
Now, let's say we changed this to NSObject which means that we're even more limited as to what can
253

254
00:22:47,270 --> 00:22:49,000
go into our array.
254

255
00:22:49,220 --> 00:22:56,060
Neither Angela, Jack, or Nemo actually fit these criteria because we need to use one of the classes and
255

256
00:22:56,060 --> 00:22:58,630
foundation that's created by Apple.
256

257
00:22:58,640 --> 00:23:05,360
So, for example, let's say I decide to create a number that's created from the NSNumber class and I set
257

258
00:23:05,360 --> 00:23:06,730
it to equal to 12,
258

259
00:23:07,130 --> 00:23:17,360
or let's say I create a word that's created from the NSString class and I set it to ABC, well, these items
259

260
00:23:17,420 --> 00:23:18,430
can go in here,
260

261
00:23:18,440 --> 00:23:18,680
right?
261

262
00:23:18,710 --> 00:23:25,250
I could put "num" and I could put "word" and if I take out "Nemo," then you'll see that this is perfectly
262

263
00:23:25,250 --> 00:23:25,700
valid.
263

264
00:23:25,700 --> 00:23:33,900
These are both NSObjects that can match this particular requirement. But as soon as I try to add
264

265
00:23:33,900 --> 00:23:42,270
in a struct, for example, on Nemo, or if I try to add in a Human, which is created from our class, none of
265

266
00:23:42,270 --> 00:23:43,680
these will be allowed.
266

267
00:23:44,160 --> 00:23:51,570
So, essentially, depending on how strict your criteria is, you can actually go through these very broad
267

268
00:23:52,680 --> 00:23:53,430
types:
268

269
00:23:53,430 --> 00:24:01,320
Any, AnyObject, and NSObject, and allows you to create collections of items that are more broad than
269

270
00:24:01,320 --> 00:24:04,870
just the classes that we've created ourselves.
270

271
00:24:04,920 --> 00:24:09,950
So, now that you've learned all about typecasting, I have a small reading assignment for you.
271

272
00:24:10,110 --> 00:24:15,870
So if you have some time, I recommend heading over to this link which you'll be able to find in the course
272

273
00:24:15,870 --> 00:24:16,760
resources,
273

274
00:24:16,950 --> 00:24:23,280
and just having a read of this page on typecasting to get a little bit more background information and
274

275
00:24:23,580 --> 00:24:28,780
learn a little bit more about this topic. So consider it an optional assignment.
275

276
00:24:28,800 --> 00:24:36,450
All right, in the next lesson, we're going to be using Firebase to save and retrieve data from the Firebase
276

277
00:24:36,510 --> 00:24:37,770
Cloud Firestorm.
277

278
00:24:37,950 --> 00:24:45,540
And when we retrieve the data back, we'll have to use some form of casting in order to convert it into
278

279
00:24:45,540 --> 00:24:48,300
a data type that has the capabilities that we need.
