1
00:00:00,506 --> 00:00:07,546
[ Silence ]

2
00:00:08,046 --> 00:00:08,346
>> All right.

3
00:00:08,756 --> 00:00:09,526
All right, we're back.

4
00:00:09,706 --> 00:00:11,126
This is Computer Science S76.

5
00:00:11,426 --> 00:00:13,686
So there weren't too
many questions from you,

6
00:00:13,686 --> 00:00:15,786
so that means it's my turn
to start asking questions.

7
00:00:15,786 --> 00:00:18,926
Last week we started
talking about MVC, which,

8
00:00:18,966 --> 00:00:20,726
how about we'll start with
the softball, stands for what?

9
00:00:20,726 --> 00:00:22,016
>> Model-view-controller.

10
00:00:22,076 --> 00:00:23,196
>> Model-view-controller.

11
00:00:23,196 --> 00:00:27,676
Okay. So what is the
Controller in that acronym?

12
00:00:27,676 --> 00:00:27,946
>> [Inaudible response].

13
00:00:27,946 --> 00:00:28,216
.

14
00:00:28,216 --> 00:00:30,556
>> Okay. Brains of the
application, so it's the code

15
00:00:30,556 --> 00:00:32,576
that you write, the
so-called business logic

16
00:00:32,576 --> 00:00:34,946
that governs the control
of your application.

17
00:00:34,946 --> 00:00:37,966
It's the entry point to really
the logic that you write.

18
00:00:37,966 --> 00:00:38,506
All right?

19
00:00:38,506 --> 00:00:40,586
How about the V, view?

20
00:00:40,586 --> 00:00:43,886
>> Interactions with the user.

21
00:00:44,006 --> 00:00:45,526
>> Yeah, so interactions
with the user.

22
00:00:45,526 --> 00:00:47,756
So view typically deals
with presentation,

23
00:00:47,756 --> 00:00:49,946
both the anesthetics thereof,

24
00:00:49,946 --> 00:00:52,226
so how you're displaying
information to the user,

25
00:00:52,386 --> 00:00:54,896
and then it typically has some
UI mechanisms, like buttons

26
00:00:54,896 --> 00:00:58,366
and text fields and whatnot,
that somehow send messages back

27
00:00:58,366 --> 00:00:59,926
to which of the letters?

28
00:01:00,536 --> 00:01:01,666
>> The Controller.

29
00:01:01,666 --> 00:01:02,366
>> The Controller.

30
00:01:02,366 --> 00:01:05,876
So you have this bidirectional
arrow essentially between your C

31
00:01:05,876 --> 00:01:07,506
and your V, so the
two are talking,

32
00:01:07,506 --> 00:01:11,996
but you do not have an arrow
between, say, V and M directly.

33
00:01:11,996 --> 00:01:14,886
Rather the model is where you
typically represent your data,

34
00:01:14,886 --> 00:01:17,236
and we'll do a simple example
tonight of what you might want

35
00:01:17,236 --> 00:01:20,286
to model with its own class
that we write ourselves.

36
00:01:20,676 --> 00:01:23,146
But typically, all of those
communications should be

37
00:01:23,206 --> 00:01:25,846
marshaled through the
so-called Controller,

38
00:01:25,846 --> 00:01:27,946
so that's where really
the intellectual property

39
00:01:27,946 --> 00:01:30,376
of your app tends to be, in
the aesthetics or in the View.

40
00:01:30,376 --> 00:01:33,626
And then the model is where
we'll do our data typing

41
00:01:33,626 --> 00:01:35,606
and our data representation
encapsulation.

42
00:01:35,606 --> 00:01:36,776
We'll do a bit of
that in just a bit.

43
00:01:36,776 --> 00:01:37,566
All right.

44
00:01:37,596 --> 00:01:41,056
So that was MVC, and in what --

45
00:01:41,056 --> 00:01:43,256
what form does this take
in the world of iOS?

46
00:01:43,476 --> 00:01:47,616
Well, in iOS, we have a few
classes with the UI kit,

47
00:01:47,666 --> 00:01:51,376
so this is the API
that provides access

48
00:01:51,376 --> 00:01:53,256
to UI related things in iOS.

49
00:01:53,256 --> 00:01:56,236
And UIApplication was a class
that we barely spent any time

50
00:01:56,236 --> 00:01:59,856
with because we just make
reference to it in Main,

51
00:01:59,996 --> 00:02:02,566
essentially, where we
have a new UIApplication,

52
00:02:02,566 --> 00:02:03,236
and that's the class

53
00:02:03,236 --> 00:02:05,076
that embodies your
actual application.

54
00:02:05,076 --> 00:02:07,396
But beyond that, we don't really
need to care too much about it,

55
00:02:07,766 --> 00:02:10,156
but UIApplicationDelegate
is a class

56
00:02:10,556 --> 00:02:13,186
that we spent a little
more time talking about,

57
00:02:13,946 --> 00:02:21,046
and what is that class's role
when you create an iOS app?

58
00:02:21,376 --> 00:02:24,006
Use it in a sentence
that makes it sound

59
00:02:24,006 --> 00:02:26,206
like technically you're
comfy with what its role is.

60
00:02:27,096 --> 00:02:28,226
>> Isn't that where
you put your code?

61
00:02:28,596 --> 00:02:29,566
>> So it's where
you put your code,

62
00:02:29,566 --> 00:02:30,806
or at least the first
entry point.

63
00:02:30,806 --> 00:02:32,816
You wouldn't put
your code in Main.M,

64
00:02:32,816 --> 00:02:35,606
but rather you might first put
it in UIApplicationDelegate,

65
00:02:35,786 --> 00:02:38,526
and conceptually it's to this
class, or an object thereof,

66
00:02:38,816 --> 00:02:41,476
that controlled your application
is delegated or passed.

67
00:02:41,726 --> 00:02:43,336
So he's now the guy in charge.

68
00:02:43,596 --> 00:02:46,166
But as soon as we started doing
more interesting applications

69
00:02:46,166 --> 00:02:47,816
than just rectangles
on the screen

70
00:02:47,816 --> 00:02:49,536
and started getting
interactions from users,

71
00:02:49,786 --> 00:02:53,166
we further delegated control
from the UIApplicationDelegate

72
00:02:53,406 --> 00:02:55,286
to an object of what type?

73
00:02:57,056 --> 00:02:57,636
>> UIViewController.

74
00:02:57,636 --> 00:02:58,316
>> UIViewController.

75
00:02:58,316 --> 00:02:59,936
And we don't have to, per se.

76
00:02:59,936 --> 00:03:02,216
Games don't necessarily
use that same class,

77
00:03:02,216 --> 00:03:04,446
and custom applications don't
necessarily use that class,

78
00:03:04,446 --> 00:03:06,836
but the UIViewController's
nice because it comes

79
00:03:06,836 --> 00:03:08,796
with a whole bunch of
built in functionality

80
00:03:09,046 --> 00:03:11,776
for handling various common
paradigms, like buttons

81
00:03:11,776 --> 00:03:14,106
and sliding and tabular
views and so forth.

82
00:03:14,106 --> 00:03:16,286
So it's a common starting
point, certainly for the types

83
00:03:16,286 --> 00:03:18,486
of menued applications
we've looked at thus far.

84
00:03:18,756 --> 00:03:22,416
And the UIViewController in
turn makes you solve bunches

85
00:03:22,416 --> 00:03:25,966
of UIView objects, but typically
not just generic UIView objects,

86
00:03:25,966 --> 00:03:28,366
but typically not just
generic UIView objects.

87
00:03:28,366 --> 00:03:34,486
What are some subclasses that
we've used and talked about?

88
00:03:34,486 --> 00:03:40,476
Two of which I've enumerated
tonight, albeit off camera.

89
00:03:40,566 --> 00:03:43,646
Starts with UI, ends with utton.

90
00:03:44,366 --> 00:03:45,546
>> UI Buttons.

91
00:03:45,646 --> 00:03:46,906
>> Okay, so UI Buttons
[laughter].

92
00:03:46,906 --> 00:03:48,096
So this was just a subclass,

93
00:03:48,456 --> 00:03:50,306
and thus far we've
essentially used these things

94
00:03:50,306 --> 00:03:51,746
by dragging and dropping.

95
00:03:51,746 --> 00:03:53,976
But we did have a
quick glimpse last time

96
00:03:54,296 --> 00:03:59,176
at no Nib.Xcode project,
which was a reimplementation

97
00:03:59,176 --> 00:04:01,756
of that super simple app
that gave me a text field

98
00:04:01,756 --> 00:04:04,186
for my name, gave
me a button with --

99
00:04:04,186 --> 00:04:07,796
to click on to actually then
trigger a UIAlertView saying

100
00:04:07,796 --> 00:04:09,766
hello David, or hello
such and such.

101
00:04:09,976 --> 00:04:11,636
And we dragged and
dropped that UI Button,

102
00:04:11,636 --> 00:04:15,216
but UI Button is just a
specific incarnation of UIView,

103
00:04:15,396 --> 00:04:17,796
and if you think back
to Xcode and think back

104
00:04:17,796 --> 00:04:20,086
to Interface Builder, that
drag and drop interface,

105
00:04:20,086 --> 00:04:21,916
what we're essentially
doing by dragging

106
00:04:21,916 --> 00:04:24,766
and dropping is dropping
these little objects on top

107
00:04:24,766 --> 00:04:27,336
of a canvas, and they can
overlay, overlay, overlay.

108
00:04:27,336 --> 00:04:28,626
And we'll do a little
more of that

109
00:04:28,626 --> 00:04:31,076
in a different sense tonight
by actually responding

110
00:04:31,076 --> 00:04:34,396
to arbitrary key presses, or
pinches, for zooms and the like,

111
00:04:34,396 --> 00:04:36,476
so we can actually listen
to the entire U View --

112
00:04:36,636 --> 00:04:38,256
UIView, as we will see.

113
00:04:38,486 --> 00:04:41,316
UIWindow finally was a
special case of a UIView.

114
00:04:41,316 --> 00:04:43,276
It has some additional
stuff baked into it

115
00:04:43,466 --> 00:04:45,856
that essentially describes
the full rectangular area

116
00:04:46,166 --> 00:04:48,106
of the iOS device in question.

117
00:04:48,106 --> 00:04:50,486
But today we'll spend a bit
more time in UIViewController

118
00:04:50,656 --> 00:04:54,556
and UIView, but we'll see
those other classes again along

119
00:04:54,556 --> 00:04:54,946
the way.

120
00:04:55,086 --> 00:04:56,786
So let's see.

121
00:04:56,786 --> 00:04:59,336
So last time, we looked at a
whole bunch of these templates.

122
00:04:59,336 --> 00:05:01,106
None of these templates
are strictly necessary.

123
00:05:01,106 --> 00:05:03,516
You could just start with
nothing in your project

124
00:05:03,516 --> 00:05:04,936
and start writing files by hand.

125
00:05:05,226 --> 00:05:07,296
The problem is you just end
up reinventing the wheel.

126
00:05:07,296 --> 00:05:10,126
There's a lot of configuration
details that we saw in the form

127
00:05:10,126 --> 00:05:11,946
of Property Lists,
those key value pairs

128
00:05:11,946 --> 00:05:13,646
that would just be a
pain to do manually.

129
00:05:13,646 --> 00:05:15,626
So Xcode helps jumpstart
things either

130
00:05:15,626 --> 00:05:16,706
with an empty application,

131
00:05:16,706 --> 00:05:18,756
which has the bare
minimum of configuration.

132
00:05:18,946 --> 00:05:21,926
And then we looked at Single
View last time and then a lot

133
00:05:21,926 --> 00:05:24,266
of you looked at Utility
View and you're knee-deep

134
00:05:24,266 --> 00:05:26,886
in a Utility View
application for Evil Hangman.

135
00:05:27,246 --> 00:05:30,586
So if we proceed a little
further today, let's take a look

136
00:05:30,766 --> 00:05:33,546
at these two last ones,
not because they in

137
00:05:33,546 --> 00:05:35,696
and of themselves are
applications you'll need to use

138
00:05:35,696 --> 00:05:37,836
for the project, but rather
because they're illustrative

139
00:05:38,006 --> 00:05:40,206
of somewhat more
complex applications

140
00:05:40,206 --> 00:05:43,656
that you might implement that
nonetheless assume familiarity

141
00:05:43,906 --> 00:05:46,766
with the overall
structure we had earlier.

142
00:05:46,766 --> 00:05:47,476
So let's do this.

143
00:05:47,476 --> 00:05:49,556
First, let's start
somewhere simple.

144
00:05:49,556 --> 00:05:52,346
I'm going to go into Xcode,
and I'm going to first start,

145
00:05:52,346 --> 00:05:55,296
not with an empty application,
which was super uninteresting

146
00:05:55,706 --> 00:05:57,826
by the end of last week,
but Single View Application,

147
00:05:57,826 --> 00:05:59,366
and then we'll quickly
build on from there.

148
00:05:59,366 --> 00:06:02,496
I'm going to go ahead and
call this Single View.

149
00:06:02,496 --> 00:06:04,526
I'm going to just
store it on my desktop.

150
00:06:04,526 --> 00:06:07,366
I'm going to uncheck
Storyboards here, click next,

151
00:06:07,366 --> 00:06:09,376
and then I'm going to
go ahead and click okay.

152
00:06:09,376 --> 00:06:13,076
And now we have the
following boilerplate files.

153
00:06:13,296 --> 00:06:16,506
So suppose by contrast I didn't
just create this right in front

154
00:06:16,506 --> 00:06:18,646
of you, but you were handed
this project from someone else,

155
00:06:18,646 --> 00:06:19,586
and you want to wrap your mind

156
00:06:19,586 --> 00:06:21,056
as to what's going
on inside of it.

157
00:06:21,176 --> 00:06:22,386
Where's the best place to start

158
00:06:22,386 --> 00:06:24,356
to understand what
you've been handed?

159
00:06:25,336 --> 00:06:26,586
>> A .H file.

160
00:06:26,806 --> 00:06:27,796
ViewController.H.

161
00:06:28,046 --> 00:06:31,176
>> Okay. ViewController.H. I
would propose that's maybe a

162
00:06:31,176 --> 00:06:33,626
little too deep at first glance.

163
00:06:33,626 --> 00:06:35,996
Why don't we start where the
beginning of the story begins?

164
00:06:36,416 --> 00:06:36,816
>> AppDelegate [inaudible]?

165
00:06:37,316 --> 00:06:40,056
>> Yeah, AppDelegate, and really
if we want to be super anal

166
00:06:40,056 --> 00:06:42,276
about this, technically
it's Main.M

167
00:06:42,276 --> 00:06:43,706
that kick starts
the whole process,

168
00:06:43,826 --> 00:06:45,906
and a quick glance
should at least reassure

169
00:06:45,906 --> 00:06:48,066
that there's nothing special,
nothing different there.

170
00:06:48,176 --> 00:06:50,576
But indeed it's in this
file that we see mention,

171
00:06:50,576 --> 00:06:53,506
not only of UIApplication,
but also AppDelegate,

172
00:06:53,506 --> 00:06:55,116
to whom we're going
to delegate control.

173
00:06:55,116 --> 00:06:57,266
So we've confirmed that there's
nothing distinct in there.

174
00:06:57,586 --> 00:06:59,946
So now I would propose
among the AppDelegate files,

175
00:07:00,326 --> 00:07:02,316
starting with the .H is
probably the better place,

176
00:07:02,316 --> 00:07:04,316
because it gives you, in
theory, an overview of what's

177
00:07:04,316 --> 00:07:07,686
about to go on, and it also
gives you a sense of what needs

178
00:07:07,686 --> 00:07:09,566
to be implemented
in the .M file.

179
00:07:10,066 --> 00:07:11,056
So what's going on here?

180
00:07:11,056 --> 00:07:11,916
Well, a quick recap.

181
00:07:11,916 --> 00:07:13,256
The import line does
what for us?

182
00:07:13,956 --> 00:07:20,106
>> It imports the
user interface kit.

183
00:07:20,256 --> 00:07:20,696
>> Okay, good.

184
00:07:20,696 --> 00:07:22,456
It imports the user
interface kit.

185
00:07:22,726 --> 00:07:23,616
And what does that mean?

186
00:07:23,616 --> 00:07:25,836
So in that .H file,
there's a whole bunch

187
00:07:25,836 --> 00:07:28,196
of class declarations,
perhaps, maybe a bunch

188
00:07:28,196 --> 00:07:29,596
of constants that are defined.

189
00:07:29,706 --> 00:07:31,986
A whole bunch of things that we
want to take for granted exist,

190
00:07:31,986 --> 00:07:34,596
and this is our way of
teaching Xcode that we want

191
00:07:34,596 --> 00:07:35,966
to use the code that
someone else wrote.

192
00:07:35,966 --> 00:07:39,176
All right, on the next line we
have at Class ViewController.

193
00:07:39,696 --> 00:07:41,876
Actually, that's
a little strange.

194
00:07:42,116 --> 00:07:46,476
There's a semicolon, yet no
implementation of the class.

195
00:07:47,786 --> 00:07:50,906
What is it with this line
here, at Class ViewController,

196
00:07:50,906 --> 00:07:52,906
which we've not really
spent time on?

197
00:07:53,126 --> 00:07:53,486
Yeah.

198
00:07:54,146 --> 00:08:04,466
>> So the at Class actually
tells it that it's [inaudible],

199
00:08:04,466 --> 00:08:06,716
but doesn't actually import it.

200
00:08:06,716 --> 00:08:07,186
>> Exactly.

201
00:08:07,426 --> 00:08:10,316
>> Unless you were going
to use one of its methods,

202
00:08:10,316 --> 00:08:13,546
that should suffice to
tell it that it exists.

203
00:08:13,546 --> 00:08:14,106
>> Exactly.

204
00:08:14,106 --> 00:08:16,536
So we didn't spend
time on this last time,

205
00:08:16,536 --> 00:08:20,196
but this is what's called
a forward declaration.

206
00:08:20,196 --> 00:08:24,806
It's a little hint to the
compiler saying there is going

207
00:08:24,806 --> 00:08:27,686
to be a class called
ViewController.

208
00:08:27,686 --> 00:08:30,686
I'm not going to tell you
anything more about it,

209
00:08:30,686 --> 00:08:33,096
but if you see mentions of
ViewController elsewhere

210
00:08:33,276 --> 00:08:34,836
in this file, don't complain.

211
00:08:34,836 --> 00:08:37,386
Don't give me any red
warning saying that's no --

212
00:08:37,386 --> 00:08:38,476
that not allowed.

213
00:08:38,476 --> 00:08:41,606
This is just teaching the
compiler what's actually going

214
00:08:41,786 --> 00:08:43,686
to come, and indeed
where are we using that?

215
00:08:43,686 --> 00:08:46,236
Well, a few lines later we're
declaring a property whose

216
00:08:46,236 --> 00:08:48,666
purpose in life is
to store a pointer

217
00:08:48,666 --> 00:08:51,056
to a ViewController object.

218
00:08:51,056 --> 00:08:53,216
So this is, long story short,

219
00:08:53,216 --> 00:08:56,566
in way of avoiding potential
circular references whereby one

220
00:08:56,566 --> 00:09:00,536
file might import another,
might import another.

221
00:09:00,536 --> 00:09:06,836
A common paradigm is if you
only need to make mention

222
00:09:07,116 --> 00:09:09,196
of the class in this
way in your .H file,

223
00:09:09,676 --> 00:09:13,276
just to use a forward
declaration and not

224
00:09:13,276 --> 00:09:15,926
to import the whole
ViewController.H file,

225
00:09:15,926 --> 00:09:16,866
for instance.

226
00:09:16,866 --> 00:09:21,036
Okay, what's this third,
more interesting line saying?

227
00:09:21,956 --> 00:09:25,696
At Interface AppDelegate
colon UIResponder angled

228
00:09:25,696 --> 00:09:27,596
brackets UIApplicationDelegate.

229
00:09:27,596 --> 00:09:28,656
Let's start easily.

230
00:09:28,656 --> 00:09:29,416
This just declares what?

231
00:09:29,416 --> 00:09:31,426
What's this mention in
black of AppDelegate?

232
00:09:31,426 --> 00:09:32,096
>> Name of the class.

233
00:09:32,096 --> 00:09:33,346
>> Name of the class, all right?

234
00:09:33,346 --> 00:09:35,006
The colon UIResponder means?

235
00:09:35,006 --> 00:09:35,073
>> [Inaudible audience
response].

236
00:09:35,073 --> 00:09:36,706
>> It's the -- UIResponder
is the parent of the class,

237
00:09:36,706 --> 00:09:38,906
so AppDelegate is
going to descend

238
00:09:38,906 --> 00:09:41,076
from UIResponder,
and someone else?

239
00:09:41,106 --> 00:09:42,336
The UIApplicationDelegate
in angled brackets?

240
00:09:42,366 --> 00:09:42,786
>> It's a protocol.

241
00:09:42,816 --> 00:09:43,986
>> It's a protocol, so we're
saying that we're going

242
00:09:44,016 --> 00:09:45,366
to implement the
UIApplicationDelegate protocol,

243
00:09:45,396 --> 00:09:46,566
and this makes sense
because the class, after all,

244
00:09:46,596 --> 00:09:47,136
is called AppDelegate.

245
00:09:47,166 --> 00:09:47,346
All right?

246
00:09:47,376 --> 00:09:48,006
What are the two properties?

247
00:09:48,036 --> 00:09:48,786
Well, we saw one ViewController.

248
00:09:48,816 --> 00:09:50,376
We have another pointer to the
UIWindow that'll give us access

249
00:09:50,406 --> 00:09:51,966
to the full rectangular portion
of the screen, and that's it.

250
00:09:51,996 --> 00:09:52,176
All right?

251
00:09:52,206 --> 00:09:53,076
So now let's dive
into the M file.

252
00:09:53,106 --> 00:09:53,736
All of that is boilerplate.

253
00:09:53,766 --> 00:09:55,116
None of that is different
from what we saw last week.

254
00:09:55,146 --> 00:09:56,556
This file's always a little
overwhelming at first glance

255
00:09:56,586 --> 00:09:57,426
when you have all
of these comments,

256
00:09:57,456 --> 00:09:58,716
but that just means they're
not really doing anything.

257
00:09:58,746 --> 00:10:00,246
So let's ignore anything that's
not actually doing anything

258
00:10:00,276 --> 00:10:01,896
functional, and focus only on
this first method up top named,

259
00:10:01,926 --> 00:10:02,976
what's the name of this
method that remains?

260
00:10:05,916 --> 00:10:06,236
>> AppDelegate?

261
00:10:06,236 --> 00:10:10,436
>> Not AppDelegate, so that's
the -- that's the class name.

262
00:10:10,526 --> 00:10:11,646
The name of the method is?

263
00:10:11,986 --> 00:10:13,626
>>
didFinishLaunchingWithOptions.

264
00:10:13,676 --> 00:10:16,276
>> Yeah, application
didFinishLaunchingWithOptions,

265
00:10:16,276 --> 00:10:19,576
so longly named method
there, but what's this doing?

266
00:10:19,576 --> 00:10:21,396
So first, it's allocating
a window.

267
00:10:21,636 --> 00:10:23,906
It's initializing it with a
frame that's just referring

268
00:10:23,906 --> 00:10:26,326
to the rectangle, if
we keep describing it.

269
00:10:26,326 --> 00:10:28,996
ViewController gets
-- so here is

270
00:10:28,996 --> 00:10:32,406
where we're effectively
configuring our AppDelegate

271
00:10:32,536 --> 00:10:34,076
with another guy
to whom we're going

272
00:10:34,076 --> 00:10:36,106
to delegate control,
the ViewController.

273
00:10:36,336 --> 00:10:39,706
Self.ViewController is
a property that's built

274
00:10:39,706 --> 00:10:41,836
into the AppDelegate class,
so if you actually look

275
00:10:41,836 --> 00:10:45,356
up the documentation for
a UIApplicationDelegate,

276
00:10:45,356 --> 00:10:47,756
you'll see that it comes
with that property,

277
00:10:47,756 --> 00:10:49,176
so we're setting it in that way.

278
00:10:49,456 --> 00:10:51,016
Finally we're setting
the -- sorry.

279
00:10:51,426 --> 00:10:54,006
This is our property that
we declared in the .H file,

280
00:10:54,066 --> 00:10:56,726
but it comes with a
RootViewController property

281
00:10:56,726 --> 00:10:59,386
in the window, that's in
the UIWindow documentation.

282
00:10:59,666 --> 00:11:02,296
And then that second to last
line, Make Key Invisible,

283
00:11:02,556 --> 00:11:04,466
just gives control

284
00:11:04,566 --> 00:11:07,286
to the ViewIController
to the foreground.

285
00:11:07,996 --> 00:11:09,396
What else does this
application do?

286
00:11:09,396 --> 00:11:13,386
Anything? So that's it.

287
00:11:13,386 --> 00:11:15,146
All we have is the Nib
where we could start

288
00:11:15,146 --> 00:11:17,026
to put our user interface,
but beyond that,

289
00:11:17,276 --> 00:11:20,236
this application does
terribly, terribly little.

290
00:11:21,026 --> 00:11:24,856
So let's try to see --
first, any questions?

291
00:11:24,856 --> 00:11:28,706
So let's take a more
complex tour and see

292
00:11:28,706 --> 00:11:33,216
if we can't now understand
a new application entirely,

293
00:11:33,436 --> 00:11:39,496
but this time while thinking
about it in the context

294
00:11:39,496 --> 00:11:41,096
of applications we've
seen thus far.

295
00:11:41,096 --> 00:11:43,746
So among tonight's source
code is a folder called

296
00:11:43,746 --> 00:11:44,756
Master Detail.

297
00:11:44,986 --> 00:11:48,246
This is essentially a simplified
version of the standard template

298
00:11:48,246 --> 00:11:50,796
that comes with Xcode, so
all I did was tidy things up

299
00:11:50,796 --> 00:11:52,506
and remove things that
didn't need to be there.

300
00:11:52,686 --> 00:11:55,406
As usual, let's go
into our Main.M file.

301
00:11:55,406 --> 00:11:57,906
Let me close some
superfluous windows over there.

302
00:11:58,126 --> 00:11:59,216
Nothing new happening here,

303
00:11:59,266 --> 00:12:00,996
so that's the same
file we saw earlier.

304
00:12:01,156 --> 00:12:02,326
What file should
we probably dive

305
00:12:02,326 --> 00:12:04,406
into next following
the same rule of thumb?

306
00:12:04,736 --> 00:12:05,036
>> AppDelegate.

307
00:12:05,416 --> 00:12:06,596
>> Okay, so AppDelegate.

308
00:12:06,596 --> 00:12:09,866
Start with the .H. That
looks perfectly the same,

309
00:12:09,866 --> 00:12:10,816
so nothing new there.

310
00:12:11,136 --> 00:12:16,836
AppDelegate.M, so here we have
what seems to be the same code

311
00:12:16,836 --> 00:12:21,476
as before, except for
-- any differences?

312
00:12:21,626 --> 00:12:22,156
>> MasterViewController.

313
00:12:22,856 --> 00:12:25,496
>> So we're instantiating
a MasterViewController.

314
00:12:25,496 --> 00:12:26,336
So that's interesting.

315
00:12:26,336 --> 00:12:29,276
It's not just a ViewController,
it's a MasterViewController,

316
00:12:29,496 --> 00:12:34,246
and we're making it the
RootViewController, so to speak.

317
00:12:34,246 --> 00:12:35,436
So most of this code
is the same,

318
00:12:35,436 --> 00:12:37,136
but I'm instantiating
a different class name,

319
00:12:37,396 --> 00:12:39,926
but that's because someone at
Apple decided for this template

320
00:12:39,926 --> 00:12:42,796
that we're not going to have
one ViewController implemented

321
00:12:42,796 --> 00:12:45,286
for you in .H and .M. We're
going to have what appears

322
00:12:45,286 --> 00:12:48,276
to be two: Master ViewController
and Detail ViewController.

323
00:12:48,476 --> 00:12:49,676
So at this point
I'm a little puzzled

324
00:12:49,676 --> 00:12:51,626
as to what this thing's going
to do, so let me go ahead

325
00:12:51,626 --> 00:12:52,866
and just run the application,

326
00:12:53,076 --> 00:12:54,816
and see if we can't
then work backwards

327
00:12:54,816 --> 00:12:58,156
as to how the behavior we're
about to see is functioning.

328
00:12:58,156 --> 00:13:00,076
So let me go ahead and
foreground the simulator,

329
00:13:00,356 --> 00:13:03,206
and in just a moment, we'll
see it pop to the foreground.

330
00:13:03,866 --> 00:13:06,176
Lately the simulator has
been loading a little slowly,

331
00:13:06,176 --> 00:13:06,966
but there we have it.

332
00:13:07,686 --> 00:13:10,526
And now we have,
interesting, an application

333
00:13:10,736 --> 00:13:12,526
that has nothing going on here.

334
00:13:12,726 --> 00:13:15,486
You can just about see
the horizontal lines,

335
00:13:15,486 --> 00:13:17,726
so this is some kind of
tabular view going on,

336
00:13:17,956 --> 00:13:20,646
and this application, the
starting point, is designed just

337
00:13:20,646 --> 00:13:22,006
to do something stupid, just

338
00:13:22,006 --> 00:13:25,336
to insert a new row every
time you click the plus.

339
00:13:25,516 --> 00:13:29,306
And it's choosing the timestamp
in UTC, so universal --

340
00:13:29,916 --> 00:13:33,566
universal time, and
adding a row accordingly.

341
00:13:33,636 --> 00:13:35,856
So if I do that ad nauseum,
we'll just get lots of lots

342
00:13:35,856 --> 00:13:38,576
of rows, but you might
recall this paradigm in iOS.

343
00:13:38,576 --> 00:13:40,496
If I click edit, I
get this familiar UI.

344
00:13:40,496 --> 00:13:42,666
I can go ahead and
delete, say, that one,

345
00:13:42,666 --> 00:13:45,646
by clicking that circle, then
clicking the delete button.

346
00:13:45,916 --> 00:13:49,516
Then I say done, and so there
we have that functionality.

347
00:13:49,516 --> 00:13:52,806
And if I click a row itself,
Detail View Content Goes Here.

348
00:13:53,076 --> 00:13:54,986
So what's just happened
apparently is

349
00:13:54,986 --> 00:13:56,386
that we've made some
kind of transition

350
00:13:56,656 --> 00:13:58,186
from the Master ViewController

351
00:13:58,416 --> 00:14:00,546
to what they call the
Detail ViewController,

352
00:14:00,546 --> 00:14:03,486
so this is illustrative now of
how you can hand off control

353
00:14:03,486 --> 00:14:04,916
between two ViewControllers.

354
00:14:05,126 --> 00:14:06,966
Recall that you've
essentially been doing this

355
00:14:06,966 --> 00:14:09,406
in the utility application,
or you will soon be doing this

356
00:14:09,406 --> 00:14:11,926
in the utility application
for Evil Hangman,

357
00:14:12,186 --> 00:14:13,396
but you were choosing
a different type

358
00:14:13,786 --> 00:14:15,506
of transition Rather
than side to side,

359
00:14:15,506 --> 00:14:17,336
you were doing front
to back flipping.

360
00:14:17,666 --> 00:14:21,396
So this one still is a little
different in its implementation.

361
00:14:21,396 --> 00:14:24,126
Let's next go into,
from AppDelegate.M,

362
00:14:24,126 --> 00:14:27,326
let's start with Master
ViewController.H. Is there

363
00:14:27,326 --> 00:14:29,036
anything of interest in here?

364
00:14:29,266 --> 00:14:32,256
So Master ViewController
has a property that's going

365
00:14:32,256 --> 00:14:33,946
to store the address
of what kind of object?

366
00:14:33,946 --> 00:14:40,556
Looks like a Detail
ViewController..

367
00:14:40,746 --> 00:14:42,326
So if you think about
this high level,

368
00:14:42,546 --> 00:14:45,356
the RootViewController's
the Master ViewController.

369
00:14:45,616 --> 00:14:47,516
He apparently is somehow
going to have attached

370
00:14:47,736 --> 00:14:50,466
to him the address of a
Detail ViewController,

371
00:14:50,586 --> 00:14:51,926
so it seems to be
the case, indeed,

372
00:14:51,926 --> 00:14:53,796
that the Master ViewController
is in charge.

373
00:14:54,016 --> 00:14:55,736
Now we haven't done
any of that wiring yet,

374
00:14:55,736 --> 00:14:58,536
so let's go into the .M file
for Master ViewController,

375
00:14:58,816 --> 00:15:01,166
get the lay of the land,
this is a little overwhelming

376
00:15:01,166 --> 00:15:01,866
but we'll get there.

377
00:15:02,186 --> 00:15:04,716
So now let me scroll
back up to the top

378
00:15:04,936 --> 00:15:06,846
and see what's interesting here.

379
00:15:06,846 --> 00:15:10,666
So let's focus first on
one of these at a time.

380
00:15:10,666 --> 00:15:13,756
So here's a method called
In It With Nib Name.

381
00:15:14,006 --> 00:15:16,766
This has typically been
called automatically for us,

382
00:15:16,766 --> 00:15:18,626
because we've had a
bunch of starting points

383
00:15:18,806 --> 00:15:20,356
in our applications
thus far in class

384
00:15:20,796 --> 00:15:22,456
where we had those .XID files.

385
00:15:22,656 --> 00:15:26,536
Somehow they were wired up to my
code and loaded automatically,

386
00:15:26,716 --> 00:15:29,706
and we just initialized
them based on the XML file

387
00:15:29,706 --> 00:15:32,336
that is the .XID file
somewhere on my hard drive.

388
00:15:32,686 --> 00:15:35,496
But now we're explicitly
implementing in In It

389
00:15:35,496 --> 00:15:40,286
With Nib Name bundle method,
and if I hover over this thing

390
00:15:40,286 --> 00:15:41,796
and check the question mark,

391
00:15:41,966 --> 00:15:44,676
notice that there's a whole
bunch of documentation in here

392
00:15:44,946 --> 00:15:46,936
and this method appears to come

393
00:15:46,936 --> 00:15:52,846
from an ancestor class
known as UIViewController.

394
00:15:53,246 --> 00:15:54,926
So if we really look
underneath the hood,

395
00:15:54,926 --> 00:15:57,766
Master ViewController
descends from a new class

396
00:15:58,076 --> 00:16:01,296
that gives us the tabular
View, UITableViewController,

397
00:16:01,446 --> 00:16:03,526
which in turn descends
from the thing we've seen

398
00:16:03,526 --> 00:16:05,946
in applications thus
far, UIViewController.

399
00:16:06,186 --> 00:16:07,976
So long story short,
if I actually start

400
00:16:07,976 --> 00:16:11,336
to read this documentation,
this will explain how the In It

401
00:16:11,336 --> 00:16:13,466
With Nib Name bundle
method works,

402
00:16:13,586 --> 00:16:15,876
and it is the guy that's
responsible for loading

403
00:16:15,876 --> 00:16:19,356
from the hard drive that .XID
file, and somehow making all

404
00:16:19,356 --> 00:16:21,826
of the connections we
discussed last weekend in lab.

405
00:16:22,226 --> 00:16:24,516
So it's doing one
additional thing though.

406
00:16:24,926 --> 00:16:28,686
It's calling first the
superclasses implementation

407
00:16:28,686 --> 00:16:31,976
of that same method, In
It With Nib Name bundle.

408
00:16:33,096 --> 00:16:34,856
So that's been called
automatically for us,

409
00:16:34,856 --> 00:16:37,186
because we have not explicitly
implemented this method thus

410
00:16:37,186 --> 00:16:40,396
far, but it's also doing what,
in high-level terms apparently?

411
00:16:41,006 --> 00:16:44,526
What does it appear to be doing?

412
00:16:45,076 --> 00:16:48,536
You seem to have
a guess in mind.

413
00:16:48,996 --> 00:16:50,446
Oh yes, yeah.

414
00:16:50,666 --> 00:16:54,056
>> [Inaudible] initializes
the [inaudible] class.

415
00:16:54,236 --> 00:16:56,326
>> Initializes the -- oh,
the first line does, yes.

416
00:16:56,366 --> 00:16:57,716
Sorry. Let me change
my highlighting.

417
00:16:58,006 --> 00:17:00,476
So it's not commented,
but was it --

418
00:17:00,476 --> 00:17:02,036
what do these three
lines seem to be doing?

419
00:17:02,146 --> 00:17:06,266
>> Setting the title.

420
00:17:06,466 --> 00:17:10,306
>> Yeah, setting the title
of self, so self.title.

421
00:17:10,306 --> 00:17:10,966
What is self?

422
00:17:10,966 --> 00:17:13,226
What type of object is
self at this point in time?

423
00:17:13,226 --> 00:17:14,076
>> Master ViewController.

424
00:17:14,506 --> 00:17:15,706
>> So it's a Master
ViewController,

425
00:17:15,706 --> 00:17:18,006
which in turn is a
UITableViewController,

426
00:17:18,006 --> 00:17:19,756
which in turn is a
UIViewController,

427
00:17:19,916 --> 00:17:21,766
so if we really started
poking around the docs,

428
00:17:21,766 --> 00:17:22,656
we would probably see

429
00:17:22,656 --> 00:17:24,646
that UIViewController's
have a property called?

430
00:17:24,646 --> 00:17:24,816
>> Title.

431
00:17:26,046 --> 00:17:28,376
>> Title. And indeed, that's
where this is coming from,

432
00:17:28,376 --> 00:17:29,826
our UITableViewControllers.

433
00:17:29,826 --> 00:17:32,376
And if we go back to the
application that was running,

434
00:17:32,606 --> 00:17:34,756
notice when we're here,
it's the title master,

435
00:17:35,016 --> 00:17:36,096
that's where they came from.

436
00:17:36,096 --> 00:17:38,256
So we could have typed this
in manually into the Nib,

437
00:17:38,256 --> 00:17:40,256
but because we created
the ViewController N code,

438
00:17:40,566 --> 00:17:42,226
we don't actually
have to do that there.

439
00:17:42,466 --> 00:17:44,716
Alright so this, as an
aside, is a common paradigm.

440
00:17:44,716 --> 00:17:48,746
Anytime you modify self,
it's common to call

441
00:17:48,746 --> 00:17:51,856
to check is self --
if self is non-null,

442
00:17:51,856 --> 00:17:53,716
so that is if everything
went okay

443
00:17:53,716 --> 00:17:56,046
and the previous line
did not return nil,

444
00:17:56,116 --> 00:17:58,146
meaning there's some
memory error or the like,

445
00:17:58,446 --> 00:18:01,656
you check first that self
exists okay before touching one

446
00:18:01,656 --> 00:18:03,676
of its properties as we
did here with self.title.

447
00:18:03,676 --> 00:18:04,536
All right.

448
00:18:04,536 --> 00:18:06,726
So next, I think we
saw this last time.

449
00:18:06,726 --> 00:18:07,616
View Did Load.

450
00:18:07,916 --> 00:18:10,086
We saw this in our no
Nib example, I believe.

451
00:18:10,546 --> 00:18:12,706
View Did Load, if we
read the documentation,

452
00:18:12,706 --> 00:18:13,916
is just a method that's called

453
00:18:13,916 --> 00:18:16,466
when the View Did
Load, so aptly named.

454
00:18:16,676 --> 00:18:18,736
And what does this
guy seem to be doing?

455
00:18:19,626 --> 00:18:22,856
It's wrapping a bit, but it's
about four lines of code total.

456
00:18:22,856 --> 00:18:27,256
>> It's adding the edit button.

457
00:18:27,426 --> 00:18:28,996
>> Yeah, it seems to be
adding the edit button.

458
00:18:28,996 --> 00:18:32,286
So first we called the parents
a met version of the method,

459
00:18:32,286 --> 00:18:33,726
and if we read the
documentation,

460
00:18:33,726 --> 00:18:35,236
we will be reminded typically,

461
00:18:35,356 --> 00:18:37,636
be sure to call the parent
before you do your own thing.

462
00:18:37,976 --> 00:18:41,716
Self.Navigation.Left Button
Bar Item, I don't really know

463
00:18:41,716 --> 00:18:43,936
where this comes from,
but I can probably guess

464
00:18:44,086 --> 00:18:46,466
that because we're
implementing a subclass

465
00:18:46,466 --> 00:18:47,946
of the UITableViewController,

466
00:18:48,246 --> 00:18:53,516
presumably a UITableView has a
property called navigation item.

467
00:18:53,776 --> 00:18:57,006
And that navigation item refers
to the little blue or gray bar

468
00:18:57,006 --> 00:18:58,626
at the top of this
kind of application,

469
00:18:58,886 --> 00:19:03,176
and .Left Button Item refers
to -- .Left Bar Button Item,

470
00:19:03,176 --> 00:19:04,436
refers to the thing at top left,

471
00:19:04,836 --> 00:19:06,336
and we seem to be
storing what there?

472
00:19:06,516 --> 00:19:10,316
Self.Edit Button Type Item,
whatever that happens to be,

473
00:19:10,596 --> 00:19:13,666
and then UI Button Item, add
button, so if we read this,

474
00:19:13,666 --> 00:19:16,736
we're apparently instantiating
a UI Bar Button Item,

475
00:19:16,936 --> 00:19:20,236
allocating it, initializing
it with this thing,

476
00:19:20,236 --> 00:19:22,176
UI Bar Button System Add.

477
00:19:22,436 --> 00:19:25,296
So there's a lot of code there
that's not all that interesting

478
00:19:25,296 --> 00:19:28,046
to dwell on now, but if you
think back to what's going on,

479
00:19:28,176 --> 00:19:32,046
this is really just the code
version of going to something

480
00:19:32,046 --> 00:19:35,276
like my Nib, opening up
the toolbar over here,

481
00:19:35,446 --> 00:19:39,366
scrolling down to the objects
down here, and if we scroll,

482
00:19:39,366 --> 00:19:44,516
scroll, scroll, scroll, we'll
eventually find Navigation Bar

483
00:19:44,686 --> 00:19:47,846
and Navigation Item, so what I'm
doing, a code is the equivalent

484
00:19:47,846 --> 00:19:50,346
of dragging and dropping
this into the user interface,

485
00:19:50,346 --> 00:19:52,126
much like we were
doing last week.

486
00:19:52,506 --> 00:19:53,506
So that's -- that's all.

487
00:19:53,506 --> 00:19:55,386
The magic that we've been
taking for granted of dragging

488
00:19:55,386 --> 00:19:58,516
and dropping is now being
implemented more lower level

489
00:19:58,516 --> 00:19:59,476
in code.

490
00:20:00,046 --> 00:20:00,596
All right.

491
00:20:00,596 --> 00:20:02,856
So let's not worry too much
about the user interface

492
00:20:02,856 --> 00:20:05,436
because that's not
all that interesting

493
00:20:05,436 --> 00:20:06,516
at the end of the day.

494
00:20:06,856 --> 00:20:09,586
Let me just point out a few

495
00:20:09,586 --> 00:20:11,556
of the additional
methods we've implemented.

496
00:20:11,786 --> 00:20:14,096
These are methods that we've
implemented because we need

497
00:20:14,096 --> 00:20:16,726
to implement table
related functionality.

498
00:20:16,986 --> 00:20:18,116
One of these is super simple.

499
00:20:18,436 --> 00:20:20,776
The method called Number
Of Sections In TableView,

500
00:20:20,776 --> 00:20:22,826
if you read the documentation,
its purpose in life is

501
00:20:22,826 --> 00:20:25,816
to return a number, namely
how many rows should there be

502
00:20:25,816 --> 00:20:28,666
in the table, so that the
operating system knows

503
00:20:28,666 --> 00:20:30,576
when to stop rendering rows.

504
00:20:30,886 --> 00:20:33,316
So in this case, we've
just returned -- sorry.

505
00:20:33,966 --> 00:20:35,326
Not rows, sections.

506
00:20:35,726 --> 00:20:38,666
So sections are groupings
of rows together,

507
00:20:38,666 --> 00:20:41,156
and if you have an iPhone and
you go to your settings menu,

508
00:20:41,386 --> 00:20:44,166
you'll see that there are
rows in your settings menu,

509
00:20:44,166 --> 00:20:46,676
but they're typically clustered
with some kind of bold header.

510
00:20:46,846 --> 00:20:48,226
That's referring to a section.

511
00:20:48,226 --> 00:20:49,516
We had no such aesthetics here,

512
00:20:49,516 --> 00:20:52,166
so we just have one massive
section, so I've hardcoded --

513
00:20:52,166 --> 00:20:55,216
may have hardcoded the value
of one in this template.

514
00:20:55,436 --> 00:20:58,816
So Next, TableView,
Number Of Rows In Section.

515
00:20:59,336 --> 00:21:03,036
So this is the method that tells
the program how many rows are --

516
00:21:03,036 --> 00:21:04,376
should actually be
in that table,

517
00:21:04,376 --> 00:21:06,216
how many dates have
been added to the table.

518
00:21:06,216 --> 00:21:08,656
But what is Underscore
Objects.Count?

519
00:21:08,836 --> 00:21:10,406
Where did that come from?

520
00:21:10,406 --> 00:21:14,456
>> It probably holds the
information for the rows.

521
00:21:14,456 --> 00:21:17,006
>> Yeah, it probably holds
the information for the rows

522
00:21:17,006 --> 00:21:20,156
because again, think about --
recall the difference between C

523
00:21:20,156 --> 00:21:21,736
and V, Controller and View.

524
00:21:22,046 --> 00:21:25,736
The View may very well render
what looks like a table,

525
00:21:26,006 --> 00:21:28,336
but if there's any data
that you're rendering,

526
00:21:28,336 --> 00:21:31,166
it's the Controller's job in
life to actually keep track

527
00:21:31,166 --> 00:21:33,376
of that and just
pass it to the View.

528
00:21:33,566 --> 00:21:36,686
So we shouldn't be storing
those dates in the View per se.

529
00:21:36,686 --> 00:21:39,286
We should be storing all of
those dates after every click

530
00:21:39,286 --> 00:21:42,076
of the plus button somewhere
inside of my Controller,

531
00:21:42,236 --> 00:21:43,686
and then just handing
it to the View.

532
00:21:43,896 --> 00:21:46,476
So Underscore Objects, if
we glance back at the top

533
00:21:46,476 --> 00:21:50,126
of the file, was
actually declared up here,

534
00:21:51,276 --> 00:21:54,066
and I've declared
an NS mutable array.

535
00:21:54,126 --> 00:21:56,586
What's the difference between
mutable array and NS array?

536
00:21:56,586 --> 00:21:57,536
>> You can modify it?

537
00:21:57,536 --> 00:21:58,186
>> You can modify it.

538
00:21:58,186 --> 00:21:59,876
So it's mutable in
that you can change it.

539
00:21:59,876 --> 00:22:01,906
You can add, remove
to and from it.

540
00:22:02,356 --> 00:22:05,836
So I've done At Interface Master
ViewController open paren,

541
00:22:05,836 --> 00:22:08,656
closed paren, so again, we've
already did that, I thought.

542
00:22:08,966 --> 00:22:10,496
In the .H file, we had

543
00:22:10,496 --> 00:22:12,916
At Interface
MasterViewController open

544
00:22:12,916 --> 00:22:13,626
curly brace.

545
00:22:13,626 --> 00:22:16,376
Why have we repeated ourselves
and added these parentheses?

546
00:22:16,376 --> 00:22:21,116
>> For it to be private?

547
00:22:21,116 --> 00:22:24,096
>> For it to be private or
to the illusion of privacy.

548
00:22:24,096 --> 00:22:27,786
So we've used an
unnamed category here,

549
00:22:27,786 --> 00:22:29,626
so recall that categories
are just ways

550
00:22:29,626 --> 00:22:31,116
of grouping related functions.

551
00:22:31,116 --> 00:22:33,956
But the world, as a convention,
has adopted it as a means

552
00:22:33,956 --> 00:22:36,436
of approximating the
idea of private methods

553
00:22:36,436 --> 00:22:39,276
and private data members,
private only in the sense

554
00:22:39,316 --> 00:22:42,836
that they are not being declared
to the world in the .H file,

555
00:22:42,836 --> 00:22:45,136
because .H files can be
imported by other people,

556
00:22:45,136 --> 00:22:48,086
which means other people would
see our implementation details.

557
00:22:48,336 --> 00:22:49,706
But they're nonetheless
adding it

558
00:22:49,706 --> 00:22:51,156
to the class Master
ViewController,

559
00:22:51,156 --> 00:22:52,866
because it's inside
of this declaration.

560
00:22:53,256 --> 00:22:55,956
So we apparently have an
NS mutable array Underscore

561
00:22:55,956 --> 00:22:58,336
Objects, but where is
that guy first used?

562
00:22:58,336 --> 00:23:02,536
Well, let me scroll down, and
scroll down, and scroll down,

563
00:23:03,146 --> 00:23:08,096
and it looks like, let's see,
where's our Underscore Objects?

564
00:23:08,096 --> 00:23:08,886
>> [Inaudible audience
response].

565
00:23:08,886 --> 00:23:13,196
>> Ah, there we go.

566
00:23:13,196 --> 00:23:15,506
Exactly. So here
we have a method.

567
00:23:15,506 --> 00:23:18,236
Insert New Object colon.

568
00:23:18,666 --> 00:23:21,666
So what do you think is inducing
this method to be called,

569
00:23:21,666 --> 00:23:22,856
based on what we've
seen thus far?

570
00:23:23,416 --> 00:23:26,116
>> [Inaudible] the plus button?

571
00:23:26,116 --> 00:23:28,516
>> So pitting the plus
button, and how was that done?

572
00:23:28,516 --> 00:23:30,476
Was it done in Interface
Builder, or...

573
00:23:30,936 --> 00:23:34,396
So insert new object.

574
00:23:34,396 --> 00:23:37,596
So again, let's -- let's just
do a little highlight and copy.

575
00:23:37,596 --> 00:23:38,906
Let's see where it
-- oh, interesting.

576
00:23:39,186 --> 00:23:39,996
So View Did Load.

577
00:23:39,996 --> 00:23:41,296
We didn't finish that story.

578
00:23:41,556 --> 00:23:44,456
We didn't -- we -- Apple did
not use Interface Builder teams

579
00:23:44,456 --> 00:23:45,516
to wire things up.

580
00:23:45,516 --> 00:23:47,506
They didn't -- done it
all in low-level code,

581
00:23:47,796 --> 00:23:50,666
so in View Did Load, we started
telling that story in terms

582
00:23:50,666 --> 00:23:51,736
of the Left Button Bar Item.

583
00:23:51,736 --> 00:23:54,256
If we go a little deeper,
notice what's happening here.

584
00:23:54,556 --> 00:23:57,746
When we declared this UI Bar
Button Item and allocate it

585
00:23:57,926 --> 00:24:01,446
and initialize it, we're
choosing -- this is a constant,

586
00:24:01,446 --> 00:24:04,236
this very long word UI Bar
Button System Item Add,

587
00:24:04,276 --> 00:24:07,176
is just the atrociously named
constant for the plus icon.

588
00:24:07,266 --> 00:24:08,056
That's all that's doing.

589
00:24:08,056 --> 00:24:08,676
It's aesthetic.

590
00:24:08,676 --> 00:24:11,906
But we're saying
Target colon Self Action

591
00:24:11,906 --> 00:24:13,846
at Selector Insert New Object.

592
00:24:14,176 --> 00:24:16,346
So first of all, what
does Action colon

593
00:24:16,346 --> 00:24:19,306
at Selector Insert New
Object doing functionally?

594
00:24:19,426 --> 00:24:26,406
>> It's just a message
that should be sent

595
00:24:26,406 --> 00:24:27,606
when it's -- the action happens.

596
00:24:27,606 --> 00:24:28,016
>> Exactly.

597
00:24:28,016 --> 00:24:29,686
When some action happens,
which in this case is going

598
00:24:29,686 --> 00:24:32,226
to be the touching
of the button,

599
00:24:32,226 --> 00:24:34,166
that's the default behavior
for one of these buttons

600
00:24:34,166 --> 00:24:35,656
when it's clicked
by a user's finger,

601
00:24:35,896 --> 00:24:38,246
what message do you want
to send to an object?

602
00:24:38,246 --> 00:24:40,566
You want to send this
message: Insert New Object.

603
00:24:40,736 --> 00:24:43,116
Put another way, what
method do you want to call.

604
00:24:43,676 --> 00:24:46,826
And to which object will
that message be passed?

605
00:24:47,166 --> 00:24:49,166
On which object will
that method be called?

606
00:24:49,676 --> 00:24:51,426
>> The target.

607
00:24:51,546 --> 00:24:52,176
>> The targets.

608
00:24:52,636 --> 00:24:56,636
So Target colon Self means
this class, this object,

609
00:24:57,006 --> 00:25:00,126
and that is why slightly
more lower

610
00:25:00,126 --> 00:25:01,946
in the screen we have
an implementation

611
00:25:01,946 --> 00:25:03,886
of the method that
we want to call.

612
00:25:04,186 --> 00:25:07,176
So as an aside, the reason
that we have this funky syntax,

613
00:25:07,176 --> 00:25:09,446
at Selector open
paren closed paren,

614
00:25:09,736 --> 00:25:13,026
is so that it's clear what
the name of the message is

615
00:25:13,026 --> 00:25:14,776
that you want to send,
because we've seen methods

616
00:25:14,776 --> 00:25:15,836
that have colons in them.

617
00:25:16,056 --> 00:25:18,276
And it would just
get very complicated,

618
00:25:18,276 --> 00:25:20,906
if not impossible,
to parse the string.

619
00:25:21,146 --> 00:25:24,396
If you had Action colon Insert
New Object colon, where --

620
00:25:24,396 --> 00:25:26,066
which colon belongs to what?

621
00:25:26,066 --> 00:25:27,466
So that's the idea
of At Selector.

622
00:25:27,466 --> 00:25:28,686
It's just a syntactic thing.

623
00:25:29,046 --> 00:25:31,246
So that means when you
click that plus button,

624
00:25:31,246 --> 00:25:34,266
this guy is actually called
so, in answer to the question,

625
00:25:34,266 --> 00:25:37,206
where is the objects NS
mutable array coming from?

626
00:25:37,366 --> 00:25:38,796
We instantiate it lazily.

627
00:25:38,876 --> 00:25:42,446
The first time we need it,
we check does it exist?

628
00:25:42,696 --> 00:25:46,256
If it doesn't exist, that is if
Underscore Objects equals nil,

629
00:25:46,546 --> 00:25:49,056
we're going to go ahead and
instantiate an NS mutable array

630
00:25:49,056 --> 00:25:51,146
and then we're going
to start populating it.

631
00:25:51,306 --> 00:25:53,346
And at this point, if you
start to read through the code,

632
00:25:53,346 --> 00:25:54,636
you'll see a couple
new features.

633
00:25:54,636 --> 00:25:56,636
There's this notion
of the Index Path,

634
00:25:56,636 --> 00:25:58,686
which is something specific
to these UI Table Views.

635
00:25:58,956 --> 00:26:02,816
A path is just a couple of
numbers, two numbers together.

636
00:26:02,816 --> 00:26:04,756
A section and a row.

637
00:26:05,116 --> 00:26:06,936
So an index path
is just an object

638
00:26:06,936 --> 00:26:09,746
that contains those two values,
and if you keep reading further

639
00:26:09,746 --> 00:26:12,456
in the code, you'll see
that this is the function

640
00:26:12,456 --> 00:26:14,826
that actually does the
generation of an insertion

641
00:26:14,826 --> 00:26:17,596
of the date into that
actual Table View.

642
00:26:18,316 --> 00:26:18,426
Yeah.

643
00:26:19,706 --> 00:26:22,536
>> First of all, say
we have a property

644
00:26:22,606 --> 00:26:26,396
for the objects variable.

645
00:26:26,446 --> 00:26:32,186
What would be -- would be cost
if you used the alternative?

646
00:26:32,186 --> 00:26:32,326
[Inaudible]?

647
00:26:32,326 --> 00:26:34,136
>> Good question.

648
00:26:34,136 --> 00:26:39,626
So suppose we had declared
objects as a property.

649
00:26:40,326 --> 00:26:42,326
There would be a
couple of implications.

650
00:26:42,326 --> 00:26:45,466
One, we could do Self.Objects
and mutate it that way.

651
00:26:45,746 --> 00:26:48,076
On the other hand, so could
anyone else who happens

652
00:26:48,076 --> 00:26:51,376
to be importing, for
instance, my.H file,

653
00:26:51,376 --> 00:26:52,556
if we declared the
property there,

654
00:26:52,556 --> 00:26:53,896
but we don't have
to declare there.

655
00:26:54,636 --> 00:26:59,716
You would get some marginally
additional functionality

656
00:26:59,716 --> 00:27:03,136
because by default, the setter
and/or the getter will often

657
00:27:03,136 --> 00:27:04,256
have additional code in them.

658
00:27:04,256 --> 00:27:05,856
For instance, if you've
declared it to be atomic,

659
00:27:05,856 --> 00:27:07,836
it will have some additional
code with the setter.

660
00:27:07,836 --> 00:27:08,916
The setter will, by default,

661
00:27:08,916 --> 00:27:11,416
make sure that you never set
an object equal to itself,

662
00:27:11,476 --> 00:27:13,366
which can do some bad
things circularly.

663
00:27:13,616 --> 00:27:14,966
So you would get
some protections,

664
00:27:14,966 --> 00:27:15,626
but you pay a price.

665
00:27:15,626 --> 00:27:17,636
What's the downside?

666
00:27:17,636 --> 00:27:20,976
Do you -- would you
conjecture of using a property

667
00:27:21,166 --> 00:27:23,636
to implement this
container as opposed

668
00:27:23,636 --> 00:27:26,076
to just declaring a
raw pointer like this?

669
00:27:26,416 --> 00:27:27,756
>> It takes longer?

670
00:27:27,756 --> 00:27:28,576
>> It takes longer.

671
00:27:28,576 --> 00:27:31,286
And we're talking, you know,
a negligible amount of time

672
00:27:31,286 --> 00:27:33,116
for something like
this where clearly, I,

673
00:27:33,116 --> 00:27:35,146
the human in the
bottleneck for any slowness

674
00:27:35,146 --> 00:27:37,746
in this application, how quickly
I can press, but in theory,

675
00:27:37,746 --> 00:27:39,446
that's why they've
done it in this way.

676
00:27:39,486 --> 00:27:41,346
Just to -- we're the only
ones using the property.

677
00:27:41,346 --> 00:27:42,226
Not the rest of the world.

678
00:27:42,406 --> 00:27:45,276
I know how to use it, I just
don't need the marginal overhead

679
00:27:45,276 --> 00:27:46,586
of a setter and a getter.

680
00:27:47,176 --> 00:27:47,906
But a good question.

681
00:27:48,876 --> 00:27:51,416
Okay. So let's not spend too
much time on the particulars

682
00:27:51,416 --> 00:27:54,566
of this specific application,
but let's just scroll

683
00:27:54,566 --> 00:27:56,866
through lastly the other
methods that might be here.

684
00:27:56,866 --> 00:28:01,226
So there's this one, TableView,
Self or Row at Index Path,

685
00:28:01,396 --> 00:28:05,006
because this one method actually
reveals an interesting design

686
00:28:05,006 --> 00:28:06,316
pattern that's not uncommon,

687
00:28:06,316 --> 00:28:07,876
especially for performance
reasons.

688
00:28:08,146 --> 00:28:11,366
So TableView, Self
or Row At Index Path,

689
00:28:11,366 --> 00:28:12,686
and then it's given
an index path.

690
00:28:12,686 --> 00:28:14,126
The purpose in life
of this method,

691
00:28:14,176 --> 00:28:17,146
if we read the documentation for
the UITableView Parent Class,

692
00:28:17,816 --> 00:28:24,266
is that it is supposed to return
a cell, a UITableView cell,

693
00:28:24,266 --> 00:28:26,206
so an object that
represents a cell

694
00:28:26,206 --> 00:28:28,706
in a table configured
exactly as we want it.

695
00:28:28,706 --> 00:28:31,396
And by configured, I mean what
text do you want for the cell?

696
00:28:31,556 --> 00:28:33,326
What buttons do you
want on the cell?

697
00:28:33,326 --> 00:28:35,006
What behavior do you
want for that cell?

698
00:28:35,006 --> 00:28:37,896
So in short, this method is
called when rendering this row,

699
00:28:37,896 --> 00:28:40,036
then this row, then this row,
then this row, then this row,

700
00:28:40,316 --> 00:28:43,666
it is my job to tell
iOS how I want each row

701
00:28:43,666 --> 00:28:44,986
to look and behave.

702
00:28:45,346 --> 00:28:46,666
So what's interesting, though,

703
00:28:46,666 --> 00:28:48,256
about this implementation
is the following.

704
00:28:48,256 --> 00:28:52,726
One, we have this static pointer
declared here, so identifier

705
00:28:52,726 --> 00:28:56,036
that points to a string that's
statically declared as "cell."

706
00:28:56,036 --> 00:28:57,366
This is completely arbitrary.

707
00:28:57,366 --> 00:29:00,466
It could be "fu" or "bar" any
word there, but it's going

708
00:29:00,466 --> 00:29:01,976
to be used in the following way.

709
00:29:02,316 --> 00:29:07,836
Down here, I declare UITableView
Cell, TableView DQ Reusable Cell

710
00:29:07,836 --> 00:29:12,386
With Identifier "cell," "fu,"
whatever word you've chosen.

711
00:29:13,166 --> 00:29:14,326
So what is that doing?

712
00:29:14,326 --> 00:29:16,926
Well, I'm checking if
cell equals Equals Nil,

713
00:29:17,136 --> 00:29:21,166
that means that there
apparently was no reusable cell

714
00:29:21,166 --> 00:29:23,926
in my queue, so nothing
came back.

715
00:29:24,556 --> 00:29:25,996
And so what do I proceed to do?

716
00:29:25,996 --> 00:29:27,986
Well, it looks like a
common paradigm here.

717
00:29:28,016 --> 00:29:31,416
UITableView Cell, allocate
it, then initialize it

718
00:29:31,416 --> 00:29:33,506
with some long crazy
named constant,

719
00:29:33,706 --> 00:29:38,606
and also give it a re-use
identifier of "cell," or "fu,"

720
00:29:38,606 --> 00:29:39,776
whatever word you chosen.

721
00:29:40,056 --> 00:29:42,096
Then lastly, change
the accessory type

722
00:29:42,426 --> 00:29:46,336
to be UITableView Cell
Accessory Disclosure Indicator.

723
00:29:46,396 --> 00:29:46,856
What is that?

724
00:29:46,856 --> 00:29:49,746
It's like the little eye icon
or similar on the screen.

725
00:29:50,346 --> 00:29:50,876
All right?

726
00:29:51,376 --> 00:29:54,796
So -- or rather, the little
arrow that points to the right

727
00:29:54,856 --> 00:29:56,646
that we saw on the TableView
when we were in the app.

728
00:29:56,986 --> 00:29:58,216
Then we proceed to do what?

729
00:29:58,466 --> 00:30:00,976
We grab the object at
that particular row.

730
00:30:01,456 --> 00:30:04,496
We then update the
text label on that cell

731
00:30:04,496 --> 00:30:07,216
to be whatever the description
is of that object, so in short,

732
00:30:07,436 --> 00:30:08,616
the object that we
put in that --

733
00:30:08,616 --> 00:30:11,906
the object we put in objects
was essentially a date,

734
00:30:12,736 --> 00:30:13,856
and then we're just adding

735
00:30:13,856 --> 00:30:16,786
that to the descriptive
text on the cell itself.

736
00:30:17,356 --> 00:30:18,846
And then we return the cell.

737
00:30:19,146 --> 00:30:21,406
So most of that was just
configuration details.

738
00:30:21,406 --> 00:30:23,336
Maybe new in terms of
the code we're seeing,

739
00:30:23,496 --> 00:30:25,236
but not all that
interesting except

740
00:30:25,236 --> 00:30:27,186
for this If condition here.

741
00:30:28,136 --> 00:30:31,596
What do you think the purpose
is of the relative complexity

742
00:30:31,596 --> 00:30:32,766
of these several lines?

743
00:30:32,766 --> 00:30:33,716
Why this queue?

744
00:30:33,716 --> 00:30:35,116
Why this reusable thing?

745
00:30:35,686 --> 00:30:36,506
What's going on?

746
00:30:36,966 --> 00:30:38,886
>> Make sure you don't
overwrite the cell,

747
00:30:38,886 --> 00:30:40,366
then just make sure it's unique.

748
00:30:40,366 --> 00:30:42,076
>> Okay, so make sure you
don't overwrite a cell.

749
00:30:42,076 --> 00:30:43,086
Make sure it's unique.

750
00:30:43,086 --> 00:30:46,486
True, but we could do that
by just allocating a new cell

751
00:30:46,626 --> 00:30:49,216
for every one of the dates
in this table, or every one

752
00:30:49,216 --> 00:30:51,416
of the words that I want
to put in this table.

753
00:30:52,726 --> 00:30:56,346
Why else might I be introducing
this complexity of some kind

754
00:30:56,346 --> 00:30:58,246
of queue of reusable cells?

755
00:30:58,836 --> 00:31:01,696
>> Want to change
the value inside?

756
00:31:02,036 --> 00:31:04,316
>> Want to change the value
inside, so that's true,

757
00:31:05,126 --> 00:31:07,136
but why -- what's
the motivation?

758
00:31:07,626 --> 00:31:10,626
Let me press further.

759
00:31:10,626 --> 00:31:14,216
Suppose that you can view 10
cells on the screen at once,

760
00:31:14,216 --> 00:31:15,896
based on the height of
your iPhone and the height

761
00:31:15,896 --> 00:31:20,566
of your font, and you have
allocated, let me say,

762
00:31:20,646 --> 00:31:23,526
if you want -- if you only
can display 10 rows at a time

763
00:31:23,776 --> 00:31:25,606
but you've got 100
date because you've hit

764
00:31:25,606 --> 00:31:29,856
that button 100 times,
technically only 10

765
00:31:29,946 --> 00:31:33,736
of those cells need to be
in RAM at any given time,

766
00:31:33,876 --> 00:31:35,556
because the other
90 are down here.

767
00:31:35,556 --> 00:31:37,046
The user is not going
to be able to see them,

768
00:31:37,046 --> 00:31:38,786
so why bother keeping
them in memory?

769
00:31:40,196 --> 00:31:42,726
So if I give you that insight,

770
00:31:43,536 --> 00:31:45,536
why are we apparently
using this trick?

771
00:31:45,826 --> 00:31:46,726
What's the motivation?

772
00:31:47,226 --> 00:31:47,356
Yeah.

773
00:31:47,776 --> 00:31:49,546
>> To make it faster
and [inaudible].

774
00:31:49,546 --> 00:31:49,936
>> Exactly.

775
00:31:49,936 --> 00:31:52,216
It all boils down to memory
usage and memory management,

776
00:31:52,216 --> 00:31:54,956
so to your comment earlier
about really the spirit

777
00:31:54,956 --> 00:31:56,586
of keeping memory usage low,

778
00:31:56,766 --> 00:31:59,366
you could absolutely
just allocate 100 cells

779
00:31:59,366 --> 00:32:01,836
for 100 items, and frankly
the user is probably not going

780
00:32:01,836 --> 00:32:04,086
to notice any latency when
a scrolling through them,

781
00:32:04,086 --> 00:32:05,236
because 100 is not that big.

782
00:32:05,496 --> 00:32:06,856
But suppose for Evil Hangman,

783
00:32:06,856 --> 00:32:08,116
you decided to make
an application

784
00:32:08,116 --> 00:32:10,646
that displays all 100,000
plus words at once,

785
00:32:10,646 --> 00:32:11,666
and you scroll through that.

786
00:32:12,016 --> 00:32:14,186
Then you probably will,
depending on the hardware,

787
00:32:14,186 --> 00:32:15,906
start to notice some
latency because there's

788
00:32:15,906 --> 00:32:18,786
so much RAM being taken
up by all of those rows,

789
00:32:18,786 --> 00:32:20,556
and it's completely unnecessary.

790
00:32:20,556 --> 00:32:22,706
Of the hundred thousand, you
can only see maybe 10 of them

791
00:32:22,706 --> 00:32:25,696
at once, so you only need
to have 10 actually resident

792
00:32:25,696 --> 00:32:27,896
in memory at a time,
so this queue is meant

793
00:32:27,896 --> 00:32:29,446
to be a performance
optimization.

794
00:32:29,446 --> 00:32:31,706
So if you've ever use an
iOS application that starts

795
00:32:31,706 --> 00:32:34,226
to feel very laggy for
some reason, it's probably

796
00:32:34,226 --> 00:32:37,106
because they were trying to do
too much, and potentially some

797
00:32:37,106 --> 00:32:39,886
of that work was unnecessary,
as might be the case here.

798
00:32:40,176 --> 00:32:42,386
So this is illustrative of
that kind of design paradigm,

799
00:32:42,386 --> 00:32:46,446
especially as your data
sets get larger and larger.

800
00:32:47,926 --> 00:32:50,886
Okay. Let's not dwell too
much on the other methods,

801
00:32:50,886 --> 00:32:53,716
but happy to take
questions if they arise

802
00:32:53,716 --> 00:32:55,496
or are on your minds now.

803
00:32:57,236 --> 00:32:57,876
All right.

804
00:32:57,876 --> 00:32:59,516
So that just leaves us
with one last class,

805
00:32:59,516 --> 00:33:00,816
the Detail ViewController.

806
00:33:01,016 --> 00:33:02,826
So this guy, if I
go to the .H file,

807
00:33:03,116 --> 00:33:04,996
looks pretty uninteresting,
except for the fact

808
00:33:04,996 --> 00:33:08,096
that he's got a UILabel
and he's got a Detail Item.

809
00:33:08,326 --> 00:33:10,086
I also see mention of IBOutlet.

810
00:33:10,086 --> 00:33:10,696
What is that again?

811
00:33:11,296 --> 00:33:14,746
What's an IBOutlet?

812
00:33:15,656 --> 00:33:18,146
>> Reference to a thing
that's declared in the Nib?

813
00:33:18,286 --> 00:33:18,846
>> Okay, good.

814
00:33:18,846 --> 00:33:21,046
So it's a reference to something
that's declared in the neb,

815
00:33:21,046 --> 00:33:23,196
so it's a means of
my code talking

816
00:33:23,196 --> 00:33:25,046
to my drag and drop interface.

817
00:33:25,046 --> 00:33:27,746
And in this case, the thing
in question is UILabel,

818
00:33:27,946 --> 00:33:31,236
so how can I pull up Interface
Builder and see that interface?

819
00:33:31,236 --> 00:33:33,226
What file do I want to click
next to follow this bread --

820
00:33:33,226 --> 00:33:33,926
this trail of breadcrumbs?

821
00:33:33,926 --> 00:33:35,176
>> Detail ViewController.Nib.

822
00:33:35,716 --> 00:33:40,536
>> Yeah, so Detail
ViewController.Nib,

823
00:33:40,536 --> 00:33:43,156
and if I look there,
it looks like indeed,

824
00:33:43,156 --> 00:33:45,336
someone has just dragged
and dropped a UILabel.

825
00:33:45,336 --> 00:33:49,166
I know that because I can see
its description down over here.

826
00:33:49,336 --> 00:33:52,366
And when in doubt, too, if I go
to the right-hand panel and open

827
00:33:52,366 --> 00:33:55,346
that up, and notice that I'm
on the Identity Inspector,

828
00:33:55,596 --> 00:33:57,616
Xcode has a habit
of dumbing things

829
00:33:57,616 --> 00:34:01,416
down by saying Label hyphen
Detail ViewController dot dot

830
00:34:01,416 --> 00:34:02,916
dot, when really that's not all

831
00:34:02,916 --> 00:34:04,126
that interesting
programmatically.

832
00:34:04,126 --> 00:34:06,346
You want to know what type
of object is that really,

833
00:34:06,586 --> 00:34:09,386
so in the Identity Inspector,
which you can see at top right,

834
00:34:09,716 --> 00:34:12,546
you can see that, oh, the thing
I've just clicked is actually an

835
00:34:12,546 --> 00:34:13,976
instance of UILabel.

836
00:34:13,976 --> 00:34:15,846
That is what I have dragged
and dropped, and again,

837
00:34:15,846 --> 00:34:18,996
that's the connection
between code, and the drag

838
00:34:18,996 --> 00:34:20,346
and drop interface here.

839
00:34:20,766 --> 00:34:23,386
So let's enter just one last
question before we put this

840
00:34:23,716 --> 00:34:24,896
template aside.

841
00:34:25,236 --> 00:34:27,246
How do we somehow
pass control off

842
00:34:27,246 --> 00:34:30,516
from the Master ViewController
to the Detail ViewController?

843
00:34:30,516 --> 00:34:31,836
How do we make that transition?

844
00:34:32,736 --> 00:34:34,406
We haven't looked at
the code yet per se,

845
00:34:34,406 --> 00:34:37,106
but where would you look if you
wanted to answer that question?

846
00:34:37,336 --> 00:34:40,786
How does clicking on a cell
lead to a state transition?

847
00:34:41,246 --> 00:34:45,346
What file should we look at?

848
00:34:45,606 --> 00:34:47,646
>> Do you look at the
method that's called

849
00:34:47,646 --> 00:34:49,006
when it's actually clicked?

850
00:34:49,006 --> 00:35:02,226
>> Okay, so we want to look
at the method that's called

851
00:35:02,976 --> 00:35:05,226
when it's actually clicked.

852
00:35:05,626 --> 00:35:10,396
And how can I chase
down that answer?

853
00:35:10,396 --> 00:35:19,436
>> Ask in a selector into the
constructor of one of the codes?

854
00:35:19,436 --> 00:35:19,936
>> Okay.

855
00:35:23,676 --> 00:35:25,116
>> [Inaudible] the
Master ViewController.M.

856
00:35:25,116 --> 00:35:25,606
>> Okay.

857
00:35:25,606 --> 00:35:27,786
>> Hitting control X,
control X is a selector.

858
00:35:27,786 --> 00:35:28,946
>> Selector, okay.

859
00:35:29,206 --> 00:35:33,336
So there's a selector
for insert new object.

860
00:35:33,336 --> 00:35:34,766
We saw that before.

861
00:35:34,876 --> 00:35:36,916
Only one match.

862
00:35:37,646 --> 00:35:40,986
>> There should probably
be a protocol somewhere

863
00:35:40,986 --> 00:35:43,056
that defines an interface
between Master...

864
00:35:43,056 --> 00:35:44,406
>> Okay. So let's see.

865
00:35:44,406 --> 00:35:50,126
If I scroll down here, self a
row, can edit row at index path,

866
00:35:50,126 --> 00:35:51,436
TableView Commit Editing Style.

867
00:35:51,436 --> 00:35:53,026
That doesn't sound right.

868
00:35:53,026 --> 00:35:54,676
Oh this one, interesting.

869
00:35:54,676 --> 00:35:56,186
And that's exactly right.

870
00:35:56,186 --> 00:35:57,166
What Peter proposed is

871
00:35:57,166 --> 00:36:00,466
that presumably there's
some method that's defined,

872
00:36:00,496 --> 00:36:04,376
maybe in that protocol we saw at
the very beginning of the story,

873
00:36:04,376 --> 00:36:09,476
that is what's called when
a user clicks on the row.

874
00:36:09,476 --> 00:36:11,386
And indeed that's the case.

875
00:36:11,386 --> 00:36:13,436
It's -- this is a common
paradigm, clicking on the row

876
00:36:13,436 --> 00:36:15,876
in a table, so Apple went
ahead and implemented

877
00:36:16,646 --> 00:36:23,576
that base functionality for
us, so if we want to listen

878
00:36:23,576 --> 00:36:26,386
for that key press
on one of those rows,

879
00:36:26,386 --> 00:36:28,426
we apparently just have

880
00:36:28,426 --> 00:36:32,616
to implement a method called
TableView Did Select Row

881
00:36:32,616 --> 00:36:33,036
at Index Path.

882
00:36:33,036 --> 00:36:35,276
So what's going on in there?

883
00:36:35,276 --> 00:36:37,866
Well, notice first, it
takes two arguments.

884
00:36:37,866 --> 00:36:39,176
The first is a TableView,

885
00:36:39,176 --> 00:36:43,846
so that's what TableView
did the user click on.

886
00:36:43,876 --> 00:36:47,266
Maybe there's multiple
ones on this screen.

887
00:36:47,576 --> 00:36:50,416
And what, again to be
clear, is an Index Path?

888
00:36:50,416 --> 00:36:51,346
>> Section and...

889
00:36:51,346 --> 00:36:52,896
>> Section and a row number.

890
00:36:52,896 --> 00:36:56,106
So it's going to be like
zero comma something

891
00:36:56,166 --> 00:36:58,106
for the zero section,
zero index,

892
00:36:58,106 --> 00:36:59,706
and the actual row number.

893
00:36:59,706 --> 00:37:00,076
All right.

894
00:37:00,076 --> 00:37:01,216
So what are we doing here?

895
00:37:01,586 --> 00:37:07,206
We again seem to be doing what's
generally called lazy loading.

896
00:37:07,496 --> 00:37:10,346
If the Detail ViewController
does not yet exist, if it's nil,

897
00:37:10,346 --> 00:37:11,876
what do we actually do?

898
00:37:12,156 --> 00:37:17,436
We allocate it by calling
Detail ViewController Alloc,

899
00:37:17,436 --> 00:37:24,406
we initialize it with Nib
name, Detail ViewController.

900
00:37:24,406 --> 00:37:29,186
Notice when you call this
method, you don't say .XIB.

901
00:37:29,336 --> 00:37:35,266
Bundle is just referring
to what folder is it in.

902
00:37:35,266 --> 00:37:39,186
We just say nil because
it's in the default.

903
00:37:39,186 --> 00:37:43,596
Everything is organized
at this top level.

904
00:37:43,636 --> 00:37:48,086
And so once these lines
of code have executed,

905
00:37:48,386 --> 00:37:51,166
we now have a pointer
to an object

906
00:37:51,166 --> 00:37:52,456
of type Detail ViewController.

907
00:37:52,456 --> 00:37:57,496
So we've got the thing in memory
now, we just have to transition

908
00:37:57,496 --> 00:37:59,316
from the Master to the Detail.

909
00:37:59,316 --> 00:38:01,526
So what am I going to do next?

910
00:38:01,526 --> 00:38:02,646
NS Date Object object.

911
00:38:02,646 --> 00:38:07,106
So just to be clear, what is
this next line of code doing?

912
00:38:07,106 --> 00:38:10,796
On the right-hand side, we
have what type of object?

913
00:38:10,796 --> 00:38:12,566
What is Underscore Objects?

914
00:38:12,656 --> 00:38:13,236
>> A mutable array?

915
00:38:13,236 --> 00:38:14,276
>> An NS mutable array.

916
00:38:14,276 --> 00:38:19,946
So if we index into it at
a current row, that's going

917
00:38:20,046 --> 00:38:22,966
to return an object of
what type apparently?

918
00:38:22,966 --> 00:38:25,536
An NS date, and on the left-hand
side, we're allocating what?

919
00:38:25,536 --> 00:38:27,336
What's the pop quiz here?

920
00:38:27,336 --> 00:38:27,936
>> A pointer.

921
00:38:28,226 --> 00:38:31,256
>> A pointer, good, to an
object of type NS date.

922
00:38:31,736 --> 00:38:35,876
So we're not allocating an NS
date, we're allocating a pointer

923
00:38:36,196 --> 00:38:39,776
to an NS date, so it's
just 64 bits most likely,

924
00:38:39,776 --> 00:38:40,856
not the full-fledged object.

925
00:38:40,856 --> 00:38:44,466
Next we do Self.Detail
ViewController.

926
00:38:44,466 --> 00:38:46,526
Detail ViewController.

927
00:38:47,046 --> 00:38:49,166
What is Self.Detail
ViewController?

928
00:38:49,166 --> 00:38:50,236
Where did we see that before?

929
00:38:50,696 --> 00:38:51,996
>> Property?

930
00:38:51,996 --> 00:38:57,086
>> So it's a property
that we declared earlier,

931
00:38:57,086 --> 00:38:58,146
and .Detail Item?

932
00:38:58,696 --> 00:39:00,146
Well, what's Detail Item?

933
00:39:00,146 --> 00:39:02,936
It's going to be
set to the object.

934
00:39:03,216 --> 00:39:08,206
Where did I see Detail Item?

935
00:39:08,916 --> 00:39:12,506
If I go to Detail
ViewController.H,

936
00:39:12,506 --> 00:39:16,196
Detail Item was apparently a
property that I stored here.

937
00:39:16,196 --> 00:39:16,626
It's a type ID.

938
00:39:16,626 --> 00:39:17,226
What does ID mean?

939
00:39:17,226 --> 00:39:17,816
>> Any object.

940
00:39:17,816 --> 00:39:18,526
>> Any object.

941
00:39:18,586 --> 00:39:20,616
It's a pointer that
could be nil,

942
00:39:20,616 --> 00:39:22,086
but it's a pointer
to any object.

943
00:39:22,086 --> 00:39:24,126
So this is just a generic way.

944
00:39:24,126 --> 00:39:25,766
We could have been more
explicit and stored NS dates.

945
00:39:25,766 --> 00:39:27,126
Whoever with this
template decided

946
00:39:27,126 --> 00:39:28,096
to just genericize it a bit,

947
00:39:28,096 --> 00:39:29,156
so we're storing
something of type ID there.

948
00:39:29,186 --> 00:39:30,476
So lastly in this line, we
call Push ViewController

949
00:39:30,506 --> 00:39:30,866
Animated Yes.

950
00:39:30,896 --> 00:39:32,486
So the fact that it slides from
left to right, as we can see,

951
00:39:32,516 --> 00:39:33,656
is the following -- is the
result of the following.

952
00:39:33,686 --> 00:39:34,856
Notice the sexy left
right behavior like that,

953
00:39:34,886 --> 00:39:36,296
but if I instead change the
bullion yes to bullion no,

954
00:39:36,326 --> 00:39:37,436
stop the current running
instance and rerun,

955
00:39:37,466 --> 00:39:38,456
and now go ahead and
plus, plus, plus,

956
00:39:38,486 --> 00:39:39,206
click here, much less elegance.

957
00:39:39,236 --> 00:39:39,416
All right?

958
00:39:39,446 --> 00:39:40,376
That's what makes
Apple devices Apple.

959
00:39:40,406 --> 00:39:41,396
The sexy little slides
back and forth.

960
00:39:41,426 --> 00:39:41,606
All right.

961
00:39:41,636 --> 00:39:41,876
Questions?

962
00:39:41,906 --> 00:39:43,466
Okay. So you may never again use
a Master Detail ViewController

963
00:39:43,496 --> 00:39:44,096
template, and that's fine.

964
00:39:44,126 --> 00:39:45,506
The goal of this was not to
walk through just templates

965
00:39:45,536 --> 00:39:46,136
that Apple hands to us,

966
00:39:46,166 --> 00:39:46,946
but rather [inaudible]
the design paradigms

967
00:39:46,976 --> 00:39:48,026
that they're leveraging
as a result of this

968
00:39:48,056 --> 00:39:49,316
so that you can either start
with something like this,

969
00:39:49,346 --> 00:39:50,906
or something simpler, like the
simple Single View application,

970
00:39:50,936 --> 00:39:52,166
and begin to wire things
together in the same way.

971
00:39:52,196 --> 00:39:53,336
And what this is
particularly illustrative

972
00:39:53,366 --> 00:39:54,776
of is wiring stuff together,
not using Interface Builder,

973
00:39:54,806 --> 00:39:55,706
and dragging and
dropping blue lines,

974
00:39:55,736 --> 00:39:57,386
but writing much more code and
doing it manually and precisely.

975
00:39:57,386 --> 00:39:57,453
>> [Inaudible audience
question].

976
00:39:57,453 --> 00:39:57,746
>> IB outlet in...

977
00:39:57,746 --> 00:39:57,813
>> [Inaudible audience
response].

978
00:39:57,813 --> 00:39:58,196
>> This guy over here?

979
00:39:58,226 --> 00:39:58,616
Ah, good question.

980
00:39:58,646 --> 00:39:59,366
So Detail Description Item.

981
00:39:59,396 --> 00:40:00,866
For some reason, the developer
who wrote this template seems

982
00:40:00,896 --> 00:40:02,336
to have gotten bored with
actually doing the wiring and --

983
00:40:02,366 --> 00:40:03,896
rather the coding, and decided
to wire it up so we can go

984
00:40:03,926 --> 00:40:04,976
to the Nib file for
Detail ViewController.

985
00:40:05,106 --> 00:40:08,016
And if I control
click on this thing,

986
00:40:08,016 --> 00:40:12,776
we will see that Detail
Description Label is wired

987
00:40:12,776 --> 00:40:13,936
to file's owner.

988
00:40:14,016 --> 00:40:15,946
And who is the owner of
this file apparently?

989
00:40:15,946 --> 00:40:21,046
>> Yourself, or the Controller.

990
00:40:21,126 --> 00:40:21,676
>> The Controller.

991
00:40:21,676 --> 00:40:25,316
The Detail ViewController,
because recall, that's the guy

992
00:40:25,316 --> 00:40:30,046
that initialized the Nib
in In It With Nib Names.

993
00:40:30,186 --> 00:40:32,316
So he is the file's owner,
because he is the guy

994
00:40:32,316 --> 00:40:34,726
that called this
Nib file to life.

995
00:40:35,896 --> 00:40:38,036
So that was the one instance
of dragging and dropping.

996
00:40:38,036 --> 00:40:43,666
Everything else in the
Master was done in code.

997
00:40:43,826 --> 00:40:45,646
>> Okay so that's
why it's [inaudible]?

998
00:40:45,646 --> 00:40:46,356
>> Yes. Oh, I'm sorry.

999
00:40:46,356 --> 00:40:47,416
Missed that part
of the question.

1000
00:40:47,416 --> 00:40:49,506
Yes, so if we go into
Detail ViewController,

1001
00:40:49,506 --> 00:40:51,796
we have seen a slightly
different feature here.

1002
00:40:51,796 --> 00:40:53,866
These attributes
associated with properties,

1003
00:40:54,226 --> 00:40:59,926
the reason that this here is
weak is that we do not want the,

1004
00:41:00,776 --> 00:41:02,786
what's the best way to say this.

1005
00:41:03,696 --> 00:41:06,816
This property in the Detail
ViewController is not --

1006
00:41:07,176 --> 00:41:10,376
is pointing to an object that
doesn't need to be kept around,

1007
00:41:10,376 --> 00:41:13,506
particularly if the Detail
ViewController, once it goes

1008
00:41:13,506 --> 00:41:15,486
out of scope, as by
hitting the back button,

1009
00:41:15,686 --> 00:41:16,736
disappears from memory.

1010
00:41:16,986 --> 00:41:18,576
We don't want to have
a strong reference

1011
00:41:18,576 --> 00:41:21,816
to the Detail Description
Label lest

1012
00:41:22,036 --> 00:41:25,346
that blue line keep the
Detail ViewController

1013
00:41:25,466 --> 00:41:27,536
in memory unnecessarily long.

1014
00:41:28,116 --> 00:41:29,926
So in this really
-- boils down --

1015
00:41:29,926 --> 00:41:31,396
the motivation for this is

1016
00:41:31,396 --> 00:41:33,306
because the Detail
ViewController is coming

1017
00:41:33,306 --> 00:41:36,416
and going, we want iOS to be
able to reclaim that memory,

1018
00:41:36,656 --> 00:41:39,776
and so we don't hang onto, in
a strong way, these bluelines.

1019
00:41:41,206 --> 00:41:43,246
And that's the first instance
I think we've actually seen

1020
00:41:43,246 --> 00:41:45,346
of that use of weak
for that reason.

1021
00:41:45,696 --> 00:41:46,196
Good question.

1022
00:41:47,166 --> 00:41:47,796
All right, why don't we go ahead

1023
00:41:47,796 --> 00:41:48,956
and take our five-minute
break here.

1024
00:41:48,956 --> 00:41:50,946
Will come back and start
building something from scratch.

1025
00:41:51,326 --> 00:41:53,316
And we're back.

1026
00:41:53,916 --> 00:41:55,606
So recall that there's
been a checkbox

1027
00:41:55,606 --> 00:41:56,736
that we haven't checked this far

1028
00:41:56,736 --> 00:41:58,596
because we've been
using Nibs instead.

1029
00:41:58,596 --> 00:42:00,336
And Nibs are a deliberate
design decision

1030
00:42:00,336 --> 00:42:02,736
because they've given us
much more low level control

1031
00:42:02,966 --> 00:42:04,156
over our user interface,

1032
00:42:04,416 --> 00:42:07,136
but popular these days
is another feature

1033
00:42:07,136 --> 00:42:09,506
that we keep unchecking,
known as Storyboards.

1034
00:42:09,506 --> 00:42:11,946
Anyone familiar with these yet?

1035
00:42:12,896 --> 00:42:13,866
Used Storyboards?

1036
00:42:13,866 --> 00:42:15,836
If we check that, what
we get out of the box?

1037
00:42:16,656 --> 00:42:18,766
So this is Apple's way of trying

1038
00:42:18,766 --> 00:42:20,706
to simplify the user
interface process further,

1039
00:42:20,706 --> 00:42:24,226
at least for applications that
follow some common iOS paradigms

1040
00:42:24,226 --> 00:42:26,646
like the TableView that we just
saw, the Utility Application

1041
00:42:26,646 --> 00:42:31,656
that we just saw, and making
it less necessary to write code

1042
00:42:31,806 --> 00:42:33,896
to somehow make ViewControllers
interact.

1043
00:42:34,286 --> 00:42:37,586
So if we follow this next
screen by clicking Next

1044
00:42:37,586 --> 00:42:40,296
with ViewStoryboards, what
we'll get is an application

1045
00:42:40,296 --> 00:42:42,736
that looks a bit like this,
and let me go ahead and open

1046
00:42:42,736 --> 00:42:47,826
up a different project called
Storyboard from tonight's code,

1047
00:42:48,136 --> 00:42:54,216
and this will give us a view
of exactly what's different.

1048
00:42:54,216 --> 00:42:57,576
In the Storyboard folder,
the story begins as usual

1049
00:42:57,576 --> 00:43:01,146
with Main.M, and then up here we
seem to have Main ViewController

1050
00:43:01,146 --> 00:43:03,596
and Flipside ViewController,
so what I've done was start

1051
00:43:03,596 --> 00:43:06,066
with the -- which template as
a starting point apparently?

1052
00:43:06,066 --> 00:43:06,306
>> Utility?

1053
00:43:06,726 --> 00:43:09,646
>> So the Utility Application.

1054
00:43:09,646 --> 00:43:12,836
And a couple of you did this I
think accidentally maybe last

1055
00:43:12,986 --> 00:43:15,086
week when following along
since it was pointed

1056
00:43:15,086 --> 00:43:18,216
out that your Nib file looked
a little different, and it's --

1057
00:43:18,216 --> 00:43:20,766
or your UI looked
a little different.

1058
00:43:20,766 --> 00:43:24,956
And indeed, if we go to
Main Storyboard.Storyboard,

1059
00:43:25,156 --> 00:43:27,156
we see a user interface
that looks like this

1060
00:43:27,276 --> 00:43:29,976
for utility application, and
it appears that we're seeing

1061
00:43:29,976 --> 00:43:32,876
like two Nibs simultaneously:
the Main ViewController

1062
00:43:33,096 --> 00:43:34,876
and the Flipside
ViewController's UI

1063
00:43:35,066 --> 00:43:35,896
in the same screen.

1064
00:43:35,896 --> 00:43:38,656
But they're somehow
connected via this transition,

1065
00:43:38,926 --> 00:43:41,626
generally known as a segue,
and indeed that's what it is,

1066
00:43:41,626 --> 00:43:43,156
because when you
use a Storyboard,

1067
00:43:43,346 --> 00:43:46,556
you essentially get one master
file for your user interface,

1068
00:43:46,766 --> 00:43:49,926
and you wire this up
all within itself.

1069
00:43:50,006 --> 00:43:54,176
And you specify in code
exactly what you want to happen

1070
00:43:54,176 --> 00:43:57,626
when A segues to B. So the
one line of code we need

1071
00:43:57,626 --> 00:44:00,446
to draw attention to
really is just this.

1072
00:44:00,446 --> 00:44:02,356
If I go into my Main
ViewController,

1073
00:44:02,576 --> 00:44:04,836
notice that this is actually
pretty straightforward.

1074
00:44:04,836 --> 00:44:07,206
I've simply implemented a
separate method this time called

1075
00:44:07,206 --> 00:44:09,336
Prepare For Segue Sender,

1076
00:44:09,696 --> 00:44:11,436
and this is the method
that's apparently going

1077
00:44:11,436 --> 00:44:15,146
to be called whenever the
user induces a transition

1078
00:44:15,146 --> 00:44:17,716
from the first controller
to the second controller,

1079
00:44:17,896 --> 00:44:19,156
and you can see what's doing --

1080
00:44:19,156 --> 00:44:22,346
what it's doing here if
segue identifier is equal

1081
00:44:22,346 --> 00:44:24,586
to the string "show alternate."

1082
00:44:24,976 --> 00:44:27,696
So this string, show alternate,
is completely arbitrary.

1083
00:44:27,696 --> 00:44:29,486
Could have been fu,
bar, baz, whatever.

1084
00:44:29,676 --> 00:44:31,526
But it's a string that
we'll see elsewhere

1085
00:44:31,756 --> 00:44:34,416
and apparently what's happening,
if that is the identifier

1086
00:44:34,416 --> 00:44:37,456
of the segue that the user wants
to happen by having interacted

1087
00:44:37,456 --> 00:44:38,326
with the application,

1088
00:44:38,726 --> 00:44:42,096
we're going to call
Destination ViewController

1089
00:44:42,096 --> 00:44:45,096
on the segue, set
delegate to Self.

1090
00:44:45,516 --> 00:44:49,046
In other words, before the
user transitions from this side

1091
00:44:49,656 --> 00:44:53,156
to this side, we apparently
want to inform the segue

1092
00:44:53,156 --> 00:44:57,496
that the destination is
going to be what ultimately?

1093
00:44:58,036 --> 00:45:01,186
Or rather, we want to inform
the Destination ViewController

1094
00:45:01,546 --> 00:45:06,406
that its delegate is going
to be Self, the main side.

1095
00:45:06,576 --> 00:45:07,996
So recall the same paradigm

1096
00:45:07,996 --> 00:45:09,836
in the Utility Application
we played with in class

1097
00:45:10,016 --> 00:45:12,086
that you've probably begun
with for Evil Hangman,

1098
00:45:12,086 --> 00:45:15,726
or are about to, whereby when
you click that Done button,

1099
00:45:15,916 --> 00:45:18,306
you want the transition to
go back and you need to know

1100
00:45:18,306 --> 00:45:20,006
to whom to return control,

1101
00:45:20,006 --> 00:45:21,626
in this case the
Main ViewController.

1102
00:45:21,916 --> 00:45:23,036
So that begs the question,

1103
00:45:23,036 --> 00:45:24,856
where is this quoted
string coming from?

1104
00:45:24,966 --> 00:45:26,596
Where is this identifier
for the segue?

1105
00:45:26,596 --> 00:45:30,846
So if we go to the Storyboard,
and I click on the segue itself,

1106
00:45:30,846 --> 00:45:34,046
not much happens over here, but
notice that this is apparently

1107
00:45:34,046 --> 00:45:38,646
of type Modal Segue From Button,
flip to Flipside ViewController.

1108
00:45:38,646 --> 00:45:39,866
That's the English
friendly string.

1109
00:45:40,086 --> 00:45:42,936
I'm going to have to make my
UI a bit of a mess and open up,

1110
00:45:43,606 --> 00:45:50,336
over here, the right hand panel,
and with that segue selected,

1111
00:45:50,336 --> 00:45:54,356
if I go up here to the
Attributes Inspector,

1112
00:45:54,536 --> 00:45:57,736
notice that the programmer who
made this template, in this case

1113
00:45:57,736 --> 00:46:01,106
at Apple, to manually typed in
an identifier of Show Alternate,

1114
00:46:01,296 --> 00:46:03,616
But again, that could have
been fu, bar, any string there,

1115
00:46:03,616 --> 00:46:05,706
and that's to uniquely
identify the transition.

1116
00:46:05,936 --> 00:46:07,516
So in short, if we want

1117
00:46:07,516 --> 00:46:09,796
to somehow wire together
the user interface

1118
00:46:09,796 --> 00:46:11,986
in this different
paradigm whereby both sides

1119
00:46:11,986 --> 00:46:14,476
of the application are in
one file, we simply have

1120
00:46:14,476 --> 00:46:18,516
to define what happens when
that transition occurs.

1121
00:46:18,516 --> 00:46:22,046
So I mention these now
because if you want

1122
00:46:22,046 --> 00:46:24,216
to take things further, say for
your own native application,

1123
00:46:24,216 --> 00:46:25,426
if you go that route
for the third,

1124
00:46:25,746 --> 00:46:27,896
you'll find that this is
a very common paradigm now

1125
00:46:27,896 --> 00:46:30,786
with iOS programming because
it really eliminates a lot more

1126
00:46:30,786 --> 00:46:32,076
of the wiring that
you need to do,

1127
00:46:32,076 --> 00:46:34,066
and it centralizes
the UI in one place.

1128
00:46:34,266 --> 00:46:36,456
And as this picture
kind of suggests,

1129
00:46:36,616 --> 00:46:39,366
if you have a particularly
complex UI, like a menu,

1130
00:46:39,366 --> 00:46:42,406
and then a submenu, and other
submenus and other submenus,

1131
00:46:42,656 --> 00:46:44,436
you can wire them all together

1132
00:46:44,466 --> 00:46:45,986
within the confines
of the same tool.

1133
00:46:46,086 --> 00:46:47,306
And it's just a simplification.

1134
00:46:47,486 --> 00:46:47,596
Yeah.

1135
00:46:47,696 --> 00:46:56,026
>> Is there a disadvantage of
wiring like the information

1136
00:46:56,026 --> 00:46:57,706
to the second page and then
going back to the first page?

1137
00:46:57,706 --> 00:46:58,266
>> Good question.

1138
00:46:58,266 --> 00:46:59,156
Is there a disadvantage?

1139
00:46:59,156 --> 00:46:59,406
Not really.

1140
00:46:59,406 --> 00:47:01,656
The gripe people tend to
have with Interface Builder

1141
00:47:01,656 --> 00:47:03,756
or using Nibs or Storyboards in
this way is that you don't have

1142
00:47:03,756 --> 00:47:07,146
as much low-level control,
and you can't necessarily --

1143
00:47:07,446 --> 00:47:10,746
might take -- sometimes
take more steps to implement

1144
00:47:10,896 --> 00:47:13,146
than you want, and once you
start having to write code

1145
00:47:13,466 --> 00:47:15,966
to talk to your Nib files and
whatnot, at that point a lot

1146
00:47:15,966 --> 00:47:18,006
of people feel, oh, I'll
just do it all from scratch.

1147
00:47:18,326 --> 00:47:20,856
And so that's why we just
saw in the Master View,

1148
00:47:20,856 --> 00:47:23,586
the Master Detail Application,
the master was all code,

1149
00:47:23,756 --> 00:47:25,456
even though the detail
used a bit of wiring,

1150
00:47:25,746 --> 00:47:28,126
and the no Nib example last
week was just all code.

1151
00:47:28,376 --> 00:47:30,566
So it's just a trade-off,
and a lot of people,

1152
00:47:30,626 --> 00:47:33,216
seasoned iOS developers tend
to prefer just doing things

1153
00:47:33,216 --> 00:47:35,376
from scratch, and of
course if you're bored

1154
00:47:35,596 --> 00:47:38,256
with IOS's built-in UI in
aesthetics, you have to do it

1155
00:47:38,296 --> 00:47:40,136
from scratch if you want
to layer things on top.

1156
00:47:40,786 --> 00:47:41,816
Good question.

1157
00:47:42,506 --> 00:47:43,156
All right.

1158
00:47:43,366 --> 00:47:46,286
So let's start something
truly from scratch now,

1159
00:47:46,556 --> 00:47:49,776
and based on time, we can pull a
pre-baked cake out of the oven,

1160
00:47:49,776 --> 00:47:52,286
namely implementing an
automated teller machine.

1161
00:47:52,286 --> 00:47:55,366
So a cash machine, a bank
machine, that simulates the idea

1162
00:47:55,366 --> 00:47:57,646
of depositing money
into a bank account

1163
00:47:57,766 --> 00:47:59,316
and actually doing
some math to keep track

1164
00:47:59,316 --> 00:48:00,596
of the total account balance.

1165
00:48:00,886 --> 00:48:03,426
So let me go ahead and
create a new project.

1166
00:48:03,426 --> 00:48:05,676
We'll do this as a Single
View application just

1167
00:48:05,676 --> 00:48:08,816
to keep the focus now on the
logic and less on details

1168
00:48:08,916 --> 00:48:11,946
like the transitions
between scenes,

1169
00:48:12,256 --> 00:48:13,506
and let's go ahead and start.

1170
00:48:13,646 --> 00:48:14,796
I'll call this ATM.

1171
00:48:14,796 --> 00:48:16,536
I'm not going to
use Storyboards.

1172
00:48:16,536 --> 00:48:18,936
I'm going to use the
lower-level Nib approach,

1173
00:48:18,936 --> 00:48:20,486
especially since we
only need one anyway.

1174
00:48:20,486 --> 00:48:23,386
I'm going to go ahead and click
next, save it on my desktop,

1175
00:48:23,956 --> 00:48:27,186
and now I get our standard
files over here on the top left.

1176
00:48:27,186 --> 00:48:28,626
We could tell the
story as before,

1177
00:48:28,626 --> 00:48:30,116
but it's probably getting
a little bit redundant now.

1178
00:48:30,116 --> 00:48:32,786
Main.M somehow invokes
the AppDelegate,

1179
00:48:32,786 --> 00:48:35,016
somehow invokes the
ViewController and the UI

1180
00:48:35,016 --> 00:48:36,846
for the ViewController
comes from the Nib.

1181
00:48:37,146 --> 00:48:38,966
So let's go ahead and
create a little bit

1182
00:48:38,966 --> 00:48:42,106
of an interface here for my ATM.

1183
00:48:42,226 --> 00:48:44,686
So I'm going to go ahead and
make my whole background white,

1184
00:48:44,686 --> 00:48:46,936
just because, and
then, let's see.

1185
00:48:47,066 --> 00:48:50,426
I want my ATM to look more
like maybe a calculator

1186
00:48:50,426 --> 00:48:52,856
with a total input
field up here,

1187
00:48:53,016 --> 00:48:55,016
maybe a total account
balance down here,

1188
00:48:55,016 --> 00:48:56,246
and then a whole
bunch of numbers.

1189
00:48:56,616 --> 00:48:57,956
So let's start to wire this up.

1190
00:48:57,956 --> 00:49:01,956
I'm going to go ahead and
have a UILabel up top here.

1191
00:49:01,956 --> 00:49:07,476
I'm going to drag it to be as
wide as I -- as is recommended.

1192
00:49:07,476 --> 00:49:12,446
Let me go ahead and increase
that font size to make it,

1193
00:49:12,576 --> 00:49:15,196
oh, let's say 36, okay.

1194
00:49:15,196 --> 00:49:16,836
Now we'll go ahead and
make it a little bigger.

1195
00:49:18,046 --> 00:49:21,656
And now let me go ahead
and do another label that's

1196
00:49:21,656 --> 00:49:23,086
down here toward the bottom.

1197
00:49:23,456 --> 00:49:25,286
This is going to be my --
actually, let's just copy

1198
00:49:25,286 --> 00:49:27,936
and paste this so we get the
same font size more quickly.

1199
00:49:28,576 --> 00:49:29,866
I'm going to go down here.

1200
00:49:29,866 --> 00:49:32,136
This will be my balance.

1201
00:49:32,806 --> 00:49:33,336
All right.

1202
00:49:33,336 --> 00:49:36,006
So now I need a whole bunch of
buttons to represent this thing.

1203
00:49:36,276 --> 00:49:38,426
So I'm going to go into my
rounded rec'd [assumed spelling]

1204
00:49:38,426 --> 00:49:40,566
button here, and let's see.

1205
00:49:40,566 --> 00:49:44,616
This will be the number,
let's see, let's go ahead

1206
00:49:44,616 --> 00:49:46,766
and match this lest
we get it backwards.

1207
00:49:47,666 --> 00:49:51,886
Let's go in, to save time,
to the ATM, Xcode Project,

1208
00:49:52,386 --> 00:49:54,986
and dot dot dot so that we
don't spend all day dragging

1209
00:49:54,986 --> 00:49:55,726
and dropping.

1210
00:49:56,076 --> 00:49:58,416
Voila. Now I have
this interface.

1211
00:49:58,516 --> 00:49:59,976
So what's now on this screen?

1212
00:50:00,066 --> 00:50:02,786
Well, I write a line of the
text, so just by clicking

1213
00:50:02,786 --> 00:50:03,966
in the Attributes Inspector.

1214
00:50:04,236 --> 00:50:07,686
I centered this field here and
I added another UILabel just

1215
00:50:07,686 --> 00:50:09,386
to stay balanced, just
for user interface.

1216
00:50:09,386 --> 00:50:12,226
So there's one label,
two labels, three labels.

1217
00:50:12,226 --> 00:50:14,286
So these aren't input
text fields per se,

1218
00:50:14,286 --> 00:50:15,696
but they're sort
of output displays.

1219
00:50:15,696 --> 00:50:18,706
So in my code, I can display
what the user's typing here,

1220
00:50:18,926 --> 00:50:22,876
and I can display what the user
has in their account down here.

1221
00:50:23,196 --> 00:50:25,386
All right, so what
might I want to do next?

1222
00:50:25,386 --> 00:50:27,696
Well, the goal is I want the
user to be able to type in,

1223
00:50:27,696 --> 00:50:31,936
like, five, zero, deposit, in
order to deposit $50 in his

1224
00:50:31,936 --> 00:50:34,256
or her account, and then I
want to see 50 down here.

1225
00:50:34,256 --> 00:50:37,346
And then if I then do
10, one, zero, deposit,

1226
00:50:37,346 --> 00:50:40,786
I want to see a total account
balance of 60 down here.

1227
00:50:40,786 --> 00:50:43,736
So we need somehow -- we somehow
need to represent a few things

1228
00:50:43,736 --> 00:50:44,536
that are going on here.

1229
00:50:44,536 --> 00:50:47,546
One, all of these buttons
need to be somehow connected

1230
00:50:47,546 --> 00:50:50,206
to my code so that when
I push the number five,

1231
00:50:50,496 --> 00:50:53,196
and then the number zero,
a couple of things happen.

1232
00:50:53,196 --> 00:50:57,556
One, those numbers get saved in
RAM somewhere; two, they display

1233
00:50:57,556 --> 00:51:00,286
like a calculator would,
five, zero, up here,

1234
00:51:00,426 --> 00:51:03,096
so I somehow need my code
to talk to my interface

1235
00:51:03,096 --> 00:51:04,556
which is going to
require a IB...

1236
00:51:04,556 --> 00:51:04,706
>> Action?

1237
00:51:05,096 --> 00:51:12,826
>> In this case, if I want
my code to talk to the UI

1238
00:51:12,826 --> 00:51:16,476
and IBOutlet, in that
direction, by contrast,

1239
00:51:16,476 --> 00:51:20,696
when I push a button, I want to
trigger an IBAction to my code.

1240
00:51:20,696 --> 00:51:22,856
So I have some blue lines
going in both directions,

1241
00:51:22,856 --> 00:51:25,076
or we can do it purely
in code, as we've seen,

1242
00:51:25,076 --> 00:51:27,576
and then I have two special
buttons: deposit, of course,

1243
00:51:27,866 --> 00:51:29,526
and then the clear button.

1244
00:51:29,846 --> 00:51:33,426
So before we get there, I'm
going to go ahead and propose,

1245
00:51:33,426 --> 00:51:34,626
let me roll back in time,

1246
00:51:34,626 --> 00:51:36,256
so here's where we
were a moment ago.

1247
00:51:36,256 --> 00:51:39,436
And let's assume that we're
seeing now the cake being made

1248
00:51:39,436 --> 00:51:41,566
and then finally we'll
skip to the ending here.

1249
00:51:41,866 --> 00:51:44,426
So as we're making this thing,
I've realized in the top left

1250
00:51:44,796 --> 00:51:48,366
that this is an opportunity
to have a model, the M in MVC,

1251
00:51:48,626 --> 00:51:50,706
because this is like
a mechanical machine,

1252
00:51:50,706 --> 00:51:52,426
or a digital machine,
that somehow has

1253
00:51:52,426 --> 00:51:53,896
to store account balances.

1254
00:51:54,166 --> 00:51:56,686
So what might I want to
model in this program?

1255
00:51:56,956 --> 00:51:58,206
Well, maybe the notion
of an account.

1256
00:51:58,646 --> 00:52:00,376
In fact, an account,
like a bank account,

1257
00:52:00,376 --> 00:52:04,646
could be modeled pretty well as
an object or an instantiation

1258
00:52:04,646 --> 00:52:07,716
of some class, and inside of
an account is going to be one

1259
00:52:07,716 --> 00:52:08,656
or more pieces of data.

1260
00:52:08,656 --> 00:52:09,786
And the only one
I'm going to care

1261
00:52:09,786 --> 00:52:12,266
about for now is
the account balance.

1262
00:52:12,726 --> 00:52:15,676
So in order to do this, I'm
going to go up to an option

1263
00:52:15,676 --> 00:52:17,686
that we probably haven't used
but it's pretty straightforward.

1264
00:52:17,686 --> 00:52:21,956
File New file, so not a new
project, just create a new file.

1265
00:52:22,176 --> 00:52:24,366
And you'll see an interface
that looks a little overwhelming

1266
00:52:24,366 --> 00:52:26,566
at first because
there's a lot of options,

1267
00:52:26,806 --> 00:52:28,406
but really they're just
different templates

1268
00:52:28,406 --> 00:52:29,906
by which to start a new file.

1269
00:52:30,046 --> 00:52:32,146
And all I'm going to want
is an Objective-C Class.

1270
00:52:32,146 --> 00:52:34,936
So I'm going to go ahead and
click next, and I'm going

1271
00:52:34,936 --> 00:52:36,396
to call this thing account.

1272
00:52:36,716 --> 00:52:39,506
It's asking me what does --
what should it be a subclass of.

1273
00:52:39,506 --> 00:52:40,256
NS Object is fine.

1274
00:52:40,256 --> 00:52:41,116
Every other thing --

1275
00:52:41,116 --> 00:52:42,896
most everything descends
from NS Object,

1276
00:52:43,166 --> 00:52:44,666
so that's fine for my purposes.

1277
00:52:44,666 --> 00:52:47,436
I'm going to go ahead and
click next, going to go ahead

1278
00:52:47,436 --> 00:52:51,756
and click create, and voila,
at the top left of my file,

1279
00:52:51,986 --> 00:52:55,736
I now have the ability to
represent an account object.

1280
00:52:55,736 --> 00:52:57,156
So let's see what
I've gotten for free.

1281
00:52:57,436 --> 00:53:01,696
In Account.H, I have interface,
account descends from NS Object,

1282
00:53:02,256 --> 00:53:05,766
and in Account.M, I just
have a blank implementation.

1283
00:53:06,056 --> 00:53:08,286
So now I have an opportunity,
again for the first time,

1284
00:53:08,286 --> 00:53:10,916
to implement some notion
of an account balance.

1285
00:53:10,916 --> 00:53:12,266
And I'm going to
propose the following.

1286
00:53:12,516 --> 00:53:16,646
In my.H file, I'm going to
propose a property that's going

1287
00:53:16,646 --> 00:53:19,866
to have, let's say, a sign,
we'll come back to that

1288
00:53:19,866 --> 00:53:22,896
in a moment, non-atomic
attributes.

1289
00:53:22,896 --> 00:53:25,546
I'm going to propose
that this be an unsigned,

1290
00:53:25,726 --> 00:53:27,846
long, long balance.

1291
00:53:28,406 --> 00:53:30,186
So a couple details
pop out here.

1292
00:53:30,186 --> 00:53:33,616
So one unsigned,
just to be clear,

1293
00:53:33,616 --> 00:53:38,406
means that the value
can only be...

1294
00:53:38,406 --> 00:53:38,546
>> [Inaudible audience
response].

1295
00:53:38,546 --> 00:53:40,966
>> Nonnegative, so
it can include zeros,

1296
00:53:40,966 --> 00:53:42,256
so that's what unsigned
would mean.

1297
00:53:42,496 --> 00:53:43,806
So long, long?

1298
00:53:44,036 --> 00:53:44,446
What's that?

1299
00:53:44,446 --> 00:53:45,406
What's the role there?

1300
00:53:45,406 --> 00:53:45,473
>> [Inaudible audience
response].

1301
00:53:45,473 --> 00:53:52,156
>> We want it to be 64-bit, so
in this platform doing a long,

1302
00:53:52,156 --> 00:53:54,486
long gets me a 64-bit number,

1303
00:53:54,486 --> 00:53:56,066
and that just means
it's pretty darn big.

1304
00:53:56,066 --> 00:53:58,656
I want to avoid what's generally
called Integer Overflow,

1305
00:53:58,876 --> 00:54:01,916
whereby if we type in too big
of a number, I don't want it

1306
00:54:01,916 --> 00:54:04,466
to roll over with this
high probability just some

1307
00:54:04,466 --> 00:54:05,156
random number.

1308
00:54:05,156 --> 00:54:06,866
It turns out this is
not an adequate defense.

1309
00:54:06,866 --> 00:54:09,386
We can still break this ATM
and deposit an arbitrary amount

1310
00:54:09,386 --> 00:54:12,156
of money in our account pretty
easily, but we'll see how to --

1311
00:54:12,276 --> 00:54:14,266
we'll simulate that in a bit.

1312
00:54:14,506 --> 00:54:16,796
Non-atomic, this just has
to do with multi-threading.

1313
00:54:16,796 --> 00:54:18,086
I'm writing very
simple code here.

1314
00:54:18,086 --> 00:54:19,286
There's not going to
be two threads trying

1315
00:54:19,286 --> 00:54:21,666
to touch the account at once,
though there could be certainly

1316
00:54:21,666 --> 00:54:23,626
in a world with multiple
ATM's on a network.

1317
00:54:23,766 --> 00:54:24,826
But we'll keep it simpler.

1318
00:54:25,056 --> 00:54:27,206
And a sign now is different.

1319
00:54:27,206 --> 00:54:29,726
Typically we've seen what
attribute in lines like this?

1320
00:54:30,746 --> 00:54:30,836
Yeah.

1321
00:54:31,326 --> 00:54:31,566
>> Copy.

1322
00:54:32,136 --> 00:54:35,646
>> So, okay, we've seen copy,
but more commonly thus far

1323
00:54:35,646 --> 00:54:39,476
in our examples, we've seen
strong, or weak, in this case.

1324
00:54:39,476 --> 00:54:43,166
So a sign literally
does just that.

1325
00:54:43,166 --> 00:54:45,966
It gives me a setter that
literally moves a value

1326
00:54:45,966 --> 00:54:47,756
from the right-hand
side of an expression

1327
00:54:47,756 --> 00:54:49,256
to the left-hand side.

1328
00:54:49,256 --> 00:54:51,416
There's no checking
for duplicate values;

1329
00:54:51,696 --> 00:54:54,006
there's no deep copying
of objects.

1330
00:54:54,006 --> 00:54:55,186
And this is perfectly fine

1331
00:54:55,186 --> 00:54:57,606
for what's generally called the
Primitive, like a long, long.

1332
00:54:57,606 --> 00:54:59,486
A long, long is just 64 bits.

1333
00:54:59,566 --> 00:55:02,346
To copy 64 bits, you just assign
it from the right to the left

1334
00:55:02,346 --> 00:55:04,096
with an equals sign in between.

1335
00:55:04,436 --> 00:55:07,066
So there's no need for strong
or weak, which have to do

1336
00:55:07,066 --> 00:55:08,566
with objects and pointers.

1337
00:55:08,856 --> 00:55:11,306
A copy also has to do
with objects and pointers.

1338
00:55:11,306 --> 00:55:14,216
Assign is just for Primitive, so
that's all I've specified here.

1339
00:55:14,806 --> 00:55:17,486
Okay? And by default, is this
read write, or read only?

1340
00:55:18,046 --> 00:55:20,386
>> Read write.

1341
00:55:20,456 --> 00:55:22,466
>> It's read write, which
means I get a setter

1342
00:55:22,466 --> 00:55:24,136
and a getter automatically

1343
00:55:24,206 --> 00:55:25,756
by having declared
this property here.

1344
00:55:26,016 --> 00:55:27,686
Okay, so we're going to
keep the account simple.

1345
00:55:27,686 --> 00:55:29,096
We're not going to bother
with account numbers

1346
00:55:29,096 --> 00:55:30,546
or names or any of that.

1347
00:55:30,656 --> 00:55:31,866
We're just going
to keep it simple

1348
00:55:31,866 --> 00:55:35,806
with our placeholder there,
and now in my implementation

1349
00:55:35,806 --> 00:55:39,196
of this object, I might
want to do one thing.

1350
00:55:39,196 --> 00:55:41,596
So it turns out an
NS Object, recall,

1351
00:55:41,906 --> 00:55:44,556
comes with some default
functionality in the form of an

1352
00:55:44,556 --> 00:55:47,176
In It Method, and that
In It Method is defined

1353
00:55:47,176 --> 00:55:49,996
in the NS Object class.

1354
00:55:49,996 --> 00:55:52,666
And typically that method
does nothing by default,

1355
00:55:52,666 --> 00:55:54,426
but it's an opportunity
for us to do something.

1356
00:55:54,746 --> 00:55:57,856
What might you want to do
in the way of initialization

1357
00:55:57,856 --> 00:56:00,226
when you instantiate an account
object for the first time?

1358
00:56:00,226 --> 00:56:02,836
>> Set an initial balance?

1359
00:56:02,956 --> 00:56:04,776
>> Yeah, so why don't we
set an initial balance.

1360
00:56:05,006 --> 00:56:07,246
So the signature
for an In It Method,

1361
00:56:07,246 --> 00:56:09,756
if you look at the
documentations for NS Object,

1362
00:56:09,756 --> 00:56:12,876
or just in general, the
convention in iOS is --

1363
00:56:12,876 --> 00:56:16,346
or an object of C, is to
have an instance method,

1364
00:56:16,446 --> 00:56:19,996
hence the hyphen, returns an
ID, which is a pointer or nil,

1365
00:56:19,996 --> 00:56:22,076
and it's called In
It, by convention.

1366
00:56:22,076 --> 00:56:24,806
So it's kind of like --
it's the initialization half

1367
00:56:24,806 --> 00:56:25,626
of a constructor.

1368
00:56:25,926 --> 00:56:27,556
An Alloc would be
the other half.

1369
00:56:27,556 --> 00:56:32,166
Again a common paradigm is to
say Now This If Self Gets Super

1370
00:56:32,216 --> 00:56:35,766
In It, so this is just a
common way of saying, one,

1371
00:56:36,086 --> 00:56:38,566
call the parent classes
implementation of In It;

1372
00:56:38,756 --> 00:56:40,906
make sure that it
doesn't return nil,

1373
00:56:40,906 --> 00:56:42,926
because if it does return
nil, I don't want it

1374
00:56:42,926 --> 00:56:44,916
to start doing work
unnecessarily lest I

1375
00:56:44,916 --> 00:56:45,796
create problems.

1376
00:56:46,046 --> 00:56:48,046
And now if all is well,

1377
00:56:48,046 --> 00:56:51,726
I'm going to do Self.Balance
gets zero,

1378
00:56:52,206 --> 00:56:54,766
and then I need to
return myself.

1379
00:56:56,006 --> 00:56:56,696
So that's it.

1380
00:56:56,796 --> 00:56:58,236
If I deleted all of this,

1381
00:56:58,406 --> 00:57:01,856
we wouldn't be initializing
the Primitive to a known value,

1382
00:57:02,166 --> 00:57:04,236
so this way, we have
a default value

1383
00:57:04,236 --> 00:57:05,246
or we could be nice, right?

1384
00:57:05,246 --> 00:57:06,016
If the first time you sign

1385
00:57:06,016 --> 00:57:07,556
up for a bank account
you get some free gift,

1386
00:57:07,556 --> 00:57:09,496
maybe you get $00
in your account,

1387
00:57:09,496 --> 00:57:10,756
and we could do that right here.

1388
00:57:10,916 --> 00:57:11,186
Yes.

1389
00:57:11,406 --> 00:57:14,976
>> Why do you have to do
super Alloc and In It?

1390
00:57:14,976 --> 00:57:19,656
>> Super Alloc and In -- because
that would be bad, because when

1391
00:57:19,656 --> 00:57:22,456
In It is called, Alloc
has already been called.

1392
00:57:22,976 --> 00:57:25,086
So the convention is
call Alloc, then In It,

1393
00:57:25,206 --> 00:57:28,476
so if In It called Alloc,
that would be trying

1394
00:57:28,476 --> 00:57:29,796
to instantiate the object twice.

1395
00:57:30,436 --> 00:57:33,586
Good question.

1396
00:57:34,226 --> 00:57:34,596
All right.

1397
00:57:34,826 --> 00:57:35,766
So that's it.

1398
00:57:35,766 --> 00:57:40,326
This is a super, super
simple model, if you will,

1399
00:57:40,326 --> 00:57:41,756
but it's representative
of how we could go

1400
00:57:41,756 --> 00:57:43,066
about encapsulating information.

1401
00:57:43,066 --> 00:57:45,476
It may be in a fancier world,
this information would come

1402
00:57:45,476 --> 00:57:48,266
from a database, and if it did,
it could go in this model code.

1403
00:57:48,266 --> 00:57:50,266
But we're going to
just as an abstraction

1404
00:57:50,266 --> 00:57:52,676
for what an actual
account balance is.

1405
00:57:53,016 --> 00:57:54,396
So now, what more
do we have to do?

1406
00:57:54,396 --> 00:57:56,586
Well, let me jump back
to the pre-baked version

1407
00:57:56,586 --> 00:57:57,656
that looks now like this.

1408
00:57:58,016 --> 00:58:00,586
Notice that at top left I
have the exact same code

1409
00:58:00,586 --> 00:58:01,516
that I wrote in advance.

1410
00:58:01,516 --> 00:58:02,896
I have a property
called balance,

1411
00:58:03,106 --> 00:58:04,546
and I have an implementation
of In It.

1412
00:58:04,986 --> 00:58:07,346
So if we go back to the
Nib, I also did a few things

1413
00:58:07,346 --> 00:58:10,086
in advance consistent with
what we said was necessary.

1414
00:58:10,086 --> 00:58:16,176
One, I wired all of the
buttons to my code u IBActions,

1415
00:58:16,696 --> 00:58:21,246
and I wired my code to two
different UILabels via IB...

1416
00:58:21,746 --> 00:58:21,946
>> Outlets.

1417
00:58:22,506 --> 00:58:22,926
>> Outlets.

1418
00:58:22,926 --> 00:58:24,386
So two directions.

1419
00:58:24,386 --> 00:58:26,836
Now how can I check what
directions they went in?

1420
00:58:26,836 --> 00:58:28,536
Well, let me go ahead and
choose the number seven,

1421
00:58:28,816 --> 00:58:32,656
and notice that if I hold
control and click on there,

1422
00:58:32,946 --> 00:58:35,016
there's a whole bunch
in this drop-down,

1423
00:58:35,016 --> 00:58:37,276
but the interesting one,
recall from last week,

1424
00:58:37,276 --> 00:58:40,396
is Touch-Up Inside, that's
this act, and the result

1425
00:58:40,396 --> 00:58:41,826
of that is to do what?

1426
00:58:41,886 --> 00:58:42,976
Files Owner Digit?

1427
00:58:42,976 --> 00:58:45,446
What could that mean?

1428
00:58:45,446 --> 00:58:45,626
>> [Inaudible audience
response].

1429
00:58:45,626 --> 00:58:47,756
>> Call a method called
Digit on what object?

1430
00:58:48,286 --> 00:58:48,916
>> File's owner.

1431
00:58:48,916 --> 00:58:51,086
>> On the file's owner, which
in this case is going to be?

1432
00:58:51,086 --> 00:58:51,416
>> ViewController.

1433
00:58:52,446 --> 00:58:53,426
>> ViewController.

1434
00:58:53,426 --> 00:58:56,256
Exactly. So I'm in the
ViewController, class is Nib,

1435
00:58:56,256 --> 00:58:58,906
and the file's owner is
going to be the .M file,

1436
00:58:58,906 --> 00:59:02,616
so let's take a look at the
.M file and indeed, there is,

1437
00:59:02,616 --> 00:59:06,306
nested among a few other
methods, a method called Digit.

1438
00:59:06,616 --> 00:59:08,426
So I've declared this
as an Instance Method.

1439
00:59:08,826 --> 00:59:11,486
It returns an IBAction
by convention,

1440
00:59:11,486 --> 00:59:13,216
which is just synonymous with?

1441
00:59:14,446 --> 00:59:16,206
Remember your lower
level C details?

1442
00:59:17,356 --> 00:59:17,956
Just void.

1443
00:59:18,186 --> 00:59:20,166
Just returns void, which
means it returns nothing,

1444
00:59:20,406 --> 00:59:22,986
and it takes a pointer
called sender,

1445
00:59:23,036 --> 00:59:24,736
and what is that going
to be a pointer to?

1446
00:59:24,736 --> 00:59:26,396
>> The button that was pressed?

1447
00:59:26,556 --> 00:59:27,516
>> The button that was pressed.

1448
00:59:27,516 --> 00:59:28,246
So this is my way

1449
00:59:28,246 --> 00:59:31,116
of programmatically knowing what
button was actually pressed.

1450
00:59:31,426 --> 00:59:34,306
So here's a -- a bit of a
trick that we've leveraged

1451
00:59:34,306 --> 00:59:35,846
with the UIView class.

1452
00:59:36,086 --> 00:59:39,496
Notice in this first line of
code, I'm doing the following.

1453
00:59:39,976 --> 00:59:43,346
On the left-hand side,
I instantiate what?

1454
00:59:43,346 --> 00:59:46,186
>> Pointer to a UI Button?

1455
00:59:46,306 --> 00:59:48,806
>> Good. Pointer to a UI Button,
and I keep asking this question

1456
00:59:48,806 --> 00:59:51,536
so that the answer is
not allocate a UI Button,

1457
00:59:51,536 --> 00:59:52,206
which is not the case.

1458
00:59:52,206 --> 00:59:54,356
I've allocated a
pointer to a UI Button.

1459
00:59:54,626 --> 00:59:56,286
On the right-hand
side, what have I done?

1460
00:59:57,436 --> 00:59:59,956
>> Casting the center
variable to a UI button...

1461
01:00:00,126 --> 01:00:00,716
>> Casting.

1462
01:00:00,716 --> 01:00:01,346
>> ...per style

1463
01:00:01,606 --> 01:00:02,236
>> Exactly.

1464
01:00:02,236 --> 01:00:05,736
So this is a C-Style cast
whereby senders type?

1465
01:00:05,736 --> 01:00:08,896
I don't really know because
I declared it as an argument

1466
01:00:09,006 --> 01:00:12,526
of a type ID, I don't actually
really know what its type is,

1467
01:00:12,736 --> 01:00:16,136
so therefore I don't necessarily
know what methods I can call

1468
01:00:16,136 --> 01:00:19,226
on it, and therefore Xcode
doesn't know whether or not

1469
01:00:19,226 --> 01:00:22,226
to yell at me if I try calling a
method maybe that doesn't exist.

1470
01:00:22,566 --> 01:00:25,186
It's okay to send
messages to objects even

1471
01:00:25,186 --> 01:00:27,306
if they don't respond to
them, but if I really want

1472
01:00:27,306 --> 01:00:31,476
to leverage my compiler in my ID
here, it's nice if they can yell

1473
01:00:31,476 --> 01:00:34,296
at me when I'm do stupid
things, so I can explicitly say

1474
01:00:34,296 --> 01:00:37,356
that sender is of type UI Button
so that now, anything I do

1475
01:00:37,356 --> 01:00:40,646
with B will be known by Xcode
as referring to a button.

1476
01:00:41,356 --> 01:00:41,456
Yeah.

1477
01:00:41,816 --> 01:00:43,006
>> Is there a difference
doing in-line?

1478
01:00:43,006 --> 01:00:51,016
Like where you use [inaudible],
cast B to the sender

1479
01:00:51,336 --> 01:00:51,726
to [inaudible] up there?

1480
01:00:51,896 --> 01:00:52,616
>> Good question.

1481
01:00:52,616 --> 01:00:54,006
That would be perfectly fine.

1482
01:00:54,006 --> 01:00:58,646
You could do this, let me scroll
over, your code just starts

1483
01:00:58,646 --> 01:01:01,026
to look a little less readable,
but that's perfectly fine,

1484
01:01:01,026 --> 01:01:02,426
and there's another
way we could do this.

1485
01:01:02,616 --> 01:01:05,276
We don't strictly have
to say ID up here.

1486
01:01:05,276 --> 01:01:08,176
We could do this and then
eliminate this line altogether

1487
01:01:08,176 --> 01:01:09,316
and just refer to sender,

1488
01:01:09,496 --> 01:01:11,856
and the only reason I left
it this way is really just

1489
01:01:11,906 --> 01:01:13,116
by convention.

1490
01:01:13,436 --> 01:01:18,266
Typically Apple always says ID
as the type of the arguments,

1491
01:01:18,326 --> 01:01:21,366
and then casts it explicitly,
but functionally it's the same.

1492
01:01:21,786 --> 01:01:22,866
The compiler won't yell at you.

1493
01:01:23,366 --> 01:01:28,446
Okay. So here now is a little
grade school arithmetic that's

1494
01:01:28,446 --> 01:01:29,876
finally coming back
to be useful.

1495
01:01:30,556 --> 01:01:32,666
Why does this line work?

1496
01:01:32,666 --> 01:01:35,276
Well, Self.Amount is
referring to what?

1497
01:01:35,276 --> 01:01:37,326
I actually don't
know what amount is.

1498
01:01:37,436 --> 01:01:39,066
So what is Self in this context?

1499
01:01:39,436 --> 01:01:40,596
What class are we inside of?

1500
01:01:42,046 --> 01:01:43,526
>> ViewController.

1501
01:01:43,596 --> 01:01:44,886
>> So this is the
ViewController.

1502
01:01:44,886 --> 01:01:47,726
See I got out of sync here
with my order of operations.

1503
01:01:47,726 --> 01:01:49,726
Let me go to the .H
file and it looks

1504
01:01:49,726 --> 01:01:50,796
like there's a few
things in here.

1505
01:01:50,796 --> 01:01:52,966
So let's actually pause for a
moment and look at what's inside

1506
01:01:52,966 --> 01:01:54,476
of this particular
ViewController.

1507
01:01:54,816 --> 01:01:57,966
So I have a property
that's called account,

1508
01:01:58,386 --> 01:01:59,956
and it points to
an account object.

1509
01:01:59,956 --> 01:02:01,236
Okay so there's my bank account.

1510
01:02:01,376 --> 01:02:05,706
There is my Controller
linking to my M in MVC model.

1511
01:02:05,876 --> 01:02:08,416
So we saw that arrow promised
in the picture earlier.

1512
01:02:08,776 --> 01:02:09,666
What's next?

1513
01:02:09,666 --> 01:02:10,626
A long, long amount.

1514
01:02:10,906 --> 01:02:13,166
I am not sure why
there's an amount there,

1515
01:02:13,166 --> 01:02:14,086
so we'll come back to that.

1516
01:02:14,086 --> 01:02:15,616
There seems to be
some duplication here

1517
01:02:15,616 --> 01:02:17,196
for some reason, but
we'll come back to that.

1518
01:02:17,466 --> 01:02:19,876
And then here's the
IBOutlet and the IBAction

1519
01:02:19,876 --> 01:02:20,836
that I mentioned earlier.

1520
01:02:20,836 --> 01:02:23,376
I apparently called it
Balance Label, for the balance

1521
01:02:23,376 --> 01:02:25,266
at the bottom and Deposit Label

1522
01:02:25,356 --> 01:02:27,726
for the current number
I'm typing in at the top,

1523
01:02:27,726 --> 01:02:28,696
just like a calculator.

1524
01:02:29,046 --> 01:02:31,626
And then I have some
instance methods

1525
01:02:31,626 --> 01:02:32,916
that are declared down here.

1526
01:02:33,096 --> 01:02:34,666
As a spoiler, we're
looking at Digit,

1527
01:02:34,666 --> 01:02:35,766
and this is the method
that's going

1528
01:02:35,766 --> 01:02:37,836
to get invoked any time I
touch a digit, a number.

1529
01:02:38,406 --> 01:02:40,456
Deposit is when I hit
the green deposit button.

1530
01:02:40,686 --> 01:02:42,876
Clear is when I hit
the red clear button.

1531
01:02:43,106 --> 01:02:45,456
And show is just a
helper method I wrote

1532
01:02:45,456 --> 01:02:49,296
to keep my code organized and
centralize all of the View code,

1533
01:02:49,296 --> 01:02:50,176
as we'll see in a moment.

1534
01:02:50,626 --> 01:02:53,256
So account, to be
clear, is an account,

1535
01:02:53,406 --> 01:02:55,316
a pointer to an Account Object.

1536
01:02:55,316 --> 01:02:57,056
So now we go back
to the .M file,

1537
01:02:57,246 --> 01:02:59,096
and now in Digit,
what am I doing?

1538
01:02:59,546 --> 01:03:03,796
I'm storing Self.Amount, which
was another unsigned long, long,

1539
01:03:04,606 --> 01:03:07,136
and I'm assigning
it the return value

1540
01:03:07,136 --> 01:03:10,646
of Self.Amount times
10, plus B.Tag.

1541
01:03:10,646 --> 01:03:12,546
What do you think this is doing?

1542
01:03:12,946 --> 01:03:23,206
>> So amount just pulls
what's the current --

1543
01:03:23,206 --> 01:03:25,086
displayed right now.

1544
01:03:25,306 --> 01:03:25,536
>> Good.

1545
01:03:25,796 --> 01:03:31,386
>> So every time you click a
button, you want to multiply it

1546
01:03:31,386 --> 01:03:34,846
by 10 because every
time you click a button,

1547
01:03:34,886 --> 01:03:36,966
then you're shooting
the digits over.

1548
01:03:36,966 --> 01:03:37,396
>> Exactly.

1549
01:03:37,396 --> 01:03:39,126
>> By one digit.

1550
01:03:39,126 --> 01:03:39,946
>> Exactly.

1551
01:03:39,946 --> 01:03:43,626
So when I referred to grade
school earlier, I just meant

1552
01:03:43,626 --> 01:03:46,736
to the process of every
time you multiply by ten,

1553
01:03:46,736 --> 01:03:48,286
it shifts the number
over to the left

1554
01:03:48,286 --> 01:03:52,006
and that's effectively
the behavior you want.

1555
01:03:52,006 --> 01:03:55,876
Every time you type in
an additional number,

1556
01:03:56,826 --> 01:03:59,596
you want to shift the
current numbers over

1557
01:03:59,596 --> 01:04:02,256
and put the new one there, and
you can do that arithmetically

1558
01:04:02,366 --> 01:04:05,986
by just doing multiply by
ten of the current value,

1559
01:04:05,986 --> 01:04:07,616
and then add in B.Tag.

1560
01:04:07,616 --> 01:04:08,146
So this is curious.

1561
01:04:08,146 --> 01:04:10,836
So B is a UI Button, a B
UI Button is a descendant

1562
01:04:10,836 --> 01:04:15,326
from a class called a
UIView, and it turns out,

1563
01:04:15,326 --> 01:04:17,196
if we read the documentation,

1564
01:04:17,196 --> 01:04:19,876
that a UIView has a property
called, take a guess?

1565
01:04:19,876 --> 01:04:20,256
>> Tag.

1566
01:04:20,546 --> 01:04:23,076
>> Tag, which is
just a number field.

1567
01:04:23,076 --> 01:04:26,256
It's an NS integer that you
can use for whatever you want.

1568
01:04:26,256 --> 01:04:28,886
So for simplicity, what
I decided to do here,

1569
01:04:28,886 --> 01:04:32,176
in my ViewController, is this.

1570
01:04:32,176 --> 01:04:36,976
Notice I've got the number
seven here selected arbitrarily,

1571
01:04:37,066 --> 01:04:41,206
but we can see it on the
other numbers as well.

1572
01:04:41,206 --> 01:04:45,936
If I go up to the
Attributes Inspector,

1573
01:04:45,936 --> 01:04:50,236
notice that the contents of this
button are the number seven,

1574
01:04:50,316 --> 01:04:52,576
but they could have been seven,

1575
01:04:52,666 --> 01:04:56,876
even though that would look a
little strange, but this is only

1576
01:04:57,146 --> 01:04:59,316
to say that this is
a string up here,

1577
01:04:59,316 --> 01:05:02,126
even though it looks
like a number.

1578
01:05:02,126 --> 01:05:04,026
So that's the label
of the button.

1579
01:05:04,026 --> 01:05:07,736
But if I scroll down, and scroll
down, notice that under View,

1580
01:05:07,736 --> 01:05:10,816
which is just Apples way
of categorizing attributes

1581
01:05:10,816 --> 01:05:13,226
that are specific
to UIView Objects,

1582
01:05:13,226 --> 01:05:15,766
what field does a UIView
apparently also have?

1583
01:05:15,766 --> 01:05:15,956
>> Tags.

1584
01:05:16,336 --> 01:05:16,836
>> It's a tag.

1585
01:05:16,836 --> 01:05:17,646
So tag, all lowercase.

1586
01:05:17,646 --> 01:05:20,586
This is just a property
in the UIView class.

1587
01:05:20,826 --> 01:05:23,246
That's a number that you can
use for whatever you want.

1588
01:05:23,246 --> 01:05:25,546
Typically, the cleanest way
to use this is with constants

1589
01:05:25,546 --> 01:05:28,446
that are defined elsewhere,
so that there's some kind

1590
01:05:28,446 --> 01:05:33,626
of programmatic mapping to the
values, but for simplicity,

1591
01:05:33,626 --> 01:05:36,366
because this is a very
simple application,

1592
01:05:36,366 --> 01:05:41,286
I decided to just go through
each of my buttons and because

1593
01:05:41,286 --> 01:05:44,886
by wonderful convenience --

1594
01:05:44,976 --> 01:05:47,686
coincidence, my buttons are
meant to represent numbers,

1595
01:05:47,686 --> 01:05:51,316
I decided to assign each a tag
that's identical to its label.

1596
01:05:51,316 --> 01:05:54,816
So I manually went in and
made seven equal to seven,

1597
01:05:54,816 --> 01:05:57,646
eight is equal to eight, and
notice that the number's going

1598
01:05:57,646 --> 01:06:00,466
to be changing there
at top right.

1599
01:06:00,466 --> 01:06:03,856
If I click on two, it's
two; zero, it's zero.

1600
01:06:03,856 --> 01:06:05,846
And then notice, deposit
and clear are also zero,

1601
01:06:05,846 --> 01:06:11,336
but that's not a problem because
I probably wired those guys

1602
01:06:11,336 --> 01:06:13,746
up to different methods
so I don't have to worry

1603
01:06:14,446 --> 01:06:16,676
about confusing one
zero for the other.

1604
01:06:16,726 --> 01:06:22,096
So if we go back to the button
seven and control click on it,

1605
01:06:22,136 --> 01:06:23,836
notice that it will
send the digit message

1606
01:06:23,836 --> 01:06:26,886
to file's owner whenever
it's pressed up inside.

1607
01:06:26,886 --> 01:06:30,436
That means that digit gets
called anytime I push a number,

1608
01:06:30,436 --> 01:06:38,996
and we saw on the .M file
that that induces a little bit

1609
01:06:38,996 --> 01:06:42,676
of arithmetic where I
multiply the current amount

1610
01:06:42,676 --> 01:06:44,556
in that top field by ten.

1611
01:06:44,556 --> 01:06:49,166
I then add B.tag to it, and then
I call my Helper Method show.

1612
01:06:49,166 --> 01:06:52,676
And show, this is not
something that comes up iOS.

1613
01:06:52,816 --> 01:06:54,706
I wrote it myself.

1614
01:06:54,706 --> 01:06:56,406
It was just my way

1615
01:06:56,406 --> 01:06:58,976
of centralizing all the code
related to updating the UI,

1616
01:06:59,056 --> 01:07:00,446
and it looks like this.

1617
01:07:00,446 --> 01:07:01,756
I have two lines of code,
even though they wrap,

1618
01:07:01,756 --> 01:07:05,076
and I'm setting my Self
Balance Label Property,

1619
01:07:05,076 --> 01:07:06,996
the text thereof, to the
result of calling NS strings,

1620
01:07:06,996 --> 01:07:09,446
String With Format
Convenience Method,

1621
01:07:10,646 --> 01:07:13,306
passing in this very
cryptic looking string,

1622
01:07:13,496 --> 01:07:23,746
Dollar Sign Percent L L U. What
in the world does that mean?

1623
01:07:23,846 --> 01:07:26,226
What does the dollar sign mean?

1624
01:07:26,366 --> 01:07:27,726
>> Is it a dollar sign?

1625
01:07:27,846 --> 01:07:30,156
>> It's a dollar sign.

1626
01:07:30,156 --> 01:07:30,936
Money. Okay?

1627
01:07:31,146 --> 01:07:36,076
So percent L L U is a
placeholder that represents?

1628
01:07:36,076 --> 01:07:37,526
>> Long, long unsigned value.

1629
01:07:37,526 --> 01:07:38,816
>> Exactly.

1630
01:07:38,816 --> 01:07:40,106
A long, long unsigned value.

1631
01:07:40,106 --> 01:07:41,766
So if you're familiar with C,

1632
01:07:41,766 --> 01:07:45,376
percent D is what you typically
use for a decimal number,

1633
01:07:45,506 --> 01:07:49,626
but in this case, we want
a long long and unsigned.

1634
01:07:49,626 --> 01:07:54,976
So cryptic, but it's perfect
for what we want for our long,

1635
01:07:55,186 --> 01:07:57,936
long -- our unsigned long, long.

1636
01:07:57,936 --> 01:08:05,226
What do I want to
paste into that value?

1637
01:08:05,226 --> 01:08:07,356
Comma Self.Account.Balance,

1638
01:08:07,356 --> 01:08:09,956
whose type is, again,
long, long.

1639
01:08:09,956 --> 01:08:11,586
So I called this a
Convenience Method.

1640
01:08:11,586 --> 01:08:15,516
In what sense is String With
Format a Convenience Method?

1641
01:08:15,516 --> 01:08:16,916
What type of Method
is String With Format,

1642
01:08:17,076 --> 01:08:18,776
apparently, based
on the snippet?

1643
01:08:18,776 --> 01:08:19,156
>> A Class Method?

1644
01:08:19,196 --> 01:08:19,566
>> A class method.

1645
01:08:19,566 --> 01:08:22,646
Class method because
we don't call Alloc.

1646
01:08:22,646 --> 01:08:27,766
You just call it directly so
it's a Convenience Method,

1647
01:08:27,766 --> 01:08:32,476
excuse me, in the sense that
you don't have to call Alloc,

1648
01:08:32,476 --> 01:08:36,216
you don't then have to call In
It and jump through these hoops.

1649
01:08:36,216 --> 01:08:37,746
You just call this method.

1650
01:08:37,746 --> 01:08:41,106
And again, and I think we
said this a couple weeks ago,

1651
01:08:41,106 --> 01:08:43,666
this is a very common
paradigm in iOS.

1652
01:08:43,666 --> 01:08:46,916
If you have a class called
NS String, or String,

1653
01:08:46,916 --> 01:08:48,926
having Convenience
Methods that start

1654
01:08:48,926 --> 01:08:52,116
with roughly the class name
and then With is a common way

1655
01:08:52,116 --> 01:08:55,646
of instantiating objects
without calling Alloc,

1656
01:08:55,646 --> 01:08:58,126
so common paradigm is all.

1657
01:08:58,126 --> 01:09:00,526
Lastly, the thing done
here is identical.

1658
01:09:00,526 --> 01:09:02,936
We're just doing the same
thing with the current amount.

1659
01:09:02,936 --> 01:09:04,406
So notice the dichotomy.

1660
01:09:04,406 --> 01:09:06,256
I've got two variables
called amount.

1661
01:09:06,256 --> 01:09:08,196
One is in my ViewController,
and where's the other?

1662
01:09:08,196 --> 01:09:08,263
>> [Inaudible audience
response].

1663
01:09:08,263 --> 01:09:10,326
>> In the Account Object,
and notice the distinction.

1664
01:09:10,326 --> 01:09:11,616
What's in my account is
what I've already deposited,

1665
01:09:11,646 --> 01:09:12,786
but what's in the other
variable called Amount,

1666
01:09:12,816 --> 01:09:14,286
which is in the ViewController,
is just storing what value?

1667
01:09:14,316 --> 01:09:15,006
>> What the user has typed in.

1668
01:09:15,036 --> 01:09:15,966
>> With the user has
typed in thus far.

1669
01:09:15,996 --> 01:09:16,686
So if we run this thing now,

1670
01:09:16,716 --> 01:09:17,946
even though we haven't seen
quite all of the pieces,

1671
01:09:17,976 --> 01:09:19,086
and we pull up the
actual user interface,

1672
01:09:19,116 --> 01:09:19,866
and I click the number seven,

1673
01:09:19,896 --> 01:09:20,736
that digit message
has been sent.

1674
01:09:20,766 --> 01:09:22,056
We have done the math of
multiplying zero by ten,

1675
01:09:22,086 --> 01:09:23,076
which is the default
value, plus seven,

1676
01:09:23,106 --> 01:09:23,916
and then I've called
the Show Method,

1677
01:09:23,946 --> 01:09:24,876
which updates the
value to be seven.

1678
01:09:24,906 --> 01:09:26,286
But only once I click
deposit here is the deposit

1679
01:09:26,316 --> 01:09:26,616
method called.

1680
01:09:26,646 --> 01:09:27,096
So let's check that.

1681
01:09:27,126 --> 01:09:28,716
If I go to the Nib, and I go
to control click on deposit,

1682
01:09:28,746 --> 01:09:30,096
scroll down here, touch up
inside is mapped to deposit,

1683
01:09:30,126 --> 01:09:31,326
so now, if I want to see
what the positive does,

1684
01:09:31,356 --> 01:09:32,196
if I go into my.M and scroll

1685
01:09:32,226 --> 01:09:33,006
down to here, that
is doing what?

1686
01:09:33,036 --> 01:09:34,236
Self.Account.Balance
Plus Equals Self Amount,

1687
01:09:34,266 --> 01:09:35,016
so it's adding what's actually

1688
01:09:35,046 --> 01:09:36,366
in the Controllers variable
to the ATMs variable.

1689
01:09:36,396 --> 01:09:37,596
What am I doing with
Self.Amount Equals Zero?

1690
01:09:37,626 --> 01:09:38,616
Well, I'm just clearing
my local value

1691
01:09:38,646 --> 01:09:39,906
and then I'm updating the
UI by calling Show again.

1692
01:09:39,936 --> 01:09:41,316
So this is actually a
really clean example of MVC

1693
01:09:41,346 --> 01:09:42,366
by keeping these barriers
between everything.

1694
01:09:42,396 --> 01:09:43,356
The Controller's
doing all of my logic

1695
01:09:43,386 --> 01:09:44,646
and my temporary
arithmetic, but once I'm ready

1696
01:09:44,676 --> 01:09:45,816
to make the deposit do
I talk to the model,

1697
01:09:45,846 --> 01:09:46,956
and only once I've done
that do I show things

1698
01:09:46,986 --> 01:09:48,186
by having the Controller
call on the View by way

1699
01:09:48,216 --> 01:09:48,876
of this method I called Show.

1700
01:09:48,906 --> 01:09:49,086
All right.

1701
01:09:49,116 --> 01:09:50,556
So which method is probably
going to be pretty similar?

1702
01:09:50,586 --> 01:09:51,606
Clear? If we look at
clear, super simple.

1703
01:09:51,636 --> 01:09:52,806
It's the result of having
wired things together,

1704
01:09:52,836 --> 01:09:54,036
but suppose I've screwed
up and I forgot to wire

1705
01:09:54,066 --> 01:09:55,116
up the Clear Method,
which I can simulate

1706
01:09:55,146 --> 01:09:55,746
by clicking the X there.

1707
01:09:55,776 --> 01:09:56,856
And so now the clear
button has no effect.

1708
01:09:56,886 --> 01:09:58,356
From what to what do I need
to click and drag in order

1709
01:09:58,386 --> 01:09:59,526
to reconstruct that
IBAction or IBOutlet?

1710
01:09:59,556 --> 01:09:59,976
First what is it?

1711
01:10:00,596 --> 01:10:00,916
>> IBAction?

1712
01:10:01,796 --> 01:10:02,766
>> IBAction?

1713
01:10:02,906 --> 01:10:06,476
What do I have to go -- do?

1714
01:10:06,476 --> 01:10:06,706
>> [Inaudible audience
response].

1715
01:10:06,706 --> 01:10:07,726
>> Click on the clear?

1716
01:10:07,726 --> 01:10:08,566
All right.

1717
01:10:08,566 --> 01:10:10,366
Holding control, go to where?

1718
01:10:10,606 --> 01:10:11,146
>> File's owner.

1719
01:10:11,396 --> 01:10:12,016
>> Files owner.

1720
01:10:12,016 --> 01:10:13,976
Let go. There I see
a list of all

1721
01:10:13,976 --> 01:10:15,316
of the methods that I can call.

1722
01:10:15,316 --> 01:10:17,266
The one that doesn't have a
hyphen means I just haven't

1723
01:10:17,266 --> 01:10:18,056
wired it up yet.

1724
01:10:18,166 --> 01:10:20,376
I'm going to go do that,
and now we've fixed it.

1725
01:10:20,376 --> 01:10:23,766
Conversely, if I screwed up
my label, which currently,

1726
01:10:23,996 --> 01:10:25,366
if I click on this with control,

1727
01:10:25,366 --> 01:10:28,286
is mapped to Deposit
Label, how do I fix this?

1728
01:10:28,466 --> 01:10:30,286
Well, I can control
click on my label,

1729
01:10:30,286 --> 01:10:32,596
go to files owner, and, hmm.

1730
01:10:34,936 --> 01:10:35,916
Just the other way.

1731
01:10:35,996 --> 01:10:38,496
So IBOutlets go from
files owner to deposit.

1732
01:10:38,736 --> 01:10:40,986
There it is, Deposit
Label, wire it up,

1733
01:10:40,986 --> 01:10:43,666
and now I've resurrected
the actual interface.

1734
01:10:44,986 --> 01:10:45,946
Any questions?

1735
01:10:48,156 --> 01:10:48,996
All right.

1736
01:10:49,346 --> 01:10:51,256
So let me propose with
this particular one,

1737
01:10:51,256 --> 01:10:53,376
especially when it comes time
to your native applications,

1738
01:10:53,376 --> 01:10:55,446
if you want to start with
something from scratch,

1739
01:10:55,836 --> 01:11:00,026
think about using that as the
beginnings of an application

1740
01:11:00,026 --> 01:11:03,186
because it draws these fairly
clear lines between MV and C,

1741
01:11:03,186 --> 01:11:06,306
which recall is just the picture
that we looked at earlier,

1742
01:11:06,776 --> 01:11:08,986
and as well, last week.

1743
01:11:09,846 --> 01:11:10,176
All right.

1744
01:11:10,336 --> 01:11:11,656
So let's forge ahead to
something's that going

1745
01:11:11,656 --> 01:11:13,216
to give us a new
capability altogether.

1746
01:11:13,216 --> 01:11:15,916
Rather than focus on reinforcing
some of the things we've done,

1747
01:11:16,206 --> 01:11:19,026
let's go ahead and
consider this.

1748
01:11:19,026 --> 01:11:22,386
It turns out that there's
a whole bunch of ways

1749
01:11:22,386 --> 01:11:24,886
that we can start
storing information.

1750
01:11:24,886 --> 01:11:29,956
To date, we have not stored
any information persistently

1751
01:11:30,166 --> 01:11:31,306
in a program that we've written.

1752
01:11:31,306 --> 01:11:32,666
Every time you quit
the application,

1753
01:11:32,666 --> 01:11:34,616
any things that you've
been storing in variables,

1754
01:11:34,616 --> 01:11:35,676
anything you've stored
in properties,

1755
01:11:35,676 --> 01:11:36,796
just disappears altogether.

1756
01:11:36,796 --> 01:11:39,286
But it turns out, in iOS we
can store things in a number

1757
01:11:39,286 --> 01:11:41,256
of formats, so we have
things call Property Lists,

1758
01:11:41,256 --> 01:11:42,706
which we've actually
encountered before.

1759
01:11:42,776 --> 01:11:45,866
Something called NS Defaults
or settings, SQL Light,

1760
01:11:45,866 --> 01:11:48,526
XML or json, even
something called Core Data,

1761
01:11:48,806 --> 01:11:49,706
so Property List.

1762
01:11:49,706 --> 01:11:50,766
We've seen those before.

1763
01:11:51,196 --> 01:11:53,246
What's a Property
List, or P List, file?

1764
01:11:53,926 --> 01:11:55,746
.P List? Yeah.

1765
01:11:56,106 --> 01:11:58,116
>> It's a dictionary of strings.

1766
01:11:58,446 --> 01:11:58,796
>> Exactly.

1767
01:11:58,796 --> 01:11:59,846
Is the dictionary of strings.

1768
01:11:59,846 --> 01:12:02,396
It's a file containing key
values pairs and we've seen this

1769
01:12:02,396 --> 01:12:05,876
in Xcode in the form of a
nice little pretty table form

1770
01:12:05,876 --> 01:12:07,596
with keys on the left
and values on the right,

1771
01:12:07,746 --> 01:12:09,006
but that's just the
user-friendly way

1772
01:12:09,006 --> 01:12:11,386
of showing you what's really
an XML file with data types

1773
01:12:11,416 --> 01:12:13,376
like strings and integers
underneath the hood.

1774
01:12:13,696 --> 01:12:17,476
But it's useful, and if you've
dived into Evil Hangman already,

1775
01:12:17,476 --> 01:12:20,306
you know that this is the format
in which we've provided you

1776
01:12:20,306 --> 01:12:21,996
with a whole bunch of words.

1777
01:12:21,996 --> 01:12:24,086
It happens to be an XML
file underneath the hood,

1778
01:12:24,296 --> 01:12:26,696
and you can see as much if
you actually download that.

1779
01:12:26,696 --> 01:12:30,256
In fact, let's go over
to the distribution code,

1780
01:12:30,256 --> 01:12:33,946
and if I go to
CS76.net/projects,

1781
01:12:34,426 --> 01:12:38,096
and we have the Full Words
dog P List file there.

1782
01:12:38,096 --> 01:12:43,796
If I try to open it in
Xcode, it's going to open

1783
01:12:43,796 --> 01:12:46,746
in this big chart here,
which is kind of misleading

1784
01:12:46,746 --> 01:12:50,466
because there aren't really
keys called item zero item one.

1785
01:12:50,466 --> 01:12:52,826
This is just their way
of representing an array

1786
01:12:53,136 --> 01:12:55,586
in this table format,
but if I instead go

1787
01:12:55,586 --> 01:12:59,786
into my downloads folder here
and I open up Words.P list with,

1788
01:12:59,786 --> 01:13:02,546
let's say, Text Wrangler, which
is just a simple text editor,

1789
01:13:03,746 --> 01:13:06,956
we are going to see
this, which is XML.

1790
01:13:06,956 --> 01:13:09,616
If unfamiliar, XML is like
HTML but you get to make

1791
01:13:09,616 --> 01:13:10,726
up your own tag names,

1792
01:13:11,006 --> 01:13:13,736
and so here we have an
element called Array,

1793
01:13:13,736 --> 01:13:15,386
and then a whole
bunch of strings.

1794
01:13:15,386 --> 01:13:18,096
So that is what we have given
you for this dictionary,

1795
01:13:18,096 --> 01:13:20,796
and there's thousands and
thousands of lines here.

1796
01:13:21,006 --> 01:13:22,486
So this is actually
a perfect candidate

1797
01:13:22,486 --> 01:13:24,476
if implementing a program
that listed all these words,

1798
01:13:24,746 --> 01:13:27,666
not to keep all of them
around in like UITable cells,

1799
01:13:27,666 --> 01:13:29,436
if you were using a
TableViewController

1800
01:13:29,436 --> 01:13:30,406
like we did earlier.

1801
01:13:30,806 --> 01:13:34,546
So with regard to storage,
Property Lists are nice

1802
01:13:34,546 --> 01:13:36,766
when at least you have static
information that you want

1803
01:13:36,766 --> 01:13:38,336
to shift with your application.

1804
01:13:38,656 --> 01:13:41,796
But they can also be used
effectively to store defaults.

1805
01:13:41,796 --> 01:13:45,186
You can store value pairs,
even when an application quits,

1806
01:13:45,366 --> 01:13:49,656
and one of the things you'll get
to use an Evil Hangman or dabble

1807
01:13:49,656 --> 01:13:52,656
with in lab is NS Defaults,
which is an interface

1808
01:13:52,656 --> 01:13:55,826
for storing information
persistently in applications

1809
01:13:55,826 --> 01:13:58,396
so that when it quits, you
can actually reload those same

1810
01:13:58,396 --> 01:13:59,756
values after the fact.

1811
01:13:59,756 --> 01:14:02,216
So what kind of uses
might persistent storage

1812
01:14:02,216 --> 01:14:03,566
like that have for
an application?

1813
01:14:03,566 --> 01:14:06,486
Why is this useful?

1814
01:14:06,666 --> 01:14:10,026
>> If you got a call
while playing your game,

1815
01:14:10,106 --> 01:14:13,176
then you could store
data and when they hung

1816
01:14:13,176 --> 01:14:14,546
up the call, you
could resume it.

1817
01:14:14,546 --> 01:14:15,026
>> Okay, good.

1818
01:14:15,026 --> 01:14:16,916
So if you got a phone call,
it interrupted your game,

1819
01:14:16,916 --> 01:14:19,406
you could then reload the
information that the game --

1820
01:14:19,576 --> 01:14:20,786
the state that the
game was in so

1821
01:14:20,786 --> 01:14:22,246
that you can continue
playing it.

1822
01:14:22,586 --> 01:14:25,106
So to be honest, you probably
don't need to use Property Lists

1823
01:14:25,106 --> 01:14:28,546
for that because so long as the
application is backgrounded,

1824
01:14:28,546 --> 01:14:31,706
you can keep stuff in RAM
still, unless the user quits,

1825
01:14:31,706 --> 01:14:32,656
in which case they're at a loss.

1826
01:14:32,656 --> 01:14:34,496
>> I was talking
about NS Defaults.

1827
01:14:34,596 --> 01:14:35,166
>> Oh, I'm sorry.

1828
01:14:35,166 --> 01:14:37,336
So NS, okay so well,
and even NS Defaults.

1829
01:14:37,336 --> 01:14:40,206
So NS Defaults are truly
meant to be default values,

1830
01:14:40,836 --> 01:14:43,986
not state remembrance for
the state of the game.

1831
01:14:44,246 --> 01:14:46,136
So defaults would be like
do you want the sound

1832
01:14:46,136 --> 01:14:47,316
on or off by default?

1833
01:14:47,316 --> 01:14:49,846
Do you want -- what's
your nickname by default?

1834
01:14:50,656 --> 01:14:52,646
So NS Defaults are good
for things like that.

1835
01:14:52,646 --> 01:14:55,036
Configurable options that the
user might change in the game.

1836
01:14:55,336 --> 01:14:56,726
Settings is just another UI.

1837
01:14:56,726 --> 01:14:59,416
A lot of applications,
like in Evil Hangman,

1838
01:14:59,416 --> 01:15:01,676
will have settings built into
the application, for instance

1839
01:15:01,676 --> 01:15:03,056
on the Flipside,
and indeed that's

1840
01:15:03,056 --> 01:15:05,426
where you can store things
like the preferred word length

1841
01:15:05,426 --> 01:15:09,866
and number of guesses, and in NS
Defaults, if through that API,

1842
01:15:10,166 --> 01:15:12,996
which ends up writing a file
into the iPhone or to the iPad

1843
01:15:13,106 --> 01:15:16,366
or the like, but you can
also create write code,

1844
01:15:16,576 --> 01:15:19,526
that allows you to hook into
the settings icon on the iPhone

1845
01:15:19,526 --> 01:15:21,846
or the iPad where you can
move your settings there.

1846
01:15:22,106 --> 01:15:23,526
It's really just
design decision.

1847
01:15:23,526 --> 01:15:25,316
What people tend to do
for simple settings,

1848
01:15:25,316 --> 01:15:27,666
if you only have a few, they put
them in the application itself.

1849
01:15:27,956 --> 01:15:29,476
If there's lots and
lots of settings,

1850
01:15:29,476 --> 01:15:31,006
some people factor
them out and put them

1851
01:15:31,006 --> 01:15:32,556
under the settings
icon on the phone.

1852
01:15:32,556 --> 01:15:34,076
It's a little more annoying,
though, because you have

1853
01:15:34,076 --> 01:15:36,976
to exit the application and go
to it to actually get at them.

1854
01:15:36,976 --> 01:15:40,796
But you'll find that this is as
easy as writing key value pairs

1855
01:15:40,796 --> 01:15:44,796
to an object, so more on
that with Evil Hangman.

1856
01:15:45,016 --> 01:15:46,746
What's SQL Light, if familiar?

1857
01:15:47,286 --> 01:15:50,376
>> Like file SQL.

1858
01:15:52,416 --> 01:15:55,736
It stores a SQL accessible
database in a [inaudible] file.

1859
01:15:55,846 --> 01:15:57,226
>> Exactly.

1860
01:15:57,226 --> 01:16:00,816
So SQL, a structured query
language, is a database language

1861
01:16:00,816 --> 01:16:02,626
with which you can write
information to a database

1862
01:16:02,626 --> 01:16:05,326
and read it, and use
syntax that allows you

1863
01:16:05,326 --> 01:16:07,436
to search the database
fairly easily.

1864
01:16:07,436 --> 01:16:10,036
You don't have to resort to
linear search all of the time.

1865
01:16:10,396 --> 01:16:12,226
And it's nice because
you don't need a server.

1866
01:16:12,226 --> 01:16:15,216
You don't need MySQL or Postgres
or Oracle or anything like that.

1867
01:16:15,396 --> 01:16:17,336
You just store it
in a binary file

1868
01:16:17,336 --> 01:16:19,486
in the same folder
typically as your code,

1869
01:16:19,636 --> 01:16:23,656
and what SQL Light is, it's an
API that lets you read and write

1870
01:16:23,736 --> 01:16:26,356
from that file using
select and insert and delete

1871
01:16:26,356 --> 01:16:28,366
if you're familiar with
that feature of SQL.

1872
01:16:28,676 --> 01:16:32,696
The catch is, in iOS, the SQL
Light library is implemented not

1873
01:16:32,696 --> 01:16:36,416
in Objective-C but in C, which
means the code looks horrific.

1874
01:16:36,416 --> 01:16:38,146
It's very useful,
it's very powerful,

1875
01:16:38,146 --> 01:16:39,516
but it's also a bit arcane,

1876
01:16:39,696 --> 01:16:42,306
and so people typically
use other constructs,

1877
01:16:42,306 --> 01:16:43,476
a couple of which
we've discussed.

1878
01:16:43,866 --> 01:16:46,886
XML, meanwhile, or
json, is typically used

1879
01:16:46,886 --> 01:16:50,236
when transporting information
these days across the wire,

1880
01:16:50,236 --> 01:16:52,426
so Property List or
XML, but if you were

1881
01:16:52,426 --> 01:16:54,426
to have your own arbitrary
format, typically that's

1882
01:16:54,426 --> 01:16:56,976
for a game or a program that
somehow grabs information

1883
01:16:56,976 --> 01:16:58,256
from a server on the Internet.

1884
01:16:58,506 --> 01:17:00,156
These are very useful
data formats

1885
01:17:00,156 --> 01:17:01,436
for exchanging information.

1886
01:17:01,436 --> 01:17:04,176
And then finally there's
Core Data, which is an iOS --

1887
01:17:04,356 --> 01:17:06,346
which is an Apple
SDK which allows you

1888
01:17:06,346 --> 01:17:08,936
to abstract the notion
of a database altogether

1889
01:17:09,156 --> 01:17:12,486
and define your database
schema, define the keys

1890
01:17:12,486 --> 01:17:13,936
and the values, the relations.

1891
01:17:13,936 --> 01:17:18,066
Among them, using a very
graphical editor to wire things

1892
01:17:18,066 --> 01:17:19,356
up a little more high level.

1893
01:17:19,486 --> 01:17:20,656
And you had a question here.

1894
01:17:20,746 --> 01:17:25,276
>> Is it possible to query a
regular expression in SQL light?

1895
01:17:25,276 --> 01:17:28,596
>> Is it possible to query a
regular expression in SQL Light?

1896
01:17:28,976 --> 01:17:29,916
Simplified ones.

1897
01:17:29,946 --> 01:17:33,856
SQL supports like queries
where you can use a subset

1898
01:17:33,856 --> 01:17:36,356
of Perl's regular expressions,
or, which are common

1899
01:17:36,356 --> 01:17:37,386
in other languages as well.

1900
01:17:37,826 --> 01:17:38,496
So sort of.

1901
01:17:38,936 --> 01:17:40,876
Good question.

1902
01:17:41,256 --> 01:17:41,686
All right.

1903
01:17:41,686 --> 01:17:46,156
So let's actually -- let's go
back over here and let's go

1904
01:17:46,156 --> 01:17:49,196
into tonight's sources,
and let's go into P List.

1905
01:17:49,316 --> 01:17:54,156
So I, in advance, downloaded
the P list file earlier

1906
01:17:54,436 --> 01:17:56,116
on my own computer over here.

1907
01:17:56,676 --> 01:17:57,266
Not that when.

1908
01:17:57,396 --> 01:17:59,356
So now if I go into P List,

1909
01:17:59,356 --> 01:18:02,676
and go into the distribution
code here, we'll see some

1910
01:18:02,676 --> 01:18:04,026
of the usual friends,
and let me go

1911
01:18:04,026 --> 01:18:06,716
into Main.M. Okay,
no surprises there.

1912
01:18:06,976 --> 01:18:07,786
Let me next go

1913
01:18:07,786 --> 01:18:11,196
into AppDelegate.H.
No surprises there.

1914
01:18:11,546 --> 01:18:14,746
AppDelegate.M. No
surprises there.

1915
01:18:14,746 --> 01:18:16,016
It seems to be handing
off control now

1916
01:18:16,016 --> 01:18:19,486
to ViewController.H. Really
nothing going on there.

1917
01:18:19,896 --> 01:18:21,556
ViewController.M. Finally,

1918
01:18:21,776 --> 01:18:23,406
there's something
going on in here.

1919
01:18:23,406 --> 01:18:23,996
But let's wait.

1920
01:18:23,996 --> 01:18:26,896
Let's go to the Nib file,
and for some reason,

1921
01:18:26,896 --> 01:18:29,726
my example involves
cities in California.

1922
01:18:30,026 --> 01:18:32,436
So this is always been a stupid
feature of Interface Builder.

1923
01:18:32,436 --> 01:18:35,576
When you drag and drop
a UITableViewController

1924
01:18:35,576 --> 01:18:38,416
into an application, rather
than show you your data

1925
01:18:38,416 --> 01:18:41,396
or just blanks, they arbitrarily
show you cities in California.

1926
01:18:41,396 --> 01:18:43,266
Those are not in the
application itself.

1927
01:18:43,506 --> 01:18:44,326
It's like a screenshot

1928
01:18:44,326 --> 01:18:46,596
of someone else's application,
but mildly confusing.

1929
01:18:46,976 --> 01:18:51,986
But if I now go back to my
code, let's see what I'm doing.

1930
01:18:51,986 --> 01:18:53,116
So recall that we looked

1931
01:18:53,116 --> 01:18:55,866
at the master Detail
Application earlier,

1932
01:18:55,866 --> 01:18:58,306
which was a little complex,
and I've stolen some

1933
01:18:58,306 --> 01:18:59,926
of the simpler ideas from it,

1934
01:19:00,156 --> 01:19:03,226
just to implement the
following application.

1935
01:19:03,226 --> 01:19:05,166
If I go ahead and click
run up here, woops,

1936
01:19:05,746 --> 01:19:11,966
and let me quit the old
simulator, and let me run this.

1937
01:19:12,166 --> 01:19:15,506
In the latest version
of the simulator,

1938
01:19:15,506 --> 01:19:19,546
it's going to pop open, and you
might see some familiar words.

1939
01:19:19,546 --> 01:19:22,716
So these are from our Property
List called Small.P List,

1940
01:19:22,716 --> 01:19:24,586
which I downloaded from
the courses website.

1941
01:19:24,796 --> 01:19:26,876
Recall that the product
specification gives you a super

1942
01:19:26,876 --> 01:19:29,006
short list, just so you
can tinker without worrying

1943
01:19:29,006 --> 01:19:30,326
about hundreds of
thousands of words.

1944
01:19:30,606 --> 01:19:33,176
So that's just an XML file
that I've literally dragged

1945
01:19:33,176 --> 01:19:34,676
and dropped into the project,

1946
01:19:34,806 --> 01:19:36,636
and somehow in code
I'm opening this up.

1947
01:19:36,806 --> 01:19:36,986
Yes.

1948
01:19:37,486 --> 01:19:46,796
>> [Inaudible audience
question].

1949
01:19:47,296 --> 01:19:48,276
>> Yes, you should.

1950
01:19:48,276 --> 01:19:51,476
It's because I made
these on another computer

1951
01:19:51,546 --> 01:19:55,686
and that one, there we go, yeah.

1952
01:19:55,786 --> 01:19:58,156
So with things like
this, I'll go --

1953
01:19:58,156 --> 01:19:59,166
I'll fix these and
re-upload them

1954
01:19:59,166 --> 01:19:59,976
so you don't see
these little warnings.

1955
01:20:00,046 --> 01:20:02,846
It's because the computer
I was creating them

1956
01:20:02,846 --> 01:20:04,956
on was a slightly
different version.

1957
01:20:05,106 --> 01:20:08,036
Short answer, your code should
have no warnings, therefore do

1958
01:20:08,036 --> 01:20:08,836
as I say, not as I do.

1959
01:20:09,766 --> 01:20:11,046
But I will fix that.

1960
01:20:11,046 --> 01:20:13,856
Okay. So this P List file,
I literally just dragged

1961
01:20:13,856 --> 01:20:16,476
and dropped into the
supporting files folder,

1962
01:20:16,476 --> 01:20:17,476
but that's not really a folder.

1963
01:20:17,476 --> 01:20:19,416
I could have put it
anywhere into the project,

1964
01:20:19,576 --> 01:20:22,796
and so that means all of the
logic must be in this .M file.

1965
01:20:22,796 --> 01:20:23,876
So let's see what's going on.

1966
01:20:24,276 --> 01:20:25,856
This is my ViewController class.

1967
01:20:26,216 --> 01:20:28,606
I have chosen to implement
this familiar method now,

1968
01:20:28,606 --> 01:20:31,396
In It With Nib Name Bundle,
and what am I doing in there?

1969
01:20:31,396 --> 01:20:34,496
One, I'm calling the parent
classes version of that method,

1970
01:20:34,726 --> 01:20:37,276
so that's familiar construct,
checking it's return value

1971
01:20:37,276 --> 01:20:38,216
to make sure it's not nil,

1972
01:20:38,406 --> 01:20:39,996
and then I'm apparently
loading words.

1973
01:20:40,176 --> 01:20:42,516
So how do you go about
loading an XML file,

1974
01:20:42,516 --> 01:20:45,066
specifically a Property
List, from your application

1975
01:20:45,066 --> 01:20:47,066
if you've dragged and dropped
it in there or added it

1976
01:20:47,066 --> 01:20:48,836
by going to File Add File?

1977
01:20:49,196 --> 01:20:52,726
Well, I apparently call NS
Bundle Main Bundle, so this --

1978
01:20:52,886 --> 01:20:55,636
this is a way of saying to iOS,
give me essentially the path

1979
01:20:56,086 --> 01:20:57,346
to the default folder,

1980
01:20:57,446 --> 01:20:59,706
the default root folder
of this application.

1981
01:21:00,226 --> 01:21:04,236
Then give me specifically the
path for the following resource:

1982
01:21:04,236 --> 01:21:06,296
"small,", and what
data type is it?

1983
01:21:06,526 --> 01:21:09,056
P list. So this is a
way of telling iOS,

1984
01:21:09,356 --> 01:21:11,406
give me a file called
P List, sorry,

1985
01:21:11,406 --> 01:21:13,536
give me a file called
small dot something.

1986
01:21:13,926 --> 01:21:16,256
That something is P List
because it's of type P List,

1987
01:21:16,256 --> 01:21:18,356
and this helps it know
how to load the file,

1988
01:21:18,356 --> 01:21:20,576
whether it's a Property
List, a binary file,

1989
01:21:20,576 --> 01:21:21,796
or some generic text file.

1990
01:21:22,226 --> 01:21:23,646
Then I'm out doing this.

1991
01:21:23,746 --> 01:21:26,906
On the left-hand side,
what's going on here

1992
01:21:26,906 --> 01:21:28,086
in this highlighted portion?

1993
01:21:28,086 --> 01:21:29,126
>> [Inaudible audience
response].

1994
01:21:29,126 --> 01:21:34,976
>> Good. I'm creating a
pointer to an NS Array Object,

1995
01:21:34,976 --> 01:21:39,546
and on the right-hand side, I'm
calling NS Array Alloc In It

1996
01:21:39,546 --> 01:21:41,106
With Contents Of File.

1997
01:21:41,346 --> 01:21:43,296
So there's a bunch of
different ways to do this.

1998
01:21:43,426 --> 01:21:46,926
I have chosen to use NS Arrays
Alloc method, and then the

1999
01:21:46,926 --> 01:21:49,706
In It Method, called In Its With
Contents Of File, and it turns

2000
01:21:49,706 --> 01:21:51,646
out that if I read the
documentation for that method,

2001
01:21:51,646 --> 01:21:55,126
it just knows how to load that
information into the file.

2002
01:21:55,826 --> 01:21:58,476
But I thought NS
Arrays were unmutable?

2003
01:21:59,516 --> 01:22:00,206
Were immutable?

2004
01:22:00,776 --> 01:22:04,626
In other words, I thought
you couldn't change them,

2005
01:22:05,226 --> 01:22:08,496
but I'm clearly initializing
this one with words.

2006
01:22:09,146 --> 01:22:11,616
How do we reconcile that?

2007
01:22:11,616 --> 01:22:11,826
What's that?

2008
01:22:11,886 --> 01:22:14,156
>> You never allocated
or initialized it.

2009
01:22:14,386 --> 01:22:18,796
>> I never allocated
it or initialized it,

2010
01:22:18,796 --> 01:22:21,646
but I did allocate and
initialize it here, right?

2011
01:22:21,646 --> 01:22:23,526
>> Not on both sides.

2012
01:22:23,666 --> 01:22:25,206
>> You haven't changed
the arrays

2013
01:22:25,206 --> 01:22:27,496
and you just have it
typed NS Array pointer.

2014
01:22:27,656 --> 01:22:29,946
>> So that's okay, on
the left-hand side.

2015
01:22:30,526 --> 01:22:32,386
But why is this not
a mutable array?

2016
01:22:32,496 --> 01:22:35,576
I'm adding stuff to it which
means I'm changing it, right?

2017
01:22:35,576 --> 01:22:37,066
>> [Inaudible audience
response].

2018
01:22:37,066 --> 01:22:40,386
>> Yes, that's the
key distinction.

2019
01:22:40,386 --> 01:22:42,986
If you could never
mutate arrays,

2020
01:22:42,986 --> 01:22:45,676
you could never have
anything in an NS Array.

2021
01:22:45,676 --> 01:22:46,926
It would be a useless object.

2022
01:22:47,206 --> 01:22:50,346
But in this case, we have an NS
Array that's being initialized

2023
01:22:50,776 --> 01:22:53,816
at the point of allocation
with the contents of a file,

2024
01:22:53,816 --> 01:22:55,986
so the fact that it's an NS
Array just means I can't change

2025
01:22:55,986 --> 01:22:58,496
it after this line of code.

2026
01:22:58,626 --> 01:23:00,996
And that makes sense, because if
this application is just going

2027
01:23:00,996 --> 01:23:03,426
to show this list of words,
much like Evil Hangman is going

2028
01:23:03,426 --> 01:23:05,866
to have a long list of
words in its memory,

2029
01:23:06,186 --> 01:23:07,486
you're not going to
want to change it.

2030
01:23:07,486 --> 01:23:09,596
You just want to have one
copy of that lying around,

2031
01:23:09,596 --> 01:23:11,076
and it's slightly more efficient

2032
01:23:11,326 --> 01:23:14,486
to have the NS Array class
instead of the NS Mutable Array,

2033
01:23:14,486 --> 01:23:16,616
because one, there's
less functionality,

2034
01:23:16,616 --> 01:23:19,286
there's not the editing
code related to it, and two,

2035
01:23:19,286 --> 01:23:20,676
you protect yourself
against yourself.

2036
01:23:20,676 --> 01:23:23,096
You can't accidentally delete
a word from your dictionary

2037
01:23:23,296 --> 01:23:26,956
if you've said to the compiler,
this is an immutable NS Array.

2038
01:23:27,056 --> 01:23:28,176
All right.

2039
01:23:28,176 --> 01:23:31,366
So lastly, I'm just remembering
that pointer by assigning it

2040
01:23:31,366 --> 01:23:34,616
to my property called Words,
and then I'm returning myself.

2041
01:23:34,616 --> 01:23:38,176
So at this point in the program,
I have loaded that Property List

2042
01:23:38,176 --> 01:23:40,626
into memory, stored it in a
property, so now I have access

2043
01:23:40,626 --> 01:23:42,316
to an NS Array that
I can iterate over

2044
01:23:42,316 --> 01:23:43,256
and do whatever I want.

2045
01:23:43,686 --> 01:23:45,886
So the application
now looks like this.

2046
01:23:45,886 --> 01:23:50,566
It's a table of words and I now
somehow have to render one, two,

2047
01:23:50,566 --> 01:23:52,996
three, four, five cells,

2048
01:23:53,376 --> 01:23:56,126
but I don't proactively
push the cells to the UI.

2049
01:23:56,126 --> 01:24:00,896
I'm instead going to have the
-- the iOS is going to ask me,

2050
01:24:00,896 --> 01:24:01,846
what do you want at this cell?

2051
01:24:01,846 --> 01:24:02,806
What do you want at this cell?

2052
01:24:02,806 --> 01:24:03,726
What do you want at this cell?

2053
01:24:03,726 --> 01:24:05,016
Or rather, what do
you want at this row?

2054
01:24:05,016 --> 01:24:05,936
This row? This row?

2055
01:24:06,156 --> 01:24:08,146
And I have to return
a cell to it.

2056
01:24:08,476 --> 01:24:11,226
So if I go back to the code,
notice that we have this thing,

2057
01:24:11,226 --> 01:24:14,786
number of sections in
TableView, so that's okay here

2058
01:24:14,786 --> 01:24:16,466
because it's just one big table.

2059
01:24:16,466 --> 01:24:17,856
There's not different groupings.

2060
01:24:18,096 --> 01:24:20,356
As an aside, if I go back here,

2061
01:24:20,356 --> 01:24:22,356
let me see if I can
show you the opposite.

2062
01:24:22,356 --> 01:24:26,436
If I go into settings, this
is a UITableView, so if you go

2063
01:24:26,436 --> 01:24:29,806
into an iOS device, you've seen
to UITableView's for years now.

2064
01:24:30,156 --> 01:24:33,396
Those -- this is a UITableView
with one, two, three,

2065
01:24:33,396 --> 01:24:35,656
at least four sections, each

2066
01:24:35,656 --> 01:24:37,996
of which has some
non-zero number of rows.

2067
01:24:38,146 --> 01:24:39,546
So that's all we
mean by sections.

2068
01:24:39,836 --> 01:24:40,896
But the game we're playing,

2069
01:24:40,896 --> 01:24:44,156
or the program we're using
here just as one such section

2070
01:24:44,156 --> 01:24:45,326
since we don't see the gray.

2071
01:24:45,656 --> 01:24:46,496
So what next?

2072
01:24:46,496 --> 01:24:49,236
This, actually let me
delete for simplicity

2073
01:24:49,546 --> 01:24:53,576
since it's not necessary here,
and now we have TableView,

2074
01:24:53,626 --> 01:24:55,146
Self or Row At Index Path.

2075
01:24:55,616 --> 01:24:56,656
When is this method called?

2076
01:25:03,436 --> 01:25:05,476
When or why is this
method called?

2077
01:25:05,986 --> 01:25:06,986
What's that?

2078
01:25:06,986 --> 01:25:07,186
>> [Inaudible audience
response].

2079
01:25:07,186 --> 01:25:15,516
>> When you try to get a cell
and you pass in the Index Path,

2080
01:25:15,516 --> 01:25:18,956
yes, so this is really --
the operating system is going

2081
01:25:18,956 --> 01:25:21,796
to call this method or more
specifically, the Controller,

2082
01:25:21,996 --> 01:25:25,996
is going to call this method,
or rather the View is going

2083
01:25:25,996 --> 01:25:28,946
to call this method When I Want
To Render A Cell On The Screen,

2084
01:25:28,946 --> 01:25:31,696
it's going to say what belongs
at section zero, row zero.

2085
01:25:31,696 --> 01:25:34,746
What belongs at section zero,
row one, row two, row three,

2086
01:25:34,836 --> 01:25:38,076
and my job, as we saw earlier
with Master Detail, is to return

2087
01:25:38,076 --> 01:25:40,366
to this thing an object
representing that row

2088
01:25:40,366 --> 01:25:42,066
in the table with
whatever text I want,

2089
01:25:42,246 --> 01:25:43,646
whatever buttons I want inside.

2090
01:25:43,646 --> 01:25:46,716
So we have this same trick
using the reusable cells.

2091
01:25:47,066 --> 01:25:49,006
I'm using "cell"
again this time.

2092
01:25:49,636 --> 01:25:53,346
If not, I instantiated as
needed and then down here,

2093
01:25:53,486 --> 01:25:55,396
I am initializing
the cell as follows.

2094
01:25:55,396 --> 01:25:58,296
One, I'm setting it
so-called selection style

2095
01:25:58,576 --> 01:26:02,206
to be UITableView Cell
Selection Style None.

2096
01:26:02,506 --> 01:26:03,326
What does that mean?

2097
01:26:03,576 --> 01:26:05,636
It just means that when
the user's finger clicks

2098
01:26:05,636 --> 01:26:06,996
on this TableView,
like I'm doing

2099
01:26:06,996 --> 01:26:08,976
with my mouse, nothing happens.

2100
01:26:08,976 --> 01:26:10,696
It doesn't become blue,
it doesn't get selected.

2101
01:26:10,936 --> 01:26:12,826
>> So UITableView is
getting rows [inaudible]?

2102
01:26:13,036 --> 01:26:13,226
>> Correct.

2103
01:26:14,216 --> 01:26:16,096
It's asking me what
do you want here.

2104
01:26:16,096 --> 01:26:16,896
What do you want here?

2105
01:26:16,896 --> 01:26:17,876
What do you want here?

2106
01:26:17,876 --> 01:26:20,806
And I have to hand it back the
rectangular cell effectively.

2107
01:26:20,896 --> 01:26:25,206
Exactly. And then I'm setting
the cells text labels text equal

2108
01:26:25,206 --> 01:26:29,596
to be whatever is returned
from the object at index row,

2109
01:26:29,596 --> 01:26:31,826
so what's at index zero,
what's at index one,

2110
01:26:31,886 --> 01:26:34,356
and then I'm passing
that message to words

2111
01:26:34,666 --> 01:26:37,846
so that I get the zero
object, the one object,

2112
01:26:37,846 --> 01:26:39,646
two object, three, and so forth.

2113
01:26:39,826 --> 01:26:46,326
And if I change this, for
instance, to that, semicolon,

2114
01:26:46,476 --> 01:26:49,436
and rerun the application,
what I should get,

2115
01:26:49,436 --> 01:26:51,296
despite all of that
effort to store data,

2116
01:26:51,556 --> 01:26:54,456
is just the same string
again and again and again.

2117
01:26:54,456 --> 01:26:57,776
So that's truly a method
that's being called.

2118
01:26:58,206 --> 01:27:00,226
Finally down here,
this one's different.

2119
01:27:00,486 --> 01:27:03,316
Number -- TableView
number of rows in section,

2120
01:27:03,386 --> 01:27:05,476
this is the method
that I'm going --

2121
01:27:05,476 --> 01:27:06,406
that's going to be invoked

2122
01:27:06,406 --> 01:27:08,696
when asked how many rows
the section zero have

2123
01:27:08,696 --> 01:27:11,946
so that iOS knows how many
times to ask you for the cells.

2124
01:27:12,206 --> 01:27:14,256
In this case, I have
not hardcoded a value

2125
01:27:14,446 --> 01:27:16,746
because I don't remember
how many words are

2126
01:27:16,746 --> 01:27:18,516
in the Property List, and
maybe it would even change

2127
01:27:18,516 --> 01:27:19,216
with an update.

2128
01:27:19,486 --> 01:27:22,026
So we pass in the Count
Message to Self.Words,

2129
01:27:22,026 --> 01:27:24,516
which gives me the
array's length.

2130
01:27:25,526 --> 01:27:25,686
Yes.

2131
01:27:26,816 --> 01:27:31,296
>> So in case where you're
passing through a file,

2132
01:27:31,376 --> 01:27:35,776
we have an array
that's not immutable.

2133
01:27:35,776 --> 01:27:40,026
You're editing the actual
file itself, I'm sorry,

2134
01:27:40,026 --> 01:27:43,316
the P List itself in your-- ?

2135
01:27:43,886 --> 01:27:46,156
>> No editing has happened
to the P list here.

2136
01:27:46,156 --> 01:27:48,466
>> No, but I'm saying in terms
of like if you wanted to --

2137
01:27:48,596 --> 01:27:52,696
if the P List had
like more contents,

2138
01:27:52,866 --> 01:27:54,616
this would already account.

2139
01:27:55,056 --> 01:27:55,586
>> Yes.

2140
01:27:55,586 --> 01:27:55,816
>> Okay.

2141
01:27:55,916 --> 01:27:56,346
>> Exactly.

2142
01:27:56,346 --> 01:27:58,996
This is good design, because
even though I could go

2143
01:27:58,996 --> 01:28:01,416
to the application and I could
do a one, two, three, four,

2144
01:28:01,416 --> 01:28:04,886
there's five words in my P list,
I could just write return five.

2145
01:28:05,176 --> 01:28:08,446
The catch is that whereas
it's reasonable to assume

2146
01:28:08,446 --> 01:28:11,616
that my UI has zero,
has one section forever,

2147
01:28:11,616 --> 01:28:13,986
because that's how I designed
the user experience to be,

2148
01:28:13,986 --> 01:28:16,216
with just one big TableView,
no notion of sections,

2149
01:28:16,606 --> 01:28:19,866
that in theory could change, and
it's a poor design decision if,

2150
01:28:20,106 --> 01:28:22,506
not only do I have to update
the Property List in a year

2151
01:28:22,506 --> 01:28:25,006
when I ship a new version
with ten words and not five,

2152
01:28:25,326 --> 01:28:26,716
but to also have
to change it there.

2153
01:28:26,716 --> 01:28:28,916
It's just inviting bugs
and unmaintainability.

2154
01:28:29,816 --> 01:28:31,636
So that's all.

2155
01:28:31,856 --> 01:28:32,636
All right.

2156
01:28:32,636 --> 01:28:36,556
So nice and sexier maybe, but
let's actually do something

2157
01:28:36,556 --> 01:28:39,236
where we interact with the glass
of the screen and do something

2158
01:28:39,236 --> 01:28:42,076
like clicking or dragging or
pinching, and see how we can add

2159
01:28:42,116 --> 01:28:43,266
that element, particularly

2160
01:28:43,266 --> 01:28:45,096
as you contemplate what
you might want to do

2161
01:28:45,096 --> 01:28:47,086
with your third and
final project.

2162
01:28:47,086 --> 01:28:51,026
So it turns out that iOS
supports a whole bunch

2163
01:28:51,026 --> 01:28:53,836
of gestures, and you're probably
familiar with these naturally

2164
01:28:53,836 --> 01:28:56,356
if you have a device like
this, but they all reduce

2165
01:28:56,356 --> 01:28:58,106
to some key class name.

2166
01:28:58,106 --> 01:29:01,196
So we have things like
UITapGestureRecognizer.

2167
01:29:01,466 --> 01:29:03,596
This is the type of object
that if you instantiate,

2168
01:29:03,766 --> 01:29:06,986
you have the ability to detect
that on an arbitrary portion

2169
01:29:06,986 --> 01:29:09,716
onto the screen, not necessarily
right on top of a button,

2170
01:29:09,776 --> 01:29:11,306
which is handled for
you automatically.

2171
01:29:11,626 --> 01:29:14,296
Pinch, which is doing something
like this often to zoom.

2172
01:29:14,516 --> 01:29:17,136
Rotations, kind of twisting
your fingers around,

2173
01:29:17,136 --> 01:29:18,756
swiping left to right,
up to down.

2174
01:29:19,066 --> 01:29:21,686
Pan gesture, if you want to
move something across the screen

2175
01:29:21,686 --> 01:29:24,576
and long press, if you want to
click and hold for like a second

2176
01:29:24,576 --> 01:29:27,066
or two, that, too, can
be detected differently.

2177
01:29:27,066 --> 01:29:29,236
And if you've used Google maps
or Apple Maps or the like,

2178
01:29:29,236 --> 01:29:32,096
you've experienced a bunch of
the different UI mechanisms.

2179
01:29:32,366 --> 01:29:34,186
So how do we start doing that?

2180
01:29:34,656 --> 01:29:39,086
Well, let me go into some
code in our last project here

2181
01:29:39,086 --> 01:29:44,806
for the evening and open
up the one called Gestures.

2182
01:29:45,256 --> 01:29:47,736
Now in advance, I
went on Facebook

2183
01:29:48,236 --> 01:29:50,136
and downloaded a
few photographs.

2184
01:29:50,876 --> 01:29:53,686
Let me go ahead and
run this application,

2185
01:29:54,636 --> 01:29:56,276
and we have this
application here.

2186
01:29:57,046 --> 01:30:02,686
And if we swipe to the right,
there's his graduation.

2187
01:30:03,006 --> 01:30:06,456
And one more, in his plumbers
outfit from this weekend.

2188
01:30:06,876 --> 01:30:10,336
So we can keep flipping through
this, and each time I swipe

2189
01:30:10,336 --> 01:30:12,816
from right to left, even though
you can just barely see my

2190
01:30:12,816 --> 01:30:15,116
mouse, it's like I'm sliding
my finger from left to right.

2191
01:30:15,116 --> 01:30:15,956
And I kept it simple.

2192
01:30:15,956 --> 01:30:18,326
I didn't do it quite so that
he's sliding off the screen.

2193
01:30:18,596 --> 01:30:21,296
As soon as I start sliding,
it just jumps off to the side,

2194
01:30:21,296 --> 01:30:22,156
just to keep it simple.

2195
01:30:22,336 --> 01:30:24,376
But also, if I click and
hold on, like, his nose,

2196
01:30:24,376 --> 01:30:27,326
it's going to nag at me
because I'm using a long press

2197
01:30:27,636 --> 01:30:28,666
gesture recognizer.

2198
01:30:28,666 --> 01:30:30,466
So how do we go about
implementing this

2199
01:30:30,696 --> 01:30:33,356
and implementing that
kind of functionality?

2200
01:30:33,506 --> 01:30:34,506
Well, let's go into this.

2201
01:30:34,506 --> 01:30:37,496
So in my project here, I've
got some familiar files

2202
01:30:37,496 --> 01:30:38,166
and some new ones.

2203
01:30:38,166 --> 01:30:40,526
Under supporting files, I
have three photos of Rob,

2204
01:30:40,766 --> 01:30:43,596
so these are just JPEGs
that I dragged and dropped

2205
01:30:43,596 --> 01:30:45,816
after renaming them, after
downloading them from Facebook.

2206
01:30:45,816 --> 01:30:47,496
I encourage you to
friend Rob on Facebook.

2207
01:30:47,496 --> 01:30:49,966
If you then drag them
into the project,

2208
01:30:49,966 --> 01:30:52,106
I can now access them
programmatically.

2209
01:30:52,106 --> 01:30:55,216
And so now, I can do
something like this.

2210
01:30:55,596 --> 01:30:57,796
In Main.M is some usual code.

2211
01:30:58,376 --> 01:31:01,566
In AppDelegate.H,
is some usual code.

2212
01:31:01,966 --> 01:31:04,726
In AppDelegate.M
is some usual code.

2213
01:31:04,726 --> 01:31:05,696
So nothing new here.

2214
01:31:05,696 --> 01:31:07,666
We're building on the
same principles as before,

2215
01:31:07,856 --> 01:31:09,946
so the magic must be
somewhere in my Nib

2216
01:31:09,946 --> 01:31:11,236
in my ViewController files.

2217
01:31:11,576 --> 01:31:15,196
So my ViewController.Nib
file also looks very simple.

2218
01:31:15,506 --> 01:31:19,446
I dragged and dropped a
class called UIImageView,

2219
01:31:19,446 --> 01:31:22,976
which is like a video
player, but for images.

2220
01:31:22,976 --> 01:31:26,216
It's just a placeholder for
single PNG or gif or JPEG

2221
01:31:26,216 --> 01:31:29,556
or the like, and I configured it
to just fill the whole screen.

2222
01:31:30,006 --> 01:31:32,266
So I need to somehow
programmatically have access

2223
01:31:32,266 --> 01:31:32,726
to that.

2224
01:31:32,956 --> 01:31:35,416
So a good place to start,
again, when downloading code

2225
01:31:35,416 --> 01:31:39,086
that someone else wrote or that
you download online as part

2226
01:31:39,086 --> 01:31:41,496
of a bigger project, is
just control click on it,

2227
01:31:41,646 --> 01:31:46,916
and it looks like there is a
ImageView Property somewhere

2228
01:31:46,916 --> 01:31:49,256
that's pointing to file's owner.

2229
01:31:49,256 --> 01:31:51,316
So there's some kind of
linkage happening here,

2230
01:31:51,316 --> 01:31:53,126
some kind of outlet
to the files owner.

2231
01:31:53,436 --> 01:31:59,056
So let's look at my.H file,
and if I go into my.H file,

2232
01:31:59,576 --> 01:32:01,276
nothing there, that's
interesting.

2233
01:32:01,276 --> 01:32:04,376
ViewController.M, so I've tried

2234
01:32:04,376 --> 01:32:06,206
to take things one
step further here.

2235
01:32:06,206 --> 01:32:08,196
Thus far, we've been
putting properties

2236
01:32:08,196 --> 01:32:10,986
and method declarations
in our .H files,

2237
01:32:11,366 --> 01:32:14,406
which is a common convention,
but it's not strictly necessary,

2238
01:32:14,406 --> 01:32:18,576
because if all of my methods are
implemented in this same file,

2239
01:32:18,916 --> 01:32:22,196
and if no one else is going
to be importing my.H file,

2240
01:32:22,196 --> 01:32:24,476
and they probably shouldn't be
importing my ViewController.

2241
01:32:24,476 --> 01:32:27,346
You would typically
import utility classes,

2242
01:32:27,346 --> 01:32:32,176
or files with constants, or
files for models and the like,

2243
01:32:32,366 --> 01:32:34,766
there's really no reason for
me to advertise to the world

2244
01:32:34,766 --> 01:32:37,676
in principle in my.H file all
of this internal functionality.

2245
01:32:37,966 --> 01:32:41,406
So I can certainly just declare
these properties as private

2246
01:32:41,716 --> 01:32:44,336
by putting them in this file,
and I say private typically

2247
01:32:44,336 --> 01:32:46,686
because again, you can still
send messages to objects.

2248
01:32:46,686 --> 01:32:48,926
They may very well respond,
but just in the interest

2249
01:32:48,926 --> 01:32:50,696
of not advertising features,

2250
01:32:50,696 --> 01:32:53,326
much like Apple does not
advertise certain APIs,

2251
01:32:53,326 --> 01:32:55,326
they keep them private
though people figure it out,

2252
01:32:55,626 --> 01:32:58,216
I've decided to declare
all of my properties here

2253
01:32:58,216 --> 01:33:02,556
in this file my.M. So I seem
to have a few properties.

2254
01:33:02,556 --> 01:33:04,966
One is a bullion called
Alert In Progress,

2255
01:33:05,466 --> 01:33:06,846
and I ended up using that.

2256
01:33:06,846 --> 01:33:08,966
If I fast forward to the end
of the story, because I needed

2257
01:33:08,966 --> 01:33:12,846
to remember if and when I had
touched Rob's face for too long

2258
01:33:12,846 --> 01:33:15,236
and therefore trigger the
AlertView, because I ran

2259
01:33:15,236 --> 01:33:17,656
into a bug through trial and
error that if I kept holding,

2260
01:33:17,656 --> 01:33:19,996
I might get multiple AlertViews,
and I didn't want to do that.

2261
01:33:19,996 --> 01:33:21,976
So I wanted a simple
locking mechanism

2262
01:33:22,186 --> 01:33:25,416
to make sure I only
open one AlertView ever.

2263
01:33:25,746 --> 01:33:29,946
So next I have an ImageView
pointer to a UIImageView,

2264
01:33:29,946 --> 01:33:32,126
and that's my IBOutlet,
so that's the wiring

2265
01:33:32,126 --> 01:33:33,826
between that IDImageView --

2266
01:33:33,826 --> 01:33:36,496
sorry, that UIImageView
and my code.

2267
01:33:36,796 --> 01:33:38,396
Then I have an index.

2268
01:33:38,396 --> 01:33:39,486
I'm not sure what that is.

2269
01:33:39,486 --> 01:33:41,236
And then I have some
Robs in the form

2270
01:33:41,236 --> 01:33:42,536
of a pointer to an NS Array.

2271
01:33:42,536 --> 01:33:44,526
So let's take a guess.

2272
01:33:44,526 --> 01:33:46,706
What is going to go in
that NS Array probably?

2273
01:33:46,706 --> 01:33:46,826
Yeah.

2274
01:33:47,496 --> 01:33:48,636
>> The images?

2275
01:33:48,726 --> 01:33:49,436
>> The images.

2276
01:33:49,436 --> 01:33:52,146
So specifically maybe the names
of the images that we'll see

2277
01:33:52,146 --> 01:33:54,576
in just a moment, and then the
[inaudible] it's called index?

2278
01:33:55,236 --> 01:33:56,356
>> Where you are.

2279
01:33:56,356 --> 01:33:57,196
>> Where I am.

2280
01:33:57,196 --> 01:33:59,566
So I realize again by thinking
through the design of this,

2281
01:33:59,566 --> 01:34:02,816
if I want to implement this --
this sort of carousel of Robs

2282
01:34:02,816 --> 01:34:05,356
and I want it to wrap around so
that the third image goes back

2283
01:34:05,356 --> 01:34:07,056
to the first image,
I decided just

2284
01:34:07,056 --> 01:34:10,566
to use an index that's
going to be a 012, 012,

2285
01:34:10,566 --> 01:34:12,706
and I can use some modular
arithmetic to wrap around,

2286
01:34:12,706 --> 01:34:14,796
like you might've done
in other languages.

2287
01:34:15,106 --> 01:34:16,636
So that's where this is going.

2288
01:34:16,836 --> 01:34:19,366
Meanwhile, I've got some
private methods, private only

2289
01:34:19,366 --> 01:34:21,646
in the sense that they're
not advertised in my.H,

2290
01:34:21,906 --> 01:34:25,006
called you -- Alert View Did
Dismiss With Button Index.

2291
01:34:25,416 --> 01:34:26,426
We've seen that before.

2292
01:34:26,426 --> 01:34:27,586
When is that method called?

2293
01:34:28,196 --> 01:34:29,376
Think back to last week.

2294
01:34:29,376 --> 01:34:29,826
>> [Inaudible audience
response].

2295
01:34:29,826 --> 01:34:33,456
>> When the user clicks
the cancellation button,

2296
01:34:33,456 --> 01:34:35,396
however labeled, that
big default button.

2297
01:34:35,656 --> 01:34:38,686
I now have another method
called Handle Long Press,

2298
01:34:38,686 --> 01:34:42,186
and the Handle Swipe,
and those are implemented

2299
01:34:42,186 --> 01:34:45,846
to receive something called
a Recognizer, so a pointer

2300
01:34:45,846 --> 01:34:48,666
to some kind of logic that has
recognized what the user has

2301
01:34:48,666 --> 01:34:50,706
done so I can glean some
information about it.

2302
01:34:51,066 --> 01:34:55,156
So now if I scroll down,
what am I going to do when --

2303
01:34:55,526 --> 01:34:58,496
let's do the Handle Long Press,
because it's a little simpler.

2304
01:34:58,796 --> 01:35:00,896
So when I click and
hold on Rob's nose,

2305
01:35:00,896 --> 01:35:02,636
or frankly anywhere
on the image.

2306
01:35:02,636 --> 01:35:04,796
It doesn't matter based on
how I've implemented this,

2307
01:35:05,156 --> 01:35:06,416
what is going to happen?

2308
01:35:06,416 --> 01:35:10,776
Well, iOS is going to recognize
that you're holding Rob's face

2309
01:35:10,776 --> 01:35:13,206
down for quite some time, and
therefore some code's going

2310
01:35:13,206 --> 01:35:15,796
to get executed, specifically
this method, Handle Long Press.

2311
01:35:15,796 --> 01:35:18,386
I'm going to be passed a
pointer to the recognizer,

2312
01:35:18,386 --> 01:35:20,706
in case that's useful,
and what I decided to do

2313
01:35:20,706 --> 01:35:22,606
with that information
here is what you saw.

2314
01:35:22,826 --> 01:35:24,606
I'm going to first
check, wait a minute,

2315
01:35:24,606 --> 01:35:26,066
is there already
alert in progress?

2316
01:35:26,256 --> 01:35:28,166
This is the bull that
I referred to earlier,

2317
01:35:28,166 --> 01:35:30,036
just to make sure we don't
get stuck in an infinite loop

2318
01:35:30,036 --> 01:35:32,576
by holding his face for four
seconds instead of just two.

2319
01:35:33,106 --> 01:35:35,726
Then I set it to yes,
so that I remember,

2320
01:35:35,726 --> 01:35:37,506
and this is single
threaded code at this point,

2321
01:35:37,506 --> 01:35:40,316
so it's not a problem if
I'm still holding down.

2322
01:35:40,746 --> 01:35:43,406
Then I'm going to go ahead
and allocate a UIAlertView,

2323
01:35:43,406 --> 01:35:44,716
and we saw this code last time,

2324
01:35:44,716 --> 01:35:46,046
even though the words
are now different.

2325
01:35:46,046 --> 01:35:47,866
It's going to say,
hey, stop that.

2326
01:35:48,216 --> 01:35:52,356
I have a delegate of self, so
not nil, and a cancel button

2327
01:35:52,446 --> 01:36:01,736
of fine, so this delegate of
self is used for what purpose?

2328
01:36:01,736 --> 01:36:01,866
>> [Inaudible audience
response].

2329
01:36:01,866 --> 01:36:05,406
>> To tell the ViewController
that it is done,

2330
01:36:05,406 --> 01:36:07,166
that the user has
dismissed it specifically.

2331
01:36:07,166 --> 01:36:08,586
So not the View,
the ViewController,

2332
01:36:08,876 --> 01:36:11,346
and that is what invokes
this method, recall,

2333
01:36:11,506 --> 01:36:14,116
which we said a moment ago
is the method that's called

2334
01:36:14,116 --> 01:36:17,266
when you click that close
button on a UIAlertView.

2335
01:36:17,266 --> 01:36:19,776
So all of that stuff is
pretty much identical

2336
01:36:19,776 --> 01:36:20,886
to what we saw last week.

2337
01:36:21,146 --> 01:36:24,326
So that's the method that's
called When I Do A Long Press,

2338
01:36:24,326 --> 01:36:27,076
but how did I teach the
program to even listen

2339
01:36:27,276 --> 01:36:30,286
for those long presses
on the image in question?

2340
01:36:30,286 --> 01:36:33,736
Well, if I scroll down, we look
to a couple of places here.

2341
01:36:34,016 --> 01:36:35,546
One is In It With Nib Name.

2342
01:36:35,836 --> 01:36:36,886
So this again is going to be

2343
01:36:36,886 --> 01:36:39,836
that method that's automatically
called when you are using --

2344
01:36:39,836 --> 01:36:41,816
when you are using
Nibs in your program.

2345
01:36:42,216 --> 01:36:44,866
This is the opposite of using
Storyboards, for instance,

2346
01:36:44,866 --> 01:36:46,546
but there's a similar
mechanism for those.

2347
01:36:46,796 --> 01:36:50,386
So In It With Nib Name is
copy and paste it essentially

2348
01:36:50,386 --> 01:36:52,936
from before, but I've added
a bit of code in the middle.

2349
01:36:53,226 --> 01:36:56,546
I first said Alert
In Progress, no,

2350
01:36:56,546 --> 01:36:58,136
because I want to
know by default.

2351
01:36:58,316 --> 01:37:00,036
There is no long press,
and that makes sense.

2352
01:37:00,036 --> 01:37:02,106
When the program starts, no
one's touching it by default.

2353
01:37:02,106 --> 01:37:05,326
And then I prepare the Rob, so
to speak, and that's one way

2354
01:37:05,326 --> 01:37:06,436
to initialize the array.

2355
01:37:06,926 --> 01:37:10,316
I Alloc an NS Array,
In It With Objects,

2356
01:37:10,436 --> 01:37:13,286
and if I am not loading it
from a file, for instance,

2357
01:37:13,286 --> 01:37:17,136
just from a comma separated
list, the syntax is string,

2358
01:37:17,406 --> 01:37:21,186
string, string, nil,
all in square brackets.

2359
01:37:21,316 --> 01:37:24,916
So that much like C is how you
can declare an array statically.

2360
01:37:25,126 --> 01:37:26,346
The nil is important.

2361
01:37:26,346 --> 01:37:28,676
You have to terminate
the cease-file array

2362
01:37:28,676 --> 01:37:29,416
for that reason.

2363
01:37:29,756 --> 01:37:33,526
On then Self.Index Gets
Zero, what does this mean?

2364
01:37:34,666 --> 01:37:35,176
What's the -- ?

2365
01:37:35,346 --> 01:37:36,736
>> Start at the zero.

2366
01:37:36,736 --> 01:37:39,556
>> Yeah, start with the first
Rob at index location zero.

2367
01:37:39,876 --> 01:37:42,266
So next, View Did Load, recall,

2368
01:37:42,266 --> 01:37:45,176
is the method that's
called once your View,

2369
01:37:45,226 --> 01:37:48,156
your user interface has been
loaded, and this is your point

2370
01:37:48,156 --> 01:37:51,536
at which to start configuring
some last-minute details,

2371
01:37:51,536 --> 01:37:52,866
after everything's been opened

2372
01:37:52,866 --> 01:37:54,446
up from the Nib file,
for instance.

2373
01:37:54,656 --> 01:37:57,396
So this is new code, but
hopefully pretty readable.

2374
01:37:57,716 --> 01:38:00,976
So notice I first call the
parent class's version of this.

2375
01:38:00,976 --> 01:38:04,076
Woops, the parent class, so
I call Super View Did Load,

2376
01:38:04,376 --> 01:38:05,646
then I load the image.

2377
01:38:05,806 --> 01:38:08,966
So Self.Image View.Image.

2378
01:38:09,956 --> 01:38:11,226
Self.Image View is what?

2379
01:38:11,866 --> 01:38:13,316
>> A property.

2380
01:38:13,366 --> 01:38:15,856
>> It's a property
of type UIImageView.

2381
01:38:15,856 --> 01:38:18,066
If I read the documentation
for UIImageView,

2382
01:38:18,066 --> 01:38:22,266
turns out that a UIImageView has
a property called image whose

2383
01:38:22,266 --> 01:38:25,176
value is a pointer to a...

2384
01:38:25,756 --> 01:38:25,876
>> UI.

2385
01:38:26,076 --> 01:38:27,926
>> UIImageObject, apparently.

2386
01:38:27,926 --> 01:38:30,086
We've not seen this before,
but you can now it reader

2387
01:38:30,086 --> 01:38:31,906
from the code itself, so this --

2388
01:38:32,266 --> 01:38:34,356
this class here is
called UIImage.

2389
01:38:34,636 --> 01:38:38,696
Turns out it has a Convenience
Method called image name whereby

2390
01:38:38,736 --> 01:38:42,576
if I get the I'th Rob
at the current index,

2391
01:38:42,576 --> 01:38:45,486
so give me Rob's bracket
zero, but do it dynamically

2392
01:38:45,486 --> 01:38:48,616
in code here, that is going
to give me an Image Object,

2393
01:38:48,616 --> 01:38:52,116
UI image with Rob, and I'm going
to plop it into the carousel,

2394
01:38:52,116 --> 01:38:54,116
essentially, the
UIImageView that allows me

2395
01:38:54,116 --> 01:38:56,456
to show the image to someone.

2396
01:38:57,156 --> 01:39:00,316
So now I'm going to listen
for presses on Rob's image.

2397
01:39:00,566 --> 01:39:02,046
So code's a little ugly,

2398
01:39:02,046 --> 01:39:04,686
but what I'm doing is declaring
a pointer called Long Press

2399
01:39:04,686 --> 01:39:07,676
Gesture of type UI Long
Press Gesture Recognizer.

2400
01:39:08,146 --> 01:39:09,736
I am assigning it
the return value

2401
01:39:09,736 --> 01:39:12,776
of calling UI Long Press
Gesture Recognizer Ella,

2402
01:39:12,996 --> 01:39:14,506
so just give me one
of these recognizers.

2403
01:39:14,996 --> 01:39:16,816
I'm initializing
it with a target.

2404
01:39:17,326 --> 01:39:19,106
Self, we'll come back
to than a second.

2405
01:39:19,366 --> 01:39:21,656
Action called Handle Long Press.

2406
01:39:22,356 --> 01:39:27,886
So in layman's terms, this is
listening for a long press,

2407
01:39:28,606 --> 01:39:30,366
but in slightly more
technical terms,

2408
01:39:30,406 --> 01:39:35,196
what are we telling the UI long
press gesture recognizer object

2409
01:39:35,296 --> 01:39:37,786
exactly with in it with
target and action here?

2410
01:39:37,836 --> 01:39:47,226
>> First you're saying
that the message to be sent

2411
01:39:47,226 --> 01:39:50,846
when the long press happens
is Handle Long Press.

2412
01:39:50,876 --> 01:39:50,966
>> Good.

2413
01:39:50,996 --> 01:39:52,166
>> And you're also saying
you should send that message

2414
01:39:52,196 --> 01:39:52,976
to self, so the View Controller.

2415
01:39:53,266 --> 01:39:53,886
>> Exactly.

2416
01:39:53,886 --> 01:39:59,306
So this, again to recap, means
when you detect a UI long press,

2417
01:39:59,306 --> 01:40:01,316
a couple seconds down
with your finger,

2418
01:40:01,556 --> 01:40:03,426
send the message
Handle Long Press,

2419
01:40:03,426 --> 01:40:04,456
which could've been
named anything.

2420
01:40:04,456 --> 01:40:08,726
I came up with that method, but
pass it to specifically myself,

2421
01:40:08,916 --> 01:40:10,136
the same ViewController.

2422
01:40:10,286 --> 01:40:11,976
And that's why the
method earlier

2423
01:40:11,976 --> 01:40:16,246
in the file is indeed invoked
when we hold down the --

2424
01:40:16,246 --> 01:40:23,056
when we hold down ones finger
and call Handle Long Press.

2425
01:40:23,396 --> 01:40:26,496
So the other recognizers, let's
see first before we see them

2426
01:40:26,496 --> 01:40:29,406
in action one last time,
listen for right swipe.

2427
01:40:29,696 --> 01:40:30,546
So how do I do this?

2428
01:40:30,896 --> 01:40:31,376
Same idea.

2429
01:40:31,516 --> 01:40:34,626
I allocated UI Swipe
Gesture Recognizer.

2430
01:40:34,796 --> 01:40:36,286
I initialize it with
Target Self,

2431
01:40:36,456 --> 01:40:38,706
and this time I tell
it Call Handle Swipe

2432
01:40:39,056 --> 01:40:41,166
when the user swipes
from a certain direction.

2433
01:40:41,166 --> 01:40:42,536
But what direction is that?

2434
01:40:42,536 --> 01:40:44,806
In this case, I have to
do one additional step.

2435
01:40:44,806 --> 01:40:47,396
I have to specify the
direction, and according

2436
01:40:47,396 --> 01:40:48,506
to the documentation,

2437
01:40:48,506 --> 01:40:51,236
swipe gestures have
a direction property

2438
01:40:51,416 --> 01:40:54,506
and this crazy long
constant is what specifies.

2439
01:40:54,506 --> 01:40:56,936
When I go from right to left,

2440
01:40:57,006 --> 01:40:59,856
essentially this is what
should actually happen.

2441
01:40:59,856 --> 01:41:00,536
What should happen?

2442
01:41:00,766 --> 01:41:04,176
Well, here is how we
add to an ImageView,

2443
01:41:04,176 --> 01:41:06,596
just like we did a few lines
ago for the long press,

2444
01:41:06,966 --> 01:41:11,106
this is how we add a recognizer
to an existing view object

2445
01:41:11,436 --> 01:41:13,076
that is on this screen.

2446
01:41:13,146 --> 01:41:15,366
You create this recognizer,
and you sort of glue it

2447
01:41:15,366 --> 01:41:16,946
down onto the view so that

2448
01:41:16,946 --> 01:41:19,406
that view triggers
these various actions.

2449
01:41:19,806 --> 01:41:20,706
Listen for left swipe.

2450
01:41:21,326 --> 01:41:23,326
I've done that with a
separate line of code

2451
01:41:23,326 --> 01:41:25,786
at the end there just
by changing the constant

2452
01:41:25,826 --> 01:41:28,146
to be this, and that's so that
we can swipe right to left,

2453
01:41:28,556 --> 01:41:31,636
or left to right, to increment
or decrement the Robs.

2454
01:41:31,886 --> 01:41:35,956
And if we go back up here,
let's look at the code.

2455
01:41:35,956 --> 01:41:38,996
Let me fix this.

2456
01:41:38,996 --> 01:41:40,356
Rob we swapped in this year.

2457
01:41:41,046 --> 01:41:43,566
Handle Swipe works how?

2458
01:41:43,566 --> 01:41:45,436
So this is the method that's
called when we swipe right

2459
01:41:45,436 --> 01:41:46,466
to left, left to right.

2460
01:41:46,746 --> 01:41:48,626
This is how we figure
out the direction.

2461
01:41:48,916 --> 01:41:51,316
We ask the recognizer
that was passed

2462
01:41:51,316 --> 01:41:54,136
in via the sender argument
what direction was --

2463
01:41:54,576 --> 01:41:55,346
were you sent in.

2464
01:41:55,576 --> 01:41:57,496
I'm using a switch,
which is like an If Else,

2465
01:41:57,616 --> 01:42:00,196
but just done slightly
differently syntactically,

2466
01:42:00,586 --> 01:42:01,636
I decided to do this.

2467
01:42:02,056 --> 01:42:05,646
If the user has swiped up
down or down up, do nothing.

2468
01:42:05,886 --> 01:42:08,026
Now technically, these lines
of code do nothing useful.

2469
01:42:08,026 --> 01:42:09,916
I just left it there
for explicitness sake,

2470
01:42:09,916 --> 01:42:10,916
but it immediately breaks

2471
01:42:10,916 --> 01:42:12,516
which means there's
no effect whatsoever.

2472
01:42:12,756 --> 01:42:15,996
Meanwhile the direction left,
down here, has to do a bit

2473
01:42:15,996 --> 01:42:18,276
of math, and it took a moment
to kind of think about this,

2474
01:42:18,546 --> 01:42:21,416
but I'm updating the index value
to be, when I go from right

2475
01:42:21,416 --> 01:42:24,286
to left, plus one, and
then I need to wrap

2476
01:42:24,286 --> 01:42:26,276
around with some
modular arithmetic based

2477
01:42:26,276 --> 01:42:27,516
on the length of the array.

2478
01:42:27,956 --> 01:42:30,586
Down here meanwhile,
if I wanted to wrap

2479
01:42:30,586 --> 01:42:34,536
around to the other direction,
I had to effectively subtract

2480
01:42:34,676 --> 01:42:37,396
by one, but I wanted to make
sure that we didn't go negative,

2481
01:42:37,446 --> 01:42:39,956
so I also have some addition
in there just to make sure

2482
01:42:39,956 --> 01:42:44,086
that two goes to one, one goes
to zero, zero goes to two,

2483
01:42:44,086 --> 01:42:45,796
and doesn't accidentally
go negative.

2484
01:42:45,796 --> 01:42:48,656
So just some basic
modular arithmetic there.

2485
01:42:48,656 --> 01:42:51,456
And then lastly, what
actually updates Rob,

2486
01:42:51,456 --> 01:42:55,096
and updates him instantly, is to
change the property called Image

2487
01:42:55,096 --> 01:42:59,906
of the ImageView IDOutlets to
the image named whatever Rob is

2488
01:42:59,906 --> 01:43:02,136
at that particular index.

2489
01:43:02,716 --> 01:43:04,306
So could have implemented
this in different ways.

2490
01:43:04,306 --> 01:43:06,896
Could have stored the actual
images in an array as opposed

2491
01:43:06,896 --> 01:43:08,956
to the file names, but we
kept it simple in this way

2492
01:43:08,956 --> 01:43:10,976
so that we could actually
see the strings explicitly

2493
01:43:10,976 --> 01:43:13,376
in the code, but this is how
we can now start listening

2494
01:43:13,376 --> 01:43:15,586
for these things, and any of
these kind of interactions,

2495
01:43:15,616 --> 01:43:17,146
pinching and zooming
and rotating,

2496
01:43:17,416 --> 01:43:19,986
is implemented similarly
by implementing one or more

2497
01:43:19,986 --> 01:43:22,526
of these recognizers, and
then responding accordingly.

2498
01:43:23,396 --> 01:43:26,176
>> Is this a handle that we
have for competing recognizers,

2499
01:43:26,226 --> 01:43:31,326
say at -- for the long tap,
and actually it's a tap

2500
01:43:31,386 --> 01:43:35,456
and it's a long tap because
it only triggers long taps?

2501
01:43:35,456 --> 01:43:38,296
>> So in that case, if you're
detecting tap versus long tap,

2502
01:43:38,296 --> 01:43:40,926
if you're holding long enough,
it will only be a long tap.

2503
01:43:41,096 --> 01:43:43,686
That's what defines it as long,
holding it slightly too long.

2504
01:43:43,836 --> 01:43:45,586
If you do it within the
window, and I think it's one

2505
01:43:45,586 --> 01:43:46,826
or two seconds, that
would be a tap.

2506
01:43:47,546 --> 01:43:49,576
But you won't get both of
you're holding down like that.

2507
01:43:49,666 --> 01:43:50,706
You'll just get the long tap.

2508
01:43:50,896 --> 01:43:51,956
>> So there's no way

2509
01:43:52,166 --> 01:43:55,246
that property gesture
called [inaudible]?

2510
01:43:56,156 --> 01:43:59,146
>> You could potentially
induce multiple ones.

2511
01:43:59,586 --> 01:44:02,846
You can give priority to
them effectively by listening

2512
01:44:02,846 --> 01:44:05,386
to which one fires first, and
you can think of this again

2513
01:44:05,386 --> 01:44:07,696
as layers, as to
which layer is going

2514
01:44:07,696 --> 01:44:10,166
to receive the gesture first

2515
01:44:10,166 --> 01:44:11,846
if you've added to
multiple objects.

2516
01:44:12,216 --> 01:44:15,576
But for the case you describe,
they'd be mutually exclusive.

2517
01:44:16,076 --> 01:44:18,516
Other questions?

2518
01:44:19,076 --> 01:44:25,596
So out of curiosity, how many
people are leaning toward web

2519
01:44:25,596 --> 01:44:28,046
applications for their third
and final choice of projects?

2520
01:44:28,786 --> 01:44:30,686
Did I give a bad answer there?

2521
01:44:30,686 --> 01:44:31,876
Okay. All right, a few.

2522
01:44:31,876 --> 01:44:33,406
And iOS applications?

2523
01:44:34,536 --> 01:44:36,366
And undecided?

2524
01:44:37,406 --> 01:44:39,406
Okay. So not -- not bad.

2525
01:44:39,766 --> 01:44:42,336
So start thinking about that,
even though I know you're

2526
01:44:42,336 --> 01:44:44,996
in the midst of Evil Hangman,
but you'll soon get feedback

2527
01:44:44,996 --> 01:44:46,646
by this Wednesday from
the teaching fellows

2528
01:44:46,646 --> 01:44:49,106
on the mobile local projects,
so you can start thinking

2529
01:44:49,106 --> 01:44:50,916
about what you could've
done better there,

2530
01:44:50,916 --> 01:44:52,786
how you might do things
differently for a third

2531
01:44:52,786 --> 01:44:55,346
and final project if you go
with HTML 5 and JavaScript.

2532
01:44:55,346 --> 01:44:57,716
Also think about the native
applications and again,

2533
01:44:57,816 --> 01:45:00,006
when the specification goes
up, you'll see that step one is

2534
01:45:00,006 --> 01:45:03,476
to float the idea by your
TF, and he will confirm

2535
01:45:03,476 --> 01:45:05,066
or deny the appropriateness,

2536
01:45:05,066 --> 01:45:06,726
the viability given
the limited time,

2537
01:45:06,726 --> 01:45:08,426
and will help guide you toward
something that's doable,

2538
01:45:08,656 --> 01:45:10,946
so that in a few weeks' time,
we'll all have some cake

2539
01:45:10,946 --> 01:45:12,556
and some exhibitions
the projects.

2540
01:45:12,636 --> 01:45:13,506
Why don't we call
it a night here,

2541
01:45:13,506 --> 01:45:14,526
and I'll stick around
for questions.

2542
01:45:15,076 --> 01:45:15,646
See you at lab.

2543
01:45:16,516 --> 01:45:23,410
[ Silence ]

