1
00:00:00,506 --> 00:00:07,496
[ Silence ]

2
00:00:07,996 --> 00:00:08,496
>> David J. Malan: All right.

3
00:00:08,496 --> 00:00:09,086
We are back.

4
00:00:09,086 --> 00:00:11,406
So T minus one lectures to go.

5
00:00:11,406 --> 00:00:14,786
Tonight we finish our look at
iOS and some of the features

6
00:00:14,786 --> 00:00:16,046
that we've hinted at thus far.

7
00:00:16,186 --> 00:00:18,316
And that might empower you
to do some pretty cool things

8
00:00:18,316 --> 00:00:20,626
with your third and
final project.

9
00:00:20,626 --> 00:00:22,956
In fact, looking
ahead to exactly that,

10
00:00:23,306 --> 00:00:26,806
on Wednesday August
7th in lieu of lecture,

11
00:00:26,806 --> 00:00:29,256
we'll have an App Party of sorts
where [inaudible] will convene

12
00:00:29,256 --> 00:00:31,856
across the hall where
labs usually are held.

13
00:00:31,856 --> 00:00:34,166
We'll bring in some snacks
and food and whatnot.

14
00:00:34,166 --> 00:00:36,656
And you'll bring your
laptops and or iOS devices

15
00:00:36,656 --> 00:00:38,336
and the goal would
be to spend an hour

16
00:00:38,336 --> 00:00:41,396
or so exhibiting each other's
work and chatting and sort

17
00:00:41,396 --> 00:00:42,846
of did he briefing
how the semester went.

18
00:00:43,166 --> 00:00:47,276
And showing off what your,
hopefully, quite proud of.

19
00:00:47,276 --> 00:00:48,586
Whether that's your
final project

20
00:00:48,586 --> 00:00:50,046
or either of the prior two.

21
00:00:50,326 --> 00:00:51,696
And leading up to
that, next Monday,

22
00:00:51,696 --> 00:00:53,306
will be a couple
of guest lectures.

23
00:00:53,306 --> 00:00:54,856
So I and all the
TF's will be here.

24
00:00:54,856 --> 00:00:56,716
But we'd thought we'd
invite a couple of friends.

25
00:00:56,716 --> 00:00:58,266
One is a fellow named
Dan Armadorez,

26
00:00:58,306 --> 00:01:00,476
who used to could teach
this class and taught

27
00:01:00,476 --> 00:01:01,896
in android aspect of it.

28
00:01:01,896 --> 00:01:03,876
What we thought was we'd
give everybody some exposure

29
00:01:03,876 --> 00:01:05,976
to what android programming
is like what's similar,

30
00:01:05,976 --> 00:01:08,596
what's different so that you
can scratch that surface to see

31
00:01:08,596 --> 00:01:09,776
if that's a direction that's
a direction you'd might

32
00:01:09,776 --> 00:01:10,396
like to go in next.

33
00:01:10,396 --> 00:01:11,426
And also we'll have
a friend of ours

34
00:01:11,426 --> 00:01:14,646
from Microsoft Bob
Familiar joins us to talk

35
00:01:14,646 --> 00:01:16,296
about windows mobile
programming.

36
00:01:16,296 --> 00:01:18,206
Taking a look at how you
might do it with C sharp,

37
00:01:18,206 --> 00:01:20,846
which is Microsoft's
language for desktop

38
00:01:20,846 --> 00:01:22,156
and mobile programming as well

39
00:01:22,156 --> 00:01:24,726
as how you might also
do it using HTML 5's.

40
00:01:24,726 --> 00:01:26,706
So that'll be our final
glance for the semester.

41
00:01:26,706 --> 00:01:29,476
And we'll also tie up loose ends
with iOS and give you a sense

42
00:01:29,476 --> 00:01:30,596
of where you can go from here

43
00:01:30,596 --> 00:01:31,786
around what you might
want to keep in mind.

44
00:01:31,786 --> 00:01:33,136
So that once the
training wheels are off,

45
00:01:33,286 --> 00:01:36,206
you can actually create
some cool things on your own

46
00:01:36,206 --> 00:01:37,646
if indeed of interest.

47
00:01:38,016 --> 00:01:40,226
So with that said,
how would we go

48
00:01:40,226 --> 00:01:42,536
about making something
like this?

49
00:01:43,016 --> 00:01:45,476
So we saw our first application
last week involving Rob

50
00:01:45,476 --> 00:01:46,136
last week.

51
00:01:46,136 --> 00:01:47,686
And what were the
features we implemented

52
00:01:47,686 --> 00:01:52,056
to top Rob's three
photos last time?

53
00:01:52,056 --> 00:01:53,896
Yes? Gesture.

54
00:01:53,896 --> 00:01:55,296
So we had a couple of gestures.

55
00:01:55,296 --> 00:01:58,236
We were able to swipe from
left to right to move Rob

56
00:01:58,276 --> 00:01:59,376
from one side to the other.

57
00:01:59,376 --> 00:02:01,456
Or right to left in order to pan

58
00:02:01,506 --> 00:02:02,996
through his three
Facebook photos.

59
00:02:02,996 --> 00:02:05,176
Thank you for sending him
those Facebook friend request

60
00:02:05,176 --> 00:02:06,506
so quickly incidental ly.

61
00:02:06,976 --> 00:02:08,486
And we also had one
other feature

62
00:02:08,486 --> 00:02:11,956
that we implemented
atop Rob's face.

63
00:02:12,096 --> 00:02:13,386
Which was what?

64
00:02:14,016 --> 00:02:15,206
Alert, okay.

65
00:02:15,206 --> 00:02:16,346
But we've seen alerts before.

66
00:02:16,346 --> 00:02:19,086
How did we trigger
that alert last time?

67
00:02:19,376 --> 00:02:21,756
Yes, so touching
down or a long press.

68
00:02:21,756 --> 00:02:23,906
Or if you hold for a
good second or two,

69
00:02:24,086 --> 00:02:25,756
that is the separate
event that's fired

70
00:02:25,756 --> 00:02:26,756
that we call encode.

71
00:02:26,756 --> 00:02:29,226
And we said, "Hey, stop
that," or something similar.

72
00:02:29,226 --> 00:02:30,416
So we had two such gestures.

73
00:02:30,416 --> 00:02:31,846
But we really didn't do a couple

74
00:02:31,846 --> 00:02:35,886
of the more familiar mechanisms
whereby I might, for instance,

75
00:02:35,886 --> 00:02:37,236
want to just move
something around.

76
00:02:37,586 --> 00:02:39,886
Now this is a little
underwhelming on a back drop.

77
00:02:39,886 --> 00:02:43,896
But because this is rectangular,
you can imagine having images

78
00:02:43,896 --> 00:02:45,666
or shapes of some sort
where it makes sense

79
00:02:45,666 --> 00:02:47,166
to actually move
these things around.

80
00:02:47,166 --> 00:02:50,376
And in fact, where it will end
tonight is actually looking

81
00:02:50,376 --> 00:02:51,756
at how to do this
programmatically.

82
00:02:51,756 --> 00:02:54,416
How do you create two
dimensional graphics that move

83
00:02:54,416 --> 00:02:56,856
in response to user's
action or to just move

84
00:02:56,856 --> 00:02:58,586
around on the screen
on their own.

85
00:02:58,786 --> 00:03:00,476
So this is a translation
of sorts.

86
00:03:00,476 --> 00:03:01,996
Moving up down or left or right.

87
00:03:02,196 --> 00:03:04,016
But you can also
do in the simulator

88
00:03:04,046 --> 00:03:06,436
if you hold option you'll see

89
00:03:06,436 --> 00:03:10,066
that my cursor flanked
by a second circle.

90
00:03:10,066 --> 00:03:11,666
And these represent two fingers.

91
00:03:11,666 --> 00:03:13,366
So you can actually mimic
the idea of pinching,

92
00:03:13,366 --> 00:03:15,146
even though you can't
touch your laptop screens.

93
00:03:15,276 --> 00:03:16,506
And if we do this, we can zoom

94
00:03:16,506 --> 00:03:20,446
in on Rob's denim shirt
atop denim shorts.

95
00:03:20,756 --> 00:03:24,126
And or we can zoom out
until this image gets super

96
00:03:24,126 --> 00:03:24,776
super small.

97
00:03:24,776 --> 00:03:26,396
Much like you might
pinch or zoom in maps,

98
00:03:26,486 --> 00:03:27,866
or Google Maps or the like.

99
00:03:28,216 --> 00:03:28,916
So, how would we go

100
00:03:28,916 --> 00:03:31,486
about implementing
something like this?

101
00:03:31,486 --> 00:03:34,566
Well, let's take a look at
some basic building blocks.

102
00:03:34,566 --> 00:03:36,776
And we'll see some similarities
and some differences.

103
00:03:36,776 --> 00:03:40,976
This is the more complex of the
ones we looked at last time.

104
00:03:41,256 --> 00:03:42,946
So AppDelegate is a
good place to start.

105
00:03:42,946 --> 00:03:44,856
Main dot M never seems to
have anything of interest,

106
00:03:44,856 --> 00:03:46,596
so we won't even
glance there for now.

107
00:03:46,596 --> 00:03:48,426
Does anything look anomalous?

108
00:03:48,426 --> 00:03:49,486
New? Different?

109
00:03:50,556 --> 00:03:52,896
In this file versus
past examples?

110
00:03:53,116 --> 00:03:54,926
This is the AppDelegate.h file.

111
00:03:55,936 --> 00:03:57,116
No? Nothing magical there.

112
00:03:57,116 --> 00:03:58,856
This is just a boiler
play code that you get

113
00:03:58,856 --> 00:04:00,186
with the single view
application.

114
00:04:00,186 --> 00:04:02,736
How about the dot M
file if I scroll down.

115
00:04:02,736 --> 00:04:04,076
Looks like this is
the only method.

116
00:04:04,426 --> 00:04:06,616
Anything interesting,
new or different there?

117
00:04:07,426 --> 00:04:08,666
No. But it seems to be this guy

118
00:04:08,666 --> 00:04:11,026
as usual that's kick starting
the process by assigning

119
00:04:11,026 --> 00:04:14,166
to view controller, a
newly allocated controller.

120
00:04:14,436 --> 00:04:17,146
It's being initialized
with a nib view controller.

121
00:04:17,286 --> 00:04:19,986
There's no file extension, but
recall that that's by default

122
00:04:19,986 --> 00:04:22,876
by referring to the dot XIB file
that we had for some time now.

123
00:04:23,086 --> 00:04:25,546
And then finally we're making
it the key window and visible,

124
00:04:25,546 --> 00:04:26,616
which means foregrounds,

125
00:04:26,826 --> 00:04:28,646
whatever the contents
of that nib were.

126
00:04:28,816 --> 00:04:29,866
Well, what is that nib?

127
00:04:30,006 --> 00:04:34,596
Let's take a look in the
XIB file and we see Rob.

128
00:04:34,596 --> 00:04:36,216
For a moment in flash,
for just a moment,

129
00:04:36,216 --> 00:04:37,436
because that's actually
there's a couple

130
00:04:37,436 --> 00:04:38,726
of objects layered on here.

131
00:04:38,726 --> 00:04:42,656
And we can see this by zoom
in and I click on view.

132
00:04:42,826 --> 00:04:46,556
Recall that view a UI view
is is the rectangular shape

133
00:04:46,556 --> 00:04:47,896
that we typically lay down.

134
00:04:48,156 --> 00:04:49,396
And we have an image view.

135
00:04:49,716 --> 00:04:51,706
So, this is actually
a different class

136
00:04:51,706 --> 00:04:53,066
that we haven't seen before.

137
00:04:53,066 --> 00:04:55,226
If I pull over inspectors
over here on the right,

138
00:04:55,596 --> 00:04:59,046
and choose my identity
inspector,

139
00:04:59,266 --> 00:05:01,146
you'll see that this
is a UI image view.

140
00:05:01,146 --> 00:05:03,806
And this is like a
container for actual images.

141
00:05:03,806 --> 00:05:05,576
And those images as we'll
see in a second are going

142
00:05:05,576 --> 00:05:08,076
to take the form of
UI image objects.

143
00:05:08,326 --> 00:05:11,666
So let's actually see how
we now started listening

144
00:05:11,666 --> 00:05:14,836
for event atop Rob's
single photo there.

145
00:05:14,996 --> 00:05:17,136
Well first, let me
expand supporting files.

146
00:05:17,496 --> 00:05:20,946
There is the photo, Rob.jpeg,
that I configured here.

147
00:05:20,946 --> 00:05:23,826
And indeed if we go back to
the inspector just to confirm,

148
00:05:23,826 --> 00:05:25,826
let me go up to the
attributes inspector.

149
00:05:26,056 --> 00:05:28,636
The fact that it says rob.jpeg
on the top right corner,

150
00:05:28,636 --> 00:05:30,856
that just means that's why
the imagery was displaying

151
00:05:30,856 --> 00:05:31,936
that image.

152
00:05:32,246 --> 00:05:33,256
So no magic there.

153
00:05:33,256 --> 00:05:36,586
So is the complexity must
be in this guide, no,

154
00:05:36,646 --> 00:05:37,846
not in the view controller.

155
00:05:38,016 --> 00:05:41,666
H or the one remaining
candidate view controller.

156
00:05:41,666 --> 00:05:45,336
M. So let's see if we
can't wrap our minds

157
00:05:45,336 --> 00:05:46,496
around what's going on here.

158
00:05:46,496 --> 00:05:48,306
First, a couple of teasers.

159
00:05:48,306 --> 00:05:50,246
So this up here is
an example of what?

160
00:05:51,046 --> 00:05:52,646
What object of the construct?

161
00:05:52,646 --> 00:05:57,536
Yes? Yes, so it's a category.

162
00:05:57,536 --> 00:05:59,666
It's a nameless category
because there's nothing inside

163
00:05:59,666 --> 00:06:00,466
the parentheses.

164
00:06:00,466 --> 00:06:04,326
And it's a way of sort of
creating the illusion of privacy

165
00:06:04,326 --> 00:06:07,986
and objective C whereby we have
apparently a private data member

166
00:06:07,986 --> 00:06:11,446
called a CG point
underscore translation.

167
00:06:11,686 --> 00:06:13,936
And CG point is actually
something

168
00:06:13,936 --> 00:06:15,566
from the core's graphics
library.

169
00:06:15,566 --> 00:06:18,236
So CG, core graphics, this is
referring to Apple's support

170
00:06:18,236 --> 00:06:19,506
for two dimensional graphics.

171
00:06:19,816 --> 00:06:22,426
And we'll see that this is
actually a primitive of sorts.

172
00:06:22,426 --> 00:06:25,816
It's not actually an object
because a lot of the code you're

173
00:06:25,816 --> 00:06:29,106
about to see in two dimensional
graphics actually has its

174
00:06:29,106 --> 00:06:30,316
origins and seeds.

175
00:06:30,316 --> 00:06:32,686
So we're going to start seeing
some commingling of objective C

176
00:06:32,966 --> 00:06:35,126
and C, which is the language
they'll call you to look

177
00:06:35,126 --> 00:06:38,136
at when Rob was at the
[inaudible] a few weeks back.

178
00:06:38,556 --> 00:06:40,516
So we have a couple
of properties in here.

179
00:06:40,516 --> 00:06:42,366
One is a float called scale.

180
00:06:42,576 --> 00:06:46,156
And one is an image view, a UI
image view called image view.

181
00:06:46,156 --> 00:06:47,946
And we'll come back to
that in just a moment.

182
00:06:47,946 --> 00:06:50,296
We seem to have a couple
of private methods here,

183
00:06:50,296 --> 00:06:53,596
one is called handle pan, so
moving left to right, up, down.

184
00:06:53,896 --> 00:06:56,456
And handle pinch, which
is the two finger gesture.

185
00:06:56,686 --> 00:07:00,166
So that's just setting the stage
now to listen for those events.

186
00:07:00,166 --> 00:07:03,036
And if we scroll down here,
what seems to be going on?

187
00:07:03,036 --> 00:07:04,296
But when is this yes?

188
00:07:04,706 --> 00:07:15,896
Is there any reason to use
an instance variable rather

189
00:07:15,896 --> 00:07:18,016
than a property?

190
00:07:18,346 --> 00:07:21,826
That's a good question.

191
00:07:21,826 --> 00:07:26,056
What was the motivation
for this.

192
00:07:26,196 --> 00:07:30,866
You can still do primitive.

193
00:07:30,866 --> 00:07:33,236
Short answer I don't think yes?

194
00:07:34,926 --> 00:07:40,986
Yes, no that's true.

195
00:07:40,986 --> 00:07:44,376
But I'm at the same time not
doing the same when it comes

196
00:07:44,376 --> 00:07:46,806
to scale and image
view necessarily.

197
00:07:47,146 --> 00:07:50,226
Let me think about why we
did this the way it is,

198
00:07:50,226 --> 00:07:52,646
but short answer doesn't
matter in this way.

199
00:07:52,646 --> 00:07:54,926
We don't need the functionality
of the setter or getter.

200
00:07:55,446 --> 00:07:56,206
Pretty good question.

201
00:07:56,206 --> 00:07:57,836
I'll come back to it.

202
00:07:57,836 --> 00:07:59,426
All right so, in
initWithNibName.

203
00:07:59,426 --> 00:08:01,036
This is the first method
that's invoked here.

204
00:08:01,146 --> 00:08:04,016
And the ininitWithNibName seems
to be preparing a few things.

205
00:08:04,016 --> 00:08:05,596
So one it's calling
the super class,

206
00:08:05,596 --> 00:08:08,096
which is actually doing
the loading from that.

207
00:08:08,096 --> 00:08:10,676
XIB file, which is the
normal default case.

208
00:08:11,076 --> 00:08:13,606
And then we're apparently
setting a property called scale

209
00:08:13,936 --> 00:08:14,916
to 1.0.

210
00:08:15,066 --> 00:08:17,356
And that's just a default
reminder that by default,

211
00:08:17,356 --> 00:08:18,516
Rob is at normal scale.

212
00:08:18,516 --> 00:08:21,436
A hundred percent X, a hundred
percent Y there's no zooming

213
00:08:21,436 --> 00:08:22,236
in or out.

214
00:08:22,236 --> 00:08:23,726
And the translation X

215
00:08:23,726 --> 00:08:26,896
and translation Y is
referring oh, this is why.

216
00:08:27,456 --> 00:08:30,926
So, the reason that
I'm using the

217
00:08:30,926 --> 00:08:34,756
so CG point is actually
something called a C struct,

218
00:08:35,116 --> 00:08:37,296
which you may call it
glancing at and see.

219
00:08:37,296 --> 00:08:38,686
And just kind of like an object

220
00:08:39,016 --> 00:08:41,086
that doesn't have methods
associated with it.

221
00:08:41,086 --> 00:08:42,716
It's just a data
container for data.

222
00:08:43,036 --> 00:08:45,746
So problems actually arise
because Apple goes to use the.

223
00:08:45,746 --> 00:08:48,256
Operator when it
came to properties.

224
00:08:48,256 --> 00:08:50,886
But the. Operator's is
also used for structs.

225
00:08:51,206 --> 00:08:53,376
So doing it this way
ensures there's other clarity

226
00:08:53,376 --> 00:08:54,376
as to what's going on.

227
00:08:54,376 --> 00:08:57,526
In this particular line here,
that's highlighted in blue,

228
00:08:57,616 --> 00:09:01,776
I'm accessing the X member
of the CG point struck.

229
00:09:01,776 --> 00:09:05,056
And I'm doing then the same for
Y. So things get a little messy

230
00:09:05,056 --> 00:09:06,926
if you start commingling
the two features.

231
00:09:07,086 --> 00:09:08,316
Get back to this.

232
00:09:08,576 --> 00:09:10,076
Okay, so translation X,

233
00:09:10,076 --> 00:09:12,006
translation Y. A translation
is just a shifting.

234
00:09:12,006 --> 00:09:13,886
Up, down, left or
right or some diagonal.

235
00:09:13,886 --> 00:09:15,736
And this is implying by default.

236
00:09:15,976 --> 00:09:18,036
Rob has not been shifted
up, down, left or right.

237
00:09:18,036 --> 00:09:20,026
He's just smack dab in
the middle of the screen.

238
00:09:20,226 --> 00:09:22,496
So these are initializations
of variables.

239
00:09:22,856 --> 00:09:24,546
So now, a few things
are going on.

240
00:09:24,546 --> 00:09:26,396
There's a handle pan
method apparently.

241
00:09:26,856 --> 00:09:28,496
There's a handle pinch method.

242
00:09:28,726 --> 00:09:31,786
There's a view did load, let's
actually go to view did load

243
00:09:32,016 --> 00:09:34,456
down here and let me hide this

244
00:09:34,456 --> 00:09:35,996
so we can just focus
on these three.

245
00:09:36,276 --> 00:09:39,346
View did load recalls loaded,
once the nib has been loaded.

246
00:09:39,346 --> 00:09:40,926
The view is ready
to go in memory.

247
00:09:41,136 --> 00:09:43,306
And as the common suggest,
we're listening for two things.

248
00:09:43,306 --> 00:09:45,636
A pan from left to
right, or top to bottom,

249
00:09:45,636 --> 00:09:47,616
or bottom or top, down.

250
00:09:47,956 --> 00:09:49,796
Or a pitch with two fingers.

251
00:09:50,016 --> 00:09:52,396
And this is code quite
like we saw last week.

252
00:09:52,396 --> 00:09:55,236
We initialized a certain
type of recognizer.

253
00:09:55,736 --> 00:09:58,006
We initialized it
with a target that has

254
00:09:58,006 --> 00:10:00,466
to be self in this case.

255
00:10:00,466 --> 00:10:02,926
Self is referring to an object
of what type at the moment.

256
00:10:03,416 --> 00:10:04,806
Who is self?

257
00:10:04,806 --> 00:10:06,896
The view controller.

258
00:10:06,896 --> 00:10:10,526
So presumably whatever method,
we are telling recognizer

259
00:10:10,526 --> 00:10:14,726
to invoke when panning happens
is somewhere in this class.

260
00:10:14,726 --> 00:10:16,266
And indeed it's higher
up in the file.

261
00:10:16,486 --> 00:10:19,386
And in this selector syntax
is just our way of saying,

262
00:10:19,596 --> 00:10:21,576
call the method handle pan.

263
00:10:21,576 --> 00:10:23,716
And call in just means it
takes that one argument.

264
00:10:23,716 --> 00:10:25,776
And then over here, what
are we actually doing?

265
00:10:25,776 --> 00:10:26,846
Well, notice that self.

266
00:10:26,926 --> 00:10:30,646
Image view is our property that
maps via interfere builder.

267
00:10:30,646 --> 00:10:33,696
I drag and drop the little
blue line connecting IB outlet

268
00:10:33,696 --> 00:10:34,266
to my nib.

269
00:10:34,676 --> 00:10:36,866
This is saying, add
that recognizer

270
00:10:36,866 --> 00:10:39,746
to that view object
on the screen.

271
00:10:39,746 --> 00:10:41,766
So that is the rectangular
shape that's going

272
00:10:41,766 --> 00:10:43,176
to listen for this pan gesture.

273
00:10:43,736 --> 00:10:46,276
And pinching, essentially
the same thing.

274
00:10:47,536 --> 00:10:49,606
Any questions on
how we set that up?

275
00:10:50,256 --> 00:10:53,066
Thinking back that again
the structure is the same

276
00:10:53,066 --> 00:10:53,816
as last week.

277
00:10:54,136 --> 00:10:58,516
No? Okay. All right.

278
00:10:58,786 --> 00:11:01,896
So now let's look at the part
that does all of the thinking.

279
00:11:02,146 --> 00:11:03,746
So handle pan.

280
00:11:03,746 --> 00:11:05,816
This is where it gets
a little complex.

281
00:11:06,106 --> 00:11:08,226
But this is just the
result of reading

282
00:11:08,226 --> 00:11:10,436
through what exactly each
of these functions does.

283
00:11:10,436 --> 00:11:12,556
A lot of this is again
C. And the first thing

284
00:11:12,556 --> 00:11:16,056
that happens here is
that we first request

285
00:11:16,236 --> 00:11:20,956
from the UI image view, that
container containing the image.

286
00:11:21,226 --> 00:11:23,996
Something called CG
point translation.

287
00:11:23,996 --> 00:11:26,556
So this is essentially
0 comma 0 by default.

288
00:11:26,556 --> 00:11:28,476
And then the next
line we're making an

289
00:11:28,806 --> 00:11:31,236
AffineTransformMakeScale,
which is essentially saying

290
00:11:31,386 --> 00:11:33,296
by how much do you not to grow

291
00:11:33,296 --> 00:11:36,406
or shrink Rob along
the X and the Y axis.

292
00:11:37,106 --> 00:11:40,116
And then we go ahead and
ask to make a translation.

293
00:11:40,116 --> 00:11:43,616
Translation refers to by how
much you want to shift Rob,

294
00:11:43,616 --> 00:11:46,856
to the right, to the left, up
or down or along some diagonal

295
00:11:46,956 --> 00:11:48,776
by adding those two
axes together.

296
00:11:49,186 --> 00:11:50,796
And then lastly, this last line

297
00:11:50,796 --> 00:11:54,126
of code actually applies
that transformation.

298
00:11:54,466 --> 00:11:57,976
That changing in scale, bigger
or small sand that shifting, up,

299
00:11:57,976 --> 00:12:01,306
down, left or right to
whatever the object is,

300
00:12:01,306 --> 00:12:03,476
which is again, that
UI image view.

301
00:12:04,056 --> 00:12:06,576
So, those several
lines of code which are

302
00:12:06,576 --> 00:12:08,836
at each point essentially
declaring a C struck.

303
00:12:08,996 --> 00:12:11,596
The C struck a C struck
that's being populated

304
00:12:11,596 --> 00:12:13,676
by the return values
of these functions

305
00:12:13,676 --> 00:12:14,566
on the right hand side.

306
00:12:14,906 --> 00:12:17,476
They're then being
applied in this final line.

307
00:12:18,616 --> 00:12:23,206
So what is the role played by
these last few lines down here?

308
00:12:24,596 --> 00:12:31,646
Why are we not done as soon as
we we apply the transformation?

309
00:12:31,726 --> 00:12:31,966
Yes?

310
00:12:32,516 --> 00:12:41,036
[ Inaudible ]

311
00:12:41,536 --> 00:12:43,606
Exactly. Good.

312
00:12:43,606 --> 00:12:45,086
Because we're doing
some additive math,

313
00:12:45,216 --> 00:12:47,466
especially when it comes to
the translation, we're taking

314
00:12:47,466 --> 00:12:52,586
into account where Rob
began on the entire screen.

315
00:12:52,586 --> 00:12:54,346
So if we wanted him
to not snap back

316
00:12:54,546 --> 00:12:56,696
to the default location each
time you drag or drop him,

317
00:12:56,956 --> 00:12:59,926
we have to simply update those
local instance variables.

318
00:13:00,156 --> 00:13:00,276
Yes?

319
00:13:01,516 --> 00:13:05,546
[ Inaudible ]

320
00:13:06,046 --> 00:13:08,056
Good question.

321
00:13:08,056 --> 00:13:11,176
It does expire several times
otherwise if when I clicked

322
00:13:11,176 --> 00:13:13,236
on Rob's face, I'll be
in a simulator there.

323
00:13:13,426 --> 00:13:15,996
You wouldn't have seen anything
happened until I let go.

324
00:13:15,996 --> 00:13:18,626
So it does fire at a
particularly fast frequency

325
00:13:18,866 --> 00:13:21,386
so that you can respond
essentially pixel by pixel.

326
00:13:22,466 --> 00:13:23,146
Good question.

327
00:13:23,786 --> 00:13:29,886
Yes? You can change the rates.

328
00:13:29,886 --> 00:13:33,446
The default is set by default
but you can override it

329
00:13:33,446 --> 00:13:35,246
so you can respond
in different ways.

330
00:13:35,426 --> 00:13:36,536
Much like the long press.

331
00:13:36,586 --> 00:13:39,216
By default, it roughly two
seconds before Rob's face would

332
00:13:39,216 --> 00:13:40,796
have triggered that UI
alert view last week.

333
00:13:40,796 --> 00:13:43,306
And that too you can raise
or lower programmatically

334
00:13:43,486 --> 00:13:45,396
when declaring the
gesture recognizer.

335
00:13:46,026 --> 00:13:46,596
Good question.

336
00:13:47,246 --> 00:13:49,826
Yes? Uh huh, say that again?

337
00:13:50,026 --> 00:13:57,956
So we're called, these
are not IB action.

338
00:13:58,126 --> 00:14:05,736
So IB actions are how we declare
methods inside of a class

339
00:14:05,736 --> 00:14:15,686
when we want objects inside
of a nib to talk back at them

340
00:14:15,736 --> 00:14:19,676
or more generally for UI
views to talk back at them

341
00:14:19,676 --> 00:14:20,886
when a user interacts with them.

342
00:14:21,156 --> 00:14:24,046
In this case, it's the gesture
recognizer, which is a class

343
00:14:24,046 --> 00:14:25,446
that Apple has provided with us.

344
00:14:25,646 --> 00:14:28,306
That is responsible for
invoking this methods.

345
00:14:29,006 --> 00:14:31,836
So it's not quite
the same use case

346
00:14:31,996 --> 00:14:37,456
because these messages are being
passed by this recognizer class.

347
00:14:37,486 --> 00:14:41,696
[Inaudible] in IB
outlet property.

348
00:14:42,656 --> 00:14:48,346
So typically, if you
want to connect your code

349
00:14:48,556 --> 00:14:51,986
to an interfere that you
created with interfere builder

350
00:14:51,986 --> 00:14:54,456
in a. XIB file, then
yes, you do exactly that.

351
00:14:54,686 --> 00:14:56,596
And that is the reason why
we scroll up to the part

352
00:14:56,596 --> 00:14:58,026
that we glossed over earlier.

353
00:14:58,296 --> 00:15:00,636
I have two things
declared as properties.

354
00:15:00,636 --> 00:15:02,796
One is is the scale, which
as we'll see is just a way

355
00:15:02,796 --> 00:15:04,036
of remembering when I pinch,

356
00:15:04,186 --> 00:15:05,826
what the scale factor
is for Rob.

357
00:15:05,826 --> 00:15:10,706
If it's not 1.0 by default in
image view is very typical.

358
00:15:10,706 --> 00:15:12,196
Notice, that we have
IB outlet here.

359
00:15:12,196 --> 00:15:14,596
And we see this in a number
of examples in past weeks.

360
00:15:14,716 --> 00:15:17,316
This is my mechanism for
actually linking my code

361
00:15:17,316 --> 00:15:20,366
to the UI image view so
that I can actually apply

362
00:15:20,366 --> 00:15:23,076
that recognizer and listen
for those finger touches.

363
00:15:23,286 --> 00:15:24,786
Good question.

364
00:15:25,596 --> 00:15:29,216
So, pinching is going to be
pretty much similar in spirit,

365
00:15:29,216 --> 00:15:29,696
even though some

366
00:15:29,696 --> 00:15:31,756
of the functions calls will
be a little bit different.

367
00:15:31,756 --> 00:15:33,346
Let me scroll this
over just a bit.

368
00:15:33,346 --> 00:15:35,456
And handle pinch is method
that's going to get invoked

369
00:15:35,456 --> 00:15:36,686
when you're using the two finger

370
00:15:36,686 --> 00:15:38,336
to go separate or
closer together.

371
00:15:38,336 --> 00:15:40,276
And now we have this first.

372
00:15:40,276 --> 00:15:42,376
I'm declaring a CG float struck.

373
00:15:42,756 --> 00:15:44,416
So again, here too,
it looks like a class.

374
00:15:44,596 --> 00:15:46,146
It it looks like
an object thereof.

375
00:15:46,146 --> 00:15:49,206
But this is again just
capitalized to be consistent

376
00:15:49,206 --> 00:15:52,136
with Apple's tradition for
C [inaudible] structures.

377
00:15:52,166 --> 00:15:55,116
This is a CG float, which
is just some representation

378
00:15:55,116 --> 00:15:56,186
of some floating point value.

379
00:15:56,526 --> 00:16:01,386
CG affine transform scale is
doing a line of code similar

380
00:16:01,386 --> 00:16:03,726
to before where we
take the current scale

381
00:16:03,726 --> 00:16:06,476
and multiply it by some factor.

382
00:16:06,476 --> 00:16:09,766
And notice that the factor
has been passed in to us.

383
00:16:09,826 --> 00:16:12,896
So one of the things this
recognizer does is it figures

384
00:16:12,896 --> 00:16:14,946
out how far away did
your fingers move

385
00:16:14,946 --> 00:16:16,146
in that split second of time.

386
00:16:16,376 --> 00:16:18,956
And then it forms this method
what that difference is

387
00:16:19,076 --> 00:16:20,986
so that you can scale
accordingly.

388
00:16:21,336 --> 00:16:24,566
Then if we looked down here
we're doing a translation.

389
00:16:24,796 --> 00:16:27,166
This time we're not
actually moving Rob

390
00:16:27,166 --> 00:16:30,116
because we're we only want to
move Rob when we're panning,

391
00:16:30,206 --> 00:16:31,216
not when we're pinching.

392
00:16:31,216 --> 00:16:33,176
So he's going to
stay put but grow

393
00:16:33,236 --> 00:16:35,406
from wherever my
fingers are moving closer

394
00:16:35,406 --> 00:16:36,776
or farther away from each other.

395
00:16:37,066 --> 00:16:40,406
And then we apply these
two things again much

396
00:16:40,406 --> 00:16:41,636
like we did previously.

397
00:16:41,636 --> 00:16:44,806
And then lastly, all we do is
remember that change in scale

398
00:16:45,046 --> 00:16:46,896
so that when I do it
again, he doesn't snap back

399
00:16:47,236 --> 00:16:50,846
to the default 1.0
resolution to start anew.

400
00:16:52,576 --> 00:16:54,796
All right, any questions then?

401
00:16:55,616 --> 00:16:58,136
So we've seen some buildings
blocks now for swiping, up,

402
00:16:58,136 --> 00:17:00,396
down, left, right for
touching, for pinching,

403
00:17:00,706 --> 00:17:02,756
for clicking and dragging.

404
00:17:02,756 --> 00:17:04,616
And so, with those, for your
third project, if you choose

405
00:17:04,616 --> 00:17:05,536
to do something in iOS

406
00:17:05,666 --> 00:17:08,606
that actually has UI
interactions beyond what's

407
00:17:08,606 --> 00:17:10,966
possible out of the box
with interfere builder,

408
00:17:11,166 --> 00:17:12,766
realize that these are
the basic building blocks.

409
00:17:12,836 --> 00:17:14,696
Even for say, a simple game.

410
00:17:14,696 --> 00:17:16,316
We'll put these to
the test later tonight

411
00:17:16,316 --> 00:17:19,616
when we implement an
age old games of sorts.

412
00:17:21,206 --> 00:17:21,906
All right.

413
00:17:23,216 --> 00:17:25,266
And you might see
[inaudible] to right there.

414
00:17:26,096 --> 00:17:26,716
All right.

415
00:17:27,506 --> 00:17:33,236
So, questions on the basics
of graphics before we move

416
00:17:33,236 --> 00:17:35,466
onto things that are useful
to have in your tool kit.

417
00:17:35,756 --> 00:17:39,006
But then we'll come back full
circle to the application

418
00:17:39,006 --> 00:17:43,646
of two dimensional graphics
Actually moving on their own

419
00:17:43,646 --> 00:17:44,786
without human interaction.

420
00:17:45,566 --> 00:17:46,896
Okay, so a design question then.

421
00:17:47,066 --> 00:17:48,876
So, totally changing
years for just a moment.

422
00:17:48,876 --> 00:17:51,886
And localization refers to
what process when writing code?

423
00:17:52,726 --> 00:17:55,636
Okay, internationalization.

424
00:17:55,636 --> 00:17:57,746
So not just naively
assuming that everyone

425
00:17:57,746 --> 00:18:00,816
of your users is going to
speak English and read English

426
00:18:00,816 --> 00:18:03,046
but rather might have
some other native tongue.

427
00:18:03,046 --> 00:18:04,606
And you might want to
cater to that audience

428
00:18:04,606 --> 00:18:07,156
that actually download your user
app, can understand your app.

429
00:18:07,156 --> 00:18:08,006
Whatever the reasons.

430
00:18:08,476 --> 00:18:10,376
But this is problematic
because we've gotten

431
00:18:10,376 --> 00:18:13,076
to the habit thus far of
writing quite a lot of code.

432
00:18:13,076 --> 00:18:17,136
And what's essentially English,
since Apple came from the U.S.

433
00:18:17,556 --> 00:18:19,476
but also, quite a
lot of strings.

434
00:18:19,476 --> 00:18:22,186
Quite a lot of NS strings
inside of double quotes.

435
00:18:22,186 --> 00:18:23,706
Maybe prefix with an at sign.

436
00:18:24,016 --> 00:18:25,236
So this is kind of problematic.

437
00:18:25,436 --> 00:18:28,176
Because I feel like if I want
to suddenly support Mandarin

438
00:18:28,176 --> 00:18:31,186
or Spanish or any other
language to which I might want

439
00:18:31,186 --> 00:18:32,566
to localize high application,

440
00:18:32,846 --> 00:18:34,936
now I have to do a
whole lot of copy paste.

441
00:18:34,936 --> 00:18:38,626
And any file that has a quoted
string, like hello world,

442
00:18:38,626 --> 00:18:41,776
I'm going to apparently need
to copy my view controller.

443
00:18:41,926 --> 00:18:44,586
H and maybe make a separate
one for each language.

444
00:18:44,586 --> 00:18:45,306
View controller.

445
00:18:45,446 --> 00:18:47,666
M, a separate one
for the languages.

446
00:18:48,036 --> 00:18:49,296
Like, surely, this
isn't the way.

447
00:18:49,536 --> 00:18:52,736
Because if there's some 50, 60
languages you might even want

448
00:18:52,736 --> 00:18:54,716
to support, I mean,
that's a nightmare to have

449
00:18:54,716 --> 00:18:56,056
that much code lying around.

450
00:18:56,056 --> 00:18:57,676
If only because now if
you want to make a change,

451
00:18:57,676 --> 00:18:59,236
you have to make it
in dozens of places.

452
00:18:59,766 --> 00:19:01,126
So what's a smarter approach?

453
00:19:01,546 --> 00:19:03,116
And let me [inaudible] this

454
00:19:03,116 --> 00:19:06,106
with someone who's never
internationalized an

455
00:19:06,106 --> 00:19:07,156
application before.

456
00:19:07,636 --> 00:19:09,746
How would you go about
solving this problem?

457
00:19:09,746 --> 00:19:09,966
All right.

458
00:19:10,516 --> 00:19:35,796
[ Background Discussion ]

459
00:19:36,296 --> 00:19:38,106
Yes. So that's exactly right.

460
00:19:38,106 --> 00:19:40,196
But the principal that I'll
highlight there is the fact

461
00:19:40,196 --> 00:19:42,886
that you're proposing that
we factor out the strain.

462
00:19:42,886 --> 00:19:44,506
So you could write all
of your code in English

463
00:19:44,506 --> 00:19:46,406
or pseudo English,
an objective C or C,

464
00:19:46,406 --> 00:19:47,466
whatever the language is.

465
00:19:47,626 --> 00:19:50,366
But if you at least factor
out the strains that have

466
00:19:50,366 --> 00:19:53,266
to change based on the users
end language by putting them

467
00:19:53,266 --> 00:19:56,916
in some central file, now you
can keep separate your codes,

468
00:19:56,976 --> 00:19:59,516
your business logic so to
speak from your actual data,

469
00:19:59,516 --> 00:20:01,796
in this case, the streams
that the user sees.

470
00:20:02,026 --> 00:20:04,106
So, you're indeed right, the
way Apple typically does this

471
00:20:04,106 --> 00:20:07,286
for desktop or iOS applications
is that you have a P list file,

472
00:20:07,286 --> 00:20:09,266
which is just an XML
file underneath the hood.

473
00:20:09,546 --> 00:20:11,786
But so far as we care,
it's just a text file

474
00:20:11,836 --> 00:20:12,966
that we can therefore edit.

475
00:20:13,166 --> 00:20:14,896
And if we have after
separate file for English,

476
00:20:14,896 --> 00:20:17,426
a separate file for Mandarin,
a separate file for Spanish,

477
00:20:17,666 --> 00:20:20,046
we can essentially tell
iOS, the operating system,

478
00:20:20,256 --> 00:20:23,366
depending on what language the
user's iPhone or iPad is in,

479
00:20:23,586 --> 00:20:26,796
load the appropriate
key list file for me.

480
00:20:27,046 --> 00:20:29,156
So, in fact, you've seen
a few different things.

481
00:20:29,156 --> 00:20:32,076
We'll use a file that
typically ends in dot strains.

482
00:20:32,076 --> 00:20:33,326
But it's the same exact idea.

483
00:20:33,356 --> 00:20:36,956
It's even simpler than a P list
and that we just write things

484
00:20:36,956 --> 00:20:39,786
in the form of text,
no XML whatsoever.

485
00:20:40,246 --> 00:20:42,336
So, let's go ahead and
do an example here.

486
00:20:42,336 --> 00:20:43,916
Let me open up X code.

487
00:20:44,166 --> 00:20:46,416
Create a new project, which
we'll do a single view.

488
00:20:47,076 --> 00:20:52,796
Let me then proceed to name
this, let's say, Hola 1.

489
00:20:52,876 --> 00:20:55,606
I will bias things toward
English and Spanish for now.

490
00:20:55,606 --> 00:20:58,226
I'm going to go ahead and
leave automatic reference

491
00:20:58,226 --> 00:20:58,936
counting checked.

492
00:20:59,006 --> 00:21:01,036
I'm going to leave
everything else unchecked.

493
00:21:01,036 --> 00:21:02,866
I'm going to go ahead
and click next.

494
00:21:02,866 --> 00:21:04,736
I'm going to go ahead and
save this on my desktop

495
00:21:04,876 --> 00:21:07,256
and now I have the simplest of
applications, which will call

496
00:21:07,256 --> 00:21:11,346
if I run it, just gives me
a big white box in the form

497
00:21:11,346 --> 00:21:14,836
of an application
that looks like this.

498
00:21:15,216 --> 00:21:16,166
So very underwhelming.

499
00:21:16,166 --> 00:21:17,646
But let's make it
a little sexier

500
00:21:17,866 --> 00:21:19,616
by going into the nib file.

501
00:21:19,946 --> 00:21:23,776
Let me go ahead and drag a
label into the middle just

502
00:21:23,776 --> 00:21:27,386
so I could support iPhone
four and iPhone 5's.

503
00:21:27,436 --> 00:21:29,906
Let me go ahead and
click down here

504
00:21:29,906 --> 00:21:31,556
if you haven't noticed
this control bar,

505
00:21:31,716 --> 00:21:34,076
and turn on a constraint
called vertical center.

506
00:21:34,076 --> 00:21:36,726
This will ensure that
whatever simulator you're using

507
00:21:36,726 --> 00:21:38,016
or whatever device you're using,

508
00:21:38,016 --> 00:21:39,826
at least this text will
be vertically centered.

509
00:21:40,136 --> 00:21:42,366
And by default, let
me just go ahead

510
00:21:42,366 --> 00:21:45,566
and make the American
centric version hello world.

511
00:21:45,736 --> 00:21:46,746
All right.

512
00:21:46,746 --> 00:21:50,516
So now notice what I have on
the left hand side of my screen.

513
00:21:50,516 --> 00:21:51,976
All of the familiar files.

514
00:21:52,436 --> 00:21:54,706
The program happens to be
called Hola, but that's just

515
00:21:54,706 --> 00:21:57,176
because I wrote that and
nothing has been actually been

516
00:21:57,176 --> 00:21:58,346
internationalized yet.

517
00:21:58,676 --> 00:22:01,316
But those are all pretty
much familiar files.

518
00:22:01,316 --> 00:22:04,206
And particular notice there's
just a single nib file.

519
00:22:04,366 --> 00:22:07,036
But if I now want to
localize this application,

520
00:22:07,546 --> 00:22:08,536
we can do the following.

521
00:22:08,536 --> 00:22:11,816
And unfortunately this
feature changes location

522
00:22:11,816 --> 00:22:13,636
with every version
of X code it seems.

523
00:22:13,956 --> 00:22:16,996
But if I go ahead and click on
the project on the top left,

524
00:22:17,466 --> 00:22:21,136
then click on the project to
the right of that, you'll notice

525
00:22:21,136 --> 00:22:24,826
down here that there's a screen
in related to localization,

526
00:22:24,826 --> 00:22:26,636
a.k.a. internationalization.

527
00:22:26,636 --> 00:22:29,876
And if I go ahead and click the
plus here, I have a whole bunch

528
00:22:29,876 --> 00:22:32,346
of languages that X code
supports nicely right

529
00:22:32,346 --> 00:22:33,066
out of the box.

530
00:22:33,316 --> 00:22:34,746
I'm going to go ahead
and choose Spanish.

531
00:22:34,746 --> 00:22:36,836
And if I zoom out I'm
now being prompted

532
00:22:36,836 --> 00:22:37,716
to do a couple of things.

533
00:22:37,716 --> 00:22:39,276
Choose files and
reference language

534
00:22:39,276 --> 00:22:41,236
to create Spanish localization.

535
00:22:41,586 --> 00:22:44,336
So it turns out that by default,
there's two different files

536
00:22:44,336 --> 00:22:46,246
that can take on
some other language.

537
00:22:46,246 --> 00:22:47,876
One is the nib file apparently.

538
00:22:48,166 --> 00:22:51,436
And one is a file
called InfoPList.strings.

539
00:22:51,936 --> 00:22:54,456
So, I'm not going to
touch the latter just yet.

540
00:22:54,456 --> 00:22:56,446
I'm going to uncheck it
and come back to that.

541
00:22:56,446 --> 00:22:59,936
But I am going to tell X
code to localize my nib file.

542
00:23:00,366 --> 00:23:02,066
So if I go down here to finish,

543
00:23:02,706 --> 00:23:06,196
what I now get is both
English and Spanish.

544
00:23:06,456 --> 00:23:09,496
And if I go back to my nib,
notice that by default,

545
00:23:09,496 --> 00:23:12,206
I still see hello world
but notice what's different

546
00:23:12,206 --> 00:23:17,446
about the nib on the top left.

547
00:23:17,446 --> 00:23:20,426
Yes, it looks like its become
a hierarchy of some sort.

548
00:23:20,426 --> 00:23:23,166
If I expand this triangle,
I seem to have English,

549
00:23:23,526 --> 00:23:24,956
which is what I had
a moment ago.

550
00:23:24,956 --> 00:23:28,876
And then I have Spanish,
which is apparently the same.

551
00:23:29,286 --> 00:23:31,806
Okay, so it actually hasn't
done any translation for me.

552
00:23:31,806 --> 00:23:33,426
That's sort of human
to actually do.

553
00:23:33,636 --> 00:23:35,146
But I can go into this nib now

554
00:23:35,336 --> 00:23:38,336
and I can say something
like, hola, mundo.

555
00:23:38,836 --> 00:23:39,576
Change it there.

556
00:23:39,916 --> 00:23:42,316
Save it, and now I
have my English version

557
00:23:42,726 --> 00:23:44,276
and my Spanish version.

558
00:23:44,636 --> 00:23:45,996
So let's see what now happens.

559
00:23:45,996 --> 00:23:47,896
I'm going to go back
to the simulator.

560
00:23:47,896 --> 00:23:49,636
Or rather let me go ahead

561
00:23:49,636 --> 00:23:51,846
and [inaudible] the
simulator by running the code.

562
00:23:52,526 --> 00:23:53,196
Its been built.

563
00:23:53,546 --> 00:23:55,526
It's being installed
into the simulator.

564
00:23:56,536 --> 00:23:59,456
And when it comes

565
00:23:59,596 --> 00:24:04,356
to the foreground we
should see hello world.

566
00:24:04,826 --> 00:24:05,756
Now, let me disclaim.

567
00:24:05,876 --> 00:24:08,066
About every 5th time I try this

568
00:24:08,066 --> 00:24:09,806
on different computers,
it doesn't work.

569
00:24:09,806 --> 00:24:12,486
So if it blows up, realize
that I've should a disclaimer,

570
00:24:12,486 --> 00:24:13,136
which means it's okay.

571
00:24:13,776 --> 00:24:16,606
But if I now go here, these are
just all the applications we've

572
00:24:16,606 --> 00:24:18,166
been installing in recent weeks.

573
00:24:18,516 --> 00:24:20,906
I'm going to right click
over to the settings.

574
00:24:20,906 --> 00:24:23,936
And if you've never done
this on your phone or iPad,

575
00:24:23,936 --> 00:24:27,036
you can go to general
international language.

576
00:24:27,076 --> 00:24:29,386
And I'm going to choose
Espanol for Spanish.

577
00:24:29,686 --> 00:24:33,256
Done. It's going to change
language dot dot dot.

578
00:24:34,186 --> 00:24:36,056
The next code is going to crash
because it doesn't like it

579
00:24:36,056 --> 00:24:37,306
when you do that when
it's still running.

580
00:24:37,466 --> 00:24:39,996
But I'm going to go ahead
now and rerun the simulator.

581
00:24:41,246 --> 00:24:44,006
And now we have a Spanish
version of the application.

582
00:24:44,236 --> 00:24:46,596
So the only thing that's
changed, crash aside,

583
00:24:46,836 --> 00:24:48,996
is that I changed the
settings in my application

584
00:24:48,996 --> 00:24:51,436
to actually be, Spanish
instead of English.

585
00:24:51,436 --> 00:24:52,396
And if I went back to English,

586
00:24:52,396 --> 00:24:54,616
you should hopefully
see hello world instead.

587
00:24:54,866 --> 00:24:56,476
But a couple of things
haven't changed.

588
00:24:56,476 --> 00:24:59,046
In particular, what's the name
of this application apparently.

589
00:25:00,026 --> 00:25:01,166
So it's still Hola 1.

590
00:25:01,506 --> 00:25:04,506
So irrespective of the
language, my phone is configured

591
00:25:04,506 --> 00:25:06,246
with the application,
which is still the same.

592
00:25:06,246 --> 00:25:07,246
And maybe that's a good thing.

593
00:25:07,246 --> 00:25:08,426
Maybe you want the game

594
00:25:08,426 --> 00:25:10,806
to be called Angry Birds no
matter what the language is

595
00:25:10,806 --> 00:25:11,256
actually is.

596
00:25:11,256 --> 00:25:12,736
Or maybe you want to
localize that too.

597
00:25:12,886 --> 00:25:14,546
So you can do that
in different places.

598
00:25:14,886 --> 00:25:16,906
So let me actually
go ahead and open

599
00:25:16,906 --> 00:25:22,746
up a second example here
whereby we start fresh,

600
00:25:23,396 --> 00:25:27,186
single view application, Hola
2, will be this application.

601
00:25:28,156 --> 00:25:29,916
And save it on the desktop.

602
00:25:30,776 --> 00:25:33,836
And let's do something
that's almost the same

603
00:25:34,026 --> 00:25:36,776
but this time I want to do
a little bit more in code.

604
00:25:36,776 --> 00:25:40,116
So I'm going to go ahead
and open up my nib file.

605
00:25:40,486 --> 00:25:42,186
This time I'm going
to drag my label.

606
00:25:42,186 --> 00:25:44,066
And I'm not going to
hard code it into my nib.

607
00:25:44,066 --> 00:25:46,066
Because we're called that
if we do a little bit more

608
00:25:46,066 --> 00:25:48,946
programming, we can
actually control

609
00:25:48,946 --> 00:25:51,526
that label programmatically
from code.

610
00:25:51,796 --> 00:25:56,016
So if I want to do this let
me make sure things line

611
00:25:56,016 --> 00:25:58,826
up with the online codes
so that you can play along

612
00:25:58,826 --> 00:25:59,626
at home after.

613
00:25:59,966 --> 00:26:02,026
If I want to actually do this,
what's the first thing I need

614
00:26:02,026 --> 00:26:06,566
to do to wire my code
up to my nib file?

615
00:26:07,596 --> 00:26:10,336
So all I have is the empty
boiler play code thus far.

616
00:26:10,916 --> 00:26:14,106
Yes? Okay, so I need
to create an IB outlet,

617
00:26:14,106 --> 00:26:15,716
which likely belongs
in what file?

618
00:26:17,416 --> 00:26:19,186
Okay. So, somewhere
in the ViewController.

619
00:26:19,186 --> 00:26:20,986
And early on we're called
that we put almost all

620
00:26:20,986 --> 00:26:22,486
of our properties,
just by convention,

621
00:26:22,486 --> 00:26:23,566
into the dotted H file.

622
00:26:23,866 --> 00:26:26,446
But then gradually last week
we started moving more and more

623
00:26:26,446 --> 00:26:28,646
of our properties and
method declarations

624
00:26:28,706 --> 00:26:30,996
into the dot M file.

625
00:26:30,996 --> 00:26:33,376
The implementation file, just
because there's really no reason

626
00:26:33,376 --> 00:26:36,616
to inform the whole world what
our private implementation

627
00:26:36,616 --> 00:26:37,326
details are.

628
00:26:37,596 --> 00:26:40,466
So I'll go ahead and open
up ViewController dot M.

629
00:26:40,656 --> 00:26:43,756
And I can implement this
inside of my nameless category.

630
00:26:43,756 --> 00:26:46,426
So I'm going to declare a
property with a view attributes.

631
00:26:46,426 --> 00:26:47,576
But we will come back to that.

632
00:26:47,576 --> 00:26:52,236
It's going to be a UI label
and I'll just call this label.

633
00:26:52,786 --> 00:26:54,096
Now I need a couple
of more things.

634
00:26:54,096 --> 00:26:57,296
If this is going to be an IB
outlet, I need to say IB outlet.

635
00:26:57,946 --> 00:27:00,006
And what attributes
would be appropriate

636
00:27:00,006 --> 00:27:06,756
for this outlet,
for this IB outlet?

637
00:27:06,916 --> 00:27:08,296
Well, one is always easy.

638
00:27:08,346 --> 00:27:10,586
We haven't seen atomic, so
non atomic, I think is fine.

639
00:27:10,586 --> 00:27:12,886
We're not writing
multi-threaded code out here

640
00:27:12,886 --> 00:27:14,036
within this application.

641
00:27:14,036 --> 00:27:15,166
Read only or read write.

642
00:27:16,276 --> 00:27:19,186
The goal is to recreate
the hello world application

643
00:27:19,186 --> 00:27:22,096
by this time in code
telling it what to say.

644
00:27:22,326 --> 00:27:25,816
Either hello world
or hola mundo.

645
00:27:25,816 --> 00:27:27,396
Okay, so read write
since I want to be able

646
00:27:27,396 --> 00:27:28,786
to change what it's pointing at.

647
00:27:29,106 --> 00:27:31,016
And then lastly, I can
actually go with week.

648
00:27:31,246 --> 00:27:33,236
So we haven't spent too much
time on this but we're called

649
00:27:33,236 --> 00:27:35,726
that strong versus
weak somehow relates

650
00:27:35,726 --> 00:27:38,036
to how the pointers are
going to be dealt with.

651
00:27:38,246 --> 00:27:40,916
And in this case, weak suffices

652
00:27:41,196 --> 00:27:43,736
because all I need is a
pointer to a UI label.

653
00:27:44,046 --> 00:27:46,606
But I'm not the owner
of that UI label per se.

654
00:27:46,606 --> 00:27:48,046
The owner is really
the nib file.

655
00:27:48,046 --> 00:27:50,816
And when the nib is loaded, it
will take care of [inaudible].

656
00:27:50,816 --> 00:27:55,086
That the ram that's
necessary to store that label

657
00:27:55,086 --> 00:27:57,176
on the screen will
be allocated by it.

658
00:27:57,516 --> 00:28:00,116
I am just some other
guy, ViewController.m,

659
00:28:00,326 --> 00:28:02,096
that similarly wants
to talk to that pointer

660
00:28:02,096 --> 00:28:04,796
but it's not really mine
per se, so weak suffices.

661
00:28:04,796 --> 00:28:05,956
Someone else owns it.

662
00:28:05,956 --> 00:28:08,256
I did not instantiate it myself.

663
00:28:08,256 --> 00:28:09,466
It came from the nib.

664
00:28:09,916 --> 00:28:12,296
So after this, I now
have programmatic access

665
00:28:12,296 --> 00:28:13,066
to the label.

666
00:28:13,336 --> 00:28:14,336
So what do I want to do?

667
00:28:14,336 --> 00:28:15,396
Well, I want to get rid

668
00:28:15,396 --> 00:28:17,156
of the [inaudible]
receive memory warning.

669
00:28:17,156 --> 00:28:19,226
There's not much we can do
if this application runs

670
00:28:19,226 --> 00:28:21,336
out of memory because there's
terribly little going on,

671
00:28:21,336 --> 00:28:22,426
just that UI label.

672
00:28:22,686 --> 00:28:24,616
And I am going to put
some additional code

673
00:28:24,616 --> 00:28:25,676
into viewDidLoad.

674
00:28:25,786 --> 00:28:27,246
First, again by convention,

675
00:28:27,246 --> 00:28:30,476
I'm going to call the parent
classes, viewDidLoad method,

676
00:28:30,476 --> 00:28:32,196
whatever that happens to do.

677
00:28:32,266 --> 00:28:36,036
And when this view load so when
the nib is loaded from disk,

678
00:28:36,396 --> 00:28:38,176
and the rectangle
is constructed,

679
00:28:38,176 --> 00:28:40,656
and that UI label is placed
in the middle of the screen.

680
00:28:40,656 --> 00:28:44,246
And I want to do one
configuration detail, namely,

681
00:28:44,356 --> 00:28:49,626
self.label.text is what's
actually inside of that label.

682
00:28:49,926 --> 00:28:50,626
Is going to get.

683
00:28:50,626 --> 00:28:56,256
And this is the new
part, NSLocalizedString.

684
00:28:56,616 --> 00:28:59,556
And now according to
X codes prompts here,

685
00:28:59,706 --> 00:29:01,896
it wants a key and or a comment.

686
00:29:02,376 --> 00:29:03,866
So I somehow need to provide it

687
00:29:03,866 --> 00:29:05,886
with an identifier
for that string.

688
00:29:05,886 --> 00:29:09,466
It doesn't want me to put, for
instance, hello world, per se.

689
00:29:09,836 --> 00:29:13,786
But rather a generic key
that's going to be defined

690
00:29:13,786 --> 00:29:16,306
in two different places,
two separate files,

691
00:29:16,676 --> 00:29:19,936
so that I can look up
that value dynamically.

692
00:29:20,406 --> 00:29:22,416
So, comment, I'm going
to actually leave nil.

693
00:29:22,936 --> 00:29:26,346
Comment is just for really the
humans doing the translations.

694
00:29:26,346 --> 00:29:29,396
You can use tools to
automatically generate a file.

695
00:29:29,396 --> 00:29:31,746
We are about to generate
manually, so that if you

696
00:29:31,746 --> 00:29:33,936
or the programmer, who
maybe only speaks English,

697
00:29:33,936 --> 00:29:36,496
but you want to tell
other developers

698
00:29:36,496 --> 00:29:37,996
who actually speak
multiple languages,

699
00:29:38,176 --> 00:29:39,896
what this string represents.

700
00:29:39,896 --> 00:29:41,696
You can do it in the form
of after comment there.

701
00:29:41,856 --> 00:29:43,736
So that when they automatically
generate the file we're

702
00:29:43,736 --> 00:29:46,516
about to generate manually, they
know what you mean by that key.

703
00:29:46,516 --> 00:29:47,986
So I'm going to choose
something arbitrary

704
00:29:47,986 --> 00:29:49,786
but sensible, like, greeting.

705
00:29:49,876 --> 00:29:52,956
So quote on quote greeting, is
not what I want the user to see.

706
00:29:53,176 --> 00:29:56,786
It's just going to be a key
into a table of strings.

707
00:29:57,066 --> 00:30:00,966
So to create this I'm going
to go up to file, new, file.

708
00:30:00,966 --> 00:30:03,536
And we haven't seen this one
before, but if you poke around,

709
00:30:03,536 --> 00:30:05,366
you'll start seeing some
other useful things.

710
00:30:05,366 --> 00:30:08,496
If I go to resource, notice
there's a few resources here.

711
00:30:08,496 --> 00:30:10,116
Property list, we've
seen before.

712
00:30:10,346 --> 00:30:11,966
Strings file is another.

713
00:30:12,126 --> 00:30:13,226
And according to
the description,

714
00:30:13,226 --> 00:30:14,876
it is an empty strings file.

715
00:30:14,876 --> 00:30:15,816
It's just a text file.

716
00:30:16,116 --> 00:30:17,366
So let's go ahead
and click next.

717
00:30:17,626 --> 00:30:21,706
By default, I'm going to call
this Localizable.strings.

718
00:30:22,026 --> 00:30:25,686
And X code knows by default
to look for file by that name.

719
00:30:25,916 --> 00:30:28,686
And if it's present, go
ahead and allow the user

720
00:30:28,686 --> 00:30:31,636
to just find multiple
languages strings in there.

721
00:30:32,056 --> 00:30:32,866
So I click the create.

722
00:30:33,626 --> 00:30:36,316
And now I have this text file
over on the left hand side.

723
00:30:36,596 --> 00:30:39,556
Notice that there is just some
generic comments at the top.

724
00:30:39,776 --> 00:30:44,396
And it's in here where I can
now define some key value pairs.

725
00:30:44,916 --> 00:30:45,366
All right?

726
00:30:45,406 --> 00:30:48,576
So now, if I want to go ahead
and define the key value pair,

727
00:30:48,826 --> 00:30:54,546
let's go ahead and define what
greeting has to map to what.

728
00:30:55,106 --> 00:30:57,196
Hello world or hola mundo.

729
00:30:57,426 --> 00:31:00,076
And then we're going to need
to do that not in the same file

730
00:31:00,356 --> 00:31:01,686
but in two different places.

731
00:31:01,686 --> 00:31:03,136
So before we do that, let me go

732
00:31:03,136 --> 00:31:05,786
up to my project
settings as before.

733
00:31:06,356 --> 00:31:07,916
Hola two is the project.

734
00:31:08,006 --> 00:31:11,536
And let me go ahead and
add proactively, Spanish.

735
00:31:11,946 --> 00:31:14,996
Unfortunately by default,
X code only seems to know

736
00:31:14,996 --> 00:31:16,386
about these two default files.

737
00:31:16,386 --> 00:31:19,456
ViewController.nib
and InfoPList.strings.

738
00:31:19,636 --> 00:31:21,476
We're not doing anything
with the nib this time.

739
00:31:21,476 --> 00:31:24,366
So just to keep things clean,
I'm going to uncheck that.

740
00:31:24,596 --> 00:31:27,086
InfoPList.strings
we'll come back to.

741
00:31:27,276 --> 00:31:29,266
And now I have Spanish language.

742
00:31:29,546 --> 00:31:31,996
But unfortunately, I haven't
solved the problem at hand.

743
00:31:31,996 --> 00:31:34,336
And this is just an
[inaudible] UI decision.

744
00:31:34,616 --> 00:31:36,346
Notice on the right
hand side here,

745
00:31:36,586 --> 00:31:38,986
if you want to localize
a .strings file

746
00:31:39,046 --> 00:31:41,966
that I have created myself
manually, unfortunately you have

747
00:31:41,966 --> 00:31:44,626
to click this big
button called localize.

748
00:31:44,966 --> 00:31:46,786
And here's where
I'll be prompted, oh,

749
00:31:46,786 --> 00:31:49,176
do I want to localize this
file into which language?

750
00:31:49,176 --> 00:31:51,646
Spanish. Now we'll go
ahead and localize.

751
00:31:52,156 --> 00:31:57,956
And now that did not
behave oh, there it is.

752
00:31:58,276 --> 00:32:01,226
By default, X code does
not check both boxes.

753
00:32:01,396 --> 00:32:04,006
So if we now check English and
now go over here on the left,

754
00:32:04,516 --> 00:32:08,106
Localizable.strings has both
English and Spanish forms.

755
00:32:08,406 --> 00:32:12,366
So if we fast forward now to
the climax of this example,

756
00:32:12,366 --> 00:32:14,686
what we'll see is an example

757
00:32:14,686 --> 00:32:17,106
that has both the
Spanish version

758
00:32:17,476 --> 00:32:23,546
and the English version
exactly as follows.

759
00:32:23,546 --> 00:32:26,256
In Hola two, we have
supporting files.

760
00:32:26,256 --> 00:32:28,716
And if we go to
Localizable.strings,

761
00:32:29,136 --> 00:32:31,636
specifically the English
one, notice that again,

762
00:32:31,636 --> 00:32:33,916
this is just a mapping
of keys to values.

763
00:32:33,916 --> 00:32:36,536
Quote on quote greetings equals
quote on quote hello world.

764
00:32:36,786 --> 00:32:38,326
Notice that it's
not an NS string.

765
00:32:38,326 --> 00:32:40,096
These are C style
strings now, so there's no

766
00:32:40,096 --> 00:32:41,786
at science involved
in this file.

767
00:32:42,036 --> 00:32:44,306
But they do end with a
semicolon at the end.

768
00:32:44,596 --> 00:32:47,346
If I go to the Spanish
version, the key is the same,

769
00:32:47,346 --> 00:32:48,586
so you don't localize that.

770
00:32:48,896 --> 00:32:50,686
But the value does change.

771
00:32:50,966 --> 00:32:53,736
And so, because this file is
called Localizable.strings,

772
00:32:53,736 --> 00:32:56,856
iOS will load it
automatically for you and use

773
00:32:56,856 --> 00:33:00,306
that when you call the
function that we did earlier,

774
00:33:00,576 --> 00:33:03,116
called NS localize string.

775
00:33:04,156 --> 00:33:06,186
And there's one last thing
I did here in advance.

776
00:33:06,216 --> 00:33:10,526
In this file, which to date,
we have not actually looked at.

777
00:33:10,526 --> 00:33:12,066
InfoPList.strings.

778
00:33:12,496 --> 00:33:14,946
According to the documents,
if you define a key,

779
00:33:14,946 --> 00:33:18,436
called CFBundleDisplayName,
you can also change the name

780
00:33:18,436 --> 00:33:20,256
of your application
programmatically.

781
00:33:20,256 --> 00:33:22,686
So in this case, I want my
application to be called Hola.

782
00:33:22,926 --> 00:33:24,516
But if the user is
English speaking,

783
00:33:24,516 --> 00:33:25,736
I want it to be called Hello.

784
00:33:25,736 --> 00:33:27,396
So no more Hola one, Hola two.

785
00:33:27,586 --> 00:33:29,826
This is the formal name
for my application.

786
00:33:30,206 --> 00:33:36,166
If I go ahead and run this, I'm
still in the simulator here.

787
00:33:37,646 --> 00:33:40,726
So we should see now the
second version of this code.

788
00:33:42,166 --> 00:33:45,096
Hola mundo.

789
00:33:45,506 --> 00:33:49,686
And if I now go back to
the desktop and take a look

790
00:33:49,686 --> 00:33:51,866
at the program's
name, it's Hola.

791
00:33:51,926 --> 00:33:54,306
If I go back to English,
that's changed to Hello,

792
00:33:54,386 --> 00:33:55,906
and the string should
go to Hello world.

793
00:33:56,536 --> 00:33:58,956
So, sort of lesson learned here,
especially if you're planning

794
00:33:59,006 --> 00:34:00,606
to do something for
the app store.

795
00:34:00,606 --> 00:34:02,666
And you actually do want to
appeal to multiple languages,

796
00:34:02,666 --> 00:34:04,136
this is the sort of
thing where it's good

797
00:34:04,136 --> 00:34:07,496
to start designing your strings
file now so that you don't,

798
00:34:07,496 --> 00:34:10,406
after writing 2,000 lines
of code, have to go back in

799
00:34:10,406 --> 00:34:11,756
and then start ripping
things out

800
00:34:11,756 --> 00:34:13,456
and redefining key value pairs.

801
00:34:13,456 --> 00:34:15,666
If this isn't a problem,
if you have no expectation

802
00:34:15,666 --> 00:34:17,306
of localizing, not a big deal.

803
00:34:17,566 --> 00:34:19,016
But it is this easy.

804
00:34:19,016 --> 00:34:20,786
And it's a lot easier to
do it in the beginning,

805
00:34:20,786 --> 00:34:23,416
even if you just have
a Localizable.string

806
00:34:23,446 --> 00:34:24,376
with only English.

807
00:34:24,606 --> 00:34:26,586
Because just think how trivial
it is if you make a friend

808
00:34:26,586 --> 00:34:27,616
who speaks Spanish and he

809
00:34:27,616 --> 00:34:30,336
or she can then translate
your whole app for you just

810
00:34:30,336 --> 00:34:33,566
by your sending him or her that
text file to send back to you,

811
00:34:33,566 --> 00:34:35,246
the importance of a project.

812
00:34:35,786 --> 00:34:35,926
Yes?

813
00:34:36,516 --> 00:34:44,266
[ Background Discussion ]

814
00:34:44,766 --> 00:34:45,736
Ah, good question.

815
00:34:45,736 --> 00:34:48,596
By default there's still
one primary language.

816
00:34:48,596 --> 00:34:49,606
In this case it's English

817
00:34:49,606 --> 00:34:50,776
because that's what
I started with.

818
00:34:51,106 --> 00:34:53,636
So what would happen is that you
would get the English version

819
00:34:53,636 --> 00:34:54,106
by default.

820
00:34:54,396 --> 00:34:56,096
If the user has chosen
some other language

821
00:34:56,096 --> 00:34:57,916
that your app doesn't
explicitly support.

822
00:34:58,516 --> 00:35:02,336
[ Background Discussion ]

823
00:35:02,836 --> 00:35:03,326
Good question.

824
00:35:03,326 --> 00:35:04,166
Most likely.

825
00:35:04,166 --> 00:35:07,816
If Mac OS is configured for
Dutch and therefore X code is

826
00:35:07,816 --> 00:35:10,416
as well when you download
it from the Dutch app store,

827
00:35:10,676 --> 00:35:12,536
I believe that's
what will happen.

828
00:35:12,536 --> 00:35:16,216
But I've not had
occasion to test that.

829
00:35:16,396 --> 00:35:17,186
Other questions?

830
00:35:17,656 --> 00:35:19,856
All right.

831
00:35:20,196 --> 00:35:23,216
So, where can we take
things from here?

832
00:35:23,216 --> 00:35:28,946
So I propose that from
here there's a couple

833
00:35:28,946 --> 00:35:32,656
of gaps we can fill in before
moving onto the climax.

834
00:35:32,656 --> 00:35:36,926
Albeit a 1980's climax of
a two dimensional game.

835
00:35:37,436 --> 00:35:38,206
But sequel lites.

836
00:35:38,766 --> 00:35:40,806
Let's add one other
tool to your tool kit.

837
00:35:40,806 --> 00:35:44,496
What would sequel
lite all about?

838
00:35:44,496 --> 00:35:45,376
Okay, good.

839
00:35:45,606 --> 00:35:47,966
So it's a flat file
relational database.

840
00:35:47,966 --> 00:35:49,876
So this is just a
fancy way of saying,

841
00:35:49,876 --> 00:35:50,996
there's no server involved.

842
00:35:50,996 --> 00:35:52,846
There's just a big binary file

843
00:35:53,046 --> 00:35:55,246
that can sit inside
of your application.

844
00:35:55,246 --> 00:35:57,746
That can create the illusion of
a database to your application,

845
00:35:57,926 --> 00:35:59,126
namely a sequel database.

846
00:35:59,196 --> 00:36:01,596
And a sequel database
allows you to do searches

847
00:36:01,596 --> 00:36:05,116
and queries along the
lines of select and insert

848
00:36:05,116 --> 00:36:06,276
and delete and update.

849
00:36:06,276 --> 00:36:07,646
And even if you're not
familiar with that,

850
00:36:07,886 --> 00:36:11,176
those four letters together
compose a paradigm called CRUD.

851
00:36:11,616 --> 00:36:14,406
C R U D for create,
read, update, delete.

852
00:36:14,636 --> 00:36:17,046
Which is a very common paradigm
for talking to a database

853
00:36:17,046 --> 00:36:18,346
which essentially
lets you do anything.

854
00:36:18,346 --> 00:36:19,116
You can read from it.

855
00:36:19,356 --> 00:36:20,216
You can write to it.

856
00:36:20,216 --> 00:36:21,656
You can update things,
you can delete things,

857
00:36:21,656 --> 00:36:24,316
you can store data
in we write fashion.

858
00:36:24,566 --> 00:36:29,656
So why would you care to use
sequel in this database language

859
00:36:29,656 --> 00:36:32,316
as opposed to just using a P
list, like we've been using

860
00:36:32,366 --> 00:36:33,686
for the second project.

861
00:36:34,146 --> 00:36:37,406
Or even .strings file, you
just have a list of strings

862
00:36:37,406 --> 00:36:39,906
or some other file
format altogether.

863
00:36:43,616 --> 00:36:44,936
Speed? In what sense?

864
00:36:45,516 --> 00:36:51,546
[ Background Discussion ]

865
00:36:52,046 --> 00:36:54,856
For sure. Certainly
for large data sets

866
00:36:54,856 --> 00:36:56,476
for you have thousands,
tens of thousands,

867
00:36:56,476 --> 00:36:57,916
hundreds of thousands
of records.

868
00:36:57,916 --> 00:36:59,796
If you stored it
in a P list, well,

869
00:36:59,796 --> 00:37:01,726
by default that's
just an XML file.

870
00:37:01,726 --> 00:37:03,876
So really, it's just
a big long list.

871
00:37:04,116 --> 00:37:06,456
So if you were to do
searches on a property list,

872
00:37:06,456 --> 00:37:09,436
you essentially devolve
into linear search.

873
00:37:09,436 --> 00:37:11,566
And in an worst case, maybe
the structure you're looking

874
00:37:11,566 --> 00:37:14,416
for in the dictionary is at
the end of that P list file.

875
00:37:14,416 --> 00:37:17,066
So it's going to take you
thousands or tens of thousands

876
00:37:17,196 --> 00:37:19,716
of reads in order to find
the word you're looking for.

877
00:37:19,886 --> 00:37:22,006
By contrast, if you
use an actual database,

878
00:37:22,006 --> 00:37:24,336
whether it's my sequel or
oracle in the real world,

879
00:37:24,486 --> 00:37:27,156
or sequel lite in a constrained
environment like this,

880
00:37:27,156 --> 00:37:30,336
you can say something like,
select the word that starts

881
00:37:30,336 --> 00:37:33,196
with Z. So I'm using sort
of pseudo code verbally.

882
00:37:33,416 --> 00:37:35,156
But you can express
yourself more precisely.

883
00:37:35,156 --> 00:37:39,166
Select the word that starts with
Z and what sequel lite can do

884
00:37:39,166 --> 00:37:41,646
for you, if you tell it in
advance, is it can give you,

885
00:37:41,646 --> 00:37:42,676
what are called, indexs.

886
00:37:43,206 --> 00:37:46,146
Essentially, tree structures
that have been saved

887
00:37:46,146 --> 00:37:48,596
to this file that once
loaded into memory,

888
00:37:48,596 --> 00:37:51,456
allowed you to search
this file much faster

889
00:37:51,526 --> 00:37:53,576
than say linear search
would allow you to do.

890
00:37:53,576 --> 00:37:56,076
So at least for large
data sets, it allows you

891
00:37:56,076 --> 00:37:58,056
to express yourself a
little bit more precisely

892
00:37:58,056 --> 00:37:59,996
than just iterating over
a big list of things.

893
00:38:00,236 --> 00:38:02,596
And to get that data
more quickly.

894
00:38:02,926 --> 00:38:06,236
Unfortunately, for those of you
who are familiar with sequel,

895
00:38:06,506 --> 00:38:10,096
the price you pay is in shear
complexity of the codes.

896
00:38:10,096 --> 00:38:13,156
Since to date, it's still a
C library, which is a pain

897
00:38:13,156 --> 00:38:15,126
in the neck to use
when doing something

898
00:38:15,166 --> 00:38:16,676
as simple as we just described.

899
00:38:16,976 --> 00:38:19,926
But nonetheless, so that you
have this expressive capability

900
00:38:20,066 --> 00:38:22,786
at your disposal, particularly
for your third project

901
00:38:22,786 --> 00:38:25,336
of doing something with
a decent sized data set,

902
00:38:25,556 --> 00:38:27,956
let's take a look at this
example, called sequel lite

903
00:38:27,956 --> 00:38:30,276
from tonight's code base.

904
00:38:30,626 --> 00:38:34,016
AppDelegate look special?

905
00:38:34,106 --> 00:38:35,376
No, nothing new there.

906
00:38:35,556 --> 00:38:38,566
AppDelegate.m, anything
going on here?

907
00:38:39,376 --> 00:38:40,346
Nothing there.

908
00:38:40,346 --> 00:38:42,416
So hopefully the
interesting stuff starts

909
00:38:42,786 --> 00:38:44,096
in the nib file, okay.

910
00:38:44,336 --> 00:38:46,656
So, apparently this app
has to do with cities.

911
00:38:47,176 --> 00:38:50,466
Known as just again,
stupid boiler plate patterns

912
00:38:50,466 --> 00:38:53,086
of any UI table ViewController.

913
00:38:53,086 --> 00:38:54,996
So, this just means the
application has a table

914
00:38:54,996 --> 00:38:57,396
ViewController, and let's
actually spoil the results.

915
00:38:57,396 --> 00:38:59,166
Let me go ahead and
run this application

916
00:38:59,396 --> 00:39:01,886
and see what happens
inside of the simulator.

917
00:39:02,146 --> 00:39:04,006
And what we can see
here in the simulator is

918
00:39:04,006 --> 00:39:07,426
that all this application
does is it opens the contents

919
00:39:07,426 --> 00:39:10,736
of a sequel lite database
called small.sqlite,

920
00:39:10,736 --> 00:39:11,886
as we'll see shortly.

921
00:39:12,166 --> 00:39:14,066
And it lists those five words.

922
00:39:14,066 --> 00:39:16,266
From the small P list
file that we gave you

923
00:39:16,406 --> 00:39:17,706
for the most recent project.

924
00:39:17,706 --> 00:39:20,286
So what I did in advance
was I wrote a little script

925
00:39:20,286 --> 00:39:22,206
that converted that
property list file

926
00:39:22,206 --> 00:39:24,186
into a binary sequel lite file.

927
00:39:24,346 --> 00:39:25,726
It's pretty easy to do.

928
00:39:25,826 --> 00:39:29,526
And then I included the
small.sqlite file inside

929
00:39:29,526 --> 00:39:32,276
of the project by just dragging
and dropping it from my desktop.

930
00:39:32,766 --> 00:39:36,586
So, how is this actually
behaving in this way?

931
00:39:36,916 --> 00:39:37,696
Well, let's take a look

932
00:39:37,696 --> 00:39:40,486
at ViewController.h.
Nothing going on there.

933
00:39:40,646 --> 00:39:44,046
So all the logic must be
in ViewController.m. So,

934
00:39:44,046 --> 00:39:47,546
first of all, notice that I've
declared an NSMutableArray

935
00:39:47,546 --> 00:39:48,976
as a property called words.

936
00:39:48,976 --> 00:39:50,736
And this is just where I'm
going to store my words

937
00:39:50,736 --> 00:39:51,836
when actually using them.

938
00:39:51,836 --> 00:39:54,136
Much like you probably
have for evil hang man

939
00:39:54,136 --> 00:39:55,566
after you've loaded
the property list.

940
00:39:56,036 --> 00:39:59,196
And if I scroll down here, let
me get rid of one remnant there.

941
00:39:59,416 --> 00:40:01,046
I have in initWithNibName.

942
00:40:01,396 --> 00:40:02,976
And this is where
the nightmare begins.

943
00:40:03,266 --> 00:40:05,906
So, and I say this, because
it's just a pain in the neck

944
00:40:05,906 --> 00:40:09,226
to actually code sequel
queries in this way.

945
00:40:09,226 --> 00:40:11,176
But, this is the way it
is, not only in objective C

946
00:40:11,176 --> 00:40:13,306
but in some other environment
as well to this day.

947
00:40:13,886 --> 00:40:16,256
So, notice I'm first
initializing myself

948
00:40:16,256 --> 00:40:17,086
with the nib name.

949
00:40:17,086 --> 00:40:18,846
Whatever that was, by
calling the parent class.

950
00:40:19,526 --> 00:40:23,116
Then I'm declaring an
NSMutableArray here

951
00:40:23,436 --> 00:40:25,296
and assigning it to my property.

952
00:40:25,296 --> 00:40:27,306
So I just have an
empty changeable array.

953
00:40:27,306 --> 00:40:30,506
And now, what am I
doing in English or sort

954
00:40:30,506 --> 00:40:32,466
of semi technical English
with this highlighted line.

955
00:40:33,966 --> 00:40:35,616
What's apparently
going on there,

956
00:40:35,616 --> 00:40:37,706
even if you've never
used sequel lite before?

957
00:40:38,386 --> 00:40:39,206
Yes. Good.

958
00:40:43,096 --> 00:40:45,366
So I'm creating a
pointer called DB

959
00:40:45,366 --> 00:40:47,526
to an object of type
sequel lite.

960
00:40:47,596 --> 00:40:48,756
Whatever that happens to be.

961
00:40:48,756 --> 00:40:50,436
It's some kind of
structure presumably.

962
00:40:50,436 --> 00:40:53,486
And then in that next
line, notice I'm going back

963
00:40:53,486 --> 00:40:54,616
into objective C mode.

964
00:40:54,616 --> 00:40:57,346
The highlighted line
is effectively C.

965
00:40:57,666 --> 00:41:01,436
So here I'm declaring a path
variable that's the result

966
00:41:01,436 --> 00:41:06,206
of looking for the file called
small of type sequel lites.

967
00:41:06,276 --> 00:41:09,466
So this is just a fairly robust
way of saying, give me the path

968
00:41:09,836 --> 00:41:11,996
to the file called small.sqlite.

969
00:41:12,216 --> 00:41:15,046
And notice over here on the
left, that's the file I promised

970
00:41:15,256 --> 00:41:16,996
that I dragged and
dropped into the project.

971
00:41:16,996 --> 00:41:17,836
It's a binary file.

972
00:41:17,836 --> 00:41:19,986
So clicking on it won't
actually show me the contents.

973
00:41:20,386 --> 00:41:22,276
Now here, is a bit of syntax.

974
00:41:22,276 --> 00:41:23,386
We haven't seen too much.

975
00:41:23,386 --> 00:41:25,866
But you might recall from
Rob's lecture a few weeks back.

976
00:41:26,286 --> 00:41:29,936
Sqlite3_open is a C function

977
00:41:30,336 --> 00:41:33,406
that opens a database
connection.

978
00:41:33,646 --> 00:41:37,446
So, database, notice that
path is of what data type

979
00:41:37,446 --> 00:41:40,866
in this point of the story?

980
00:41:41,056 --> 00:41:42,006
It's an NS string.

981
00:41:42,236 --> 00:41:46,086
But sqlite3_open, perhaps take
my word for it, is a C function

982
00:41:46,246 --> 00:41:49,816
that has no concept of
objective C classes of observe.

983
00:41:50,306 --> 00:41:53,456
So we essentially have to
convert path from an NS string

984
00:41:53,746 --> 00:41:56,136
to what's called, what most
people call a char star.

985
00:41:56,136 --> 00:42:00,026
A raw C style string
which is just the dress

986
00:42:00,026 --> 00:42:01,526
of a bunch of character.

987
00:42:01,846 --> 00:42:02,656
A character array.

988
00:42:02,656 --> 00:42:05,506
And so what this line is
doing is exactly that.

989
00:42:05,716 --> 00:42:10,356
It's opening the file
call that's at that path

990
00:42:10,456 --> 00:42:13,476
and storing it inside
of the DB pointer.

991
00:42:14,146 --> 00:42:15,266
Okay? What's happening next?

992
00:42:15,266 --> 00:42:16,356
I'm selecting all words.

993
00:42:16,356 --> 00:42:18,666
So, this is what I meant earlier
about the expressiveness.

994
00:42:18,756 --> 00:42:20,096
This is a sequel query.

995
00:42:20,326 --> 00:42:22,676
And this file at the end is only
going to have one such query.

996
00:42:22,676 --> 00:42:25,426
But again there's other key
words like delete, update,

997
00:42:25,426 --> 00:42:28,166
insert, any others, select
is the operative word here.

998
00:42:28,526 --> 00:42:31,656
Here I'm declaring an
NS string called sequel.

999
00:42:31,946 --> 00:42:34,426
In the next line, I'm
dropping back down into C,

1000
00:42:34,426 --> 00:42:35,546
declaring a statement.

1001
00:42:36,336 --> 00:42:40,516
And then in this third line
I'm calling sqlite3_prepare_v2.

1002
00:42:40,516 --> 00:42:45,296
This is what happens when you
overall plan your functions

1003
00:42:45,296 --> 00:42:47,016
ahead and names get like this.

1004
00:42:47,016 --> 00:42:49,706
And then I'm passing
in a few values.

1005
00:42:49,706 --> 00:42:53,706
Again, converting from a C
an objective C style object

1006
00:42:53,986 --> 00:42:55,496
to a C style string.

1007
00:42:55,496 --> 00:42:57,956
And let me wave my hand at
some of the details there.

1008
00:42:57,956 --> 00:43:00,166
But what this just
means is get ready

1009
00:43:00,166 --> 00:43:03,306
to execute the previously
declared query.

1010
00:43:03,516 --> 00:43:06,836
Select star from
select word from words.

1011
00:43:07,116 --> 00:43:08,076
So what is words?

1012
00:43:08,076 --> 00:43:10,256
Words, again, is the database.

1013
00:43:10,256 --> 00:43:13,486
Or specifically, it's a
table inside of the database.

1014
00:43:13,486 --> 00:43:14,596
Like an excel spread sheet.

1015
00:43:14,856 --> 00:43:17,556
And word, specifically,
is is one such column

1016
00:43:17,726 --> 00:43:18,726
from that spread sheet.

1017
00:43:18,996 --> 00:43:20,636
So this is a super
simple database.

1018
00:43:20,636 --> 00:43:22,326
It essentially is an excel file

1019
00:43:22,506 --> 00:43:24,666
with a single column
A, if you will.

1020
00:43:24,666 --> 00:43:28,406
And column A is called just
because I named it such word.

1021
00:43:28,676 --> 00:43:31,096
So it's not even that
interesting of a database.

1022
00:43:31,526 --> 00:43:31,646
Yes?

1023
00:43:32,516 --> 00:43:40,016
[ Background Discussion ]

1024
00:43:40,516 --> 00:43:43,456
Exactly. So you don't
strictly need

1025
00:43:43,456 --> 00:43:45,276
to specify the database name.

1026
00:43:45,276 --> 00:43:46,996
You don't need to
say database.table

1027
00:43:46,996 --> 00:43:48,476
if it's obvious from
the context.

1028
00:43:48,776 --> 00:43:51,006
And in this case, you can
infer it from the context

1029
00:43:51,006 --> 00:43:52,476
because when we open
the connection,

1030
00:43:52,716 --> 00:43:55,086
we open the connection
to a specific database.

1031
00:43:55,426 --> 00:43:56,616
So that part has already

1032
00:43:56,926 --> 00:43:59,256
that question has already
been answered for the library.

1033
00:44:00,066 --> 00:44:02,906
So now down here is where we
are actually fetching data.

1034
00:44:03,366 --> 00:44:08,576
So by calling sqlite3_step,
passing in that statement

1035
00:44:08,576 --> 00:44:10,226
that I've prepared
in the previous line,

1036
00:44:10,666 --> 00:44:13,876
If that equals SQLITE_ROW
so, in other words,

1037
00:44:13,876 --> 00:44:16,336
if that function returns to
[inaudible] row in the form

1038
00:44:16,336 --> 00:44:19,306
of a structure, I can then
proceed to do the following.

1039
00:44:19,626 --> 00:44:24,706
This next line of code gets
the 0th column or the 0 cell

1040
00:44:24,706 --> 00:44:27,826
from that 0th column
from that return cell.

1041
00:44:28,316 --> 00:44:31,766
And then in this next
one, I convert the string

1042
00:44:31,766 --> 00:44:34,206
that I've gotten back
to what kind of object?

1043
00:44:34,946 --> 00:44:39,126
So in NS string.

1044
00:44:39,186 --> 00:44:41,696
And then the last
line, I'm finally back

1045
00:44:41,696 --> 00:44:43,076
to more familiar territory.

1046
00:44:43,076 --> 00:44:45,556
I'm adding that string
to my property,

1047
00:44:45,556 --> 00:44:48,826
which is a NSMutableArray
called words.

1048
00:44:49,276 --> 00:44:51,396
So again, the difference
here, for those less familiar

1049
00:44:51,396 --> 00:44:54,386
with C is that in C there
is no notion of an object.

1050
00:44:54,386 --> 00:44:55,386
There is no notion of a class.

1051
00:44:55,386 --> 00:44:57,196
It's not an object
oriented language.

1052
00:44:57,196 --> 00:44:59,256
So to implement the
idea of a string,

1053
00:44:59,636 --> 00:45:01,936
what C does is it uses an array.

1054
00:45:01,936 --> 00:45:04,026
So, a chunk, chunk, chunk,
chunk, chunk of memory.

1055
00:45:04,346 --> 00:45:08,036
And then to represent the
string, it uses a back slash N,

1056
00:45:08,086 --> 00:45:09,946
a null character at
the end of the string.

1057
00:45:10,216 --> 00:45:14,086
And then it gives to you the
address of the first character.

1058
00:45:14,086 --> 00:45:16,676
So in C, if you know the
address of the first character,

1059
00:45:16,896 --> 00:45:18,556
and you know that
there's guaranteed

1060
00:45:18,556 --> 00:45:20,536
to be a null character
at the end of the string,

1061
00:45:20,746 --> 00:45:22,866
you can figure out how
long it that string is

1062
00:45:22,866 --> 00:45:25,346
and what the word being
expressed actually is.

1063
00:45:25,346 --> 00:45:27,416
[Inaudible] where whatever
it is in the database.

1064
00:45:27,956 --> 00:45:30,506
Objective C by contrast
using classes and objects.

1065
00:45:30,506 --> 00:45:31,866
So maybe that's how a string,

1066
00:45:31,896 --> 00:45:33,746
an NS string is implemented
underneath the hood,

1067
00:45:33,746 --> 00:45:34,576
we just don't know.

1068
00:45:34,846 --> 00:45:35,996
So what these several lines

1069
00:45:35,996 --> 00:45:38,116
of code are doing
ultimately is toggling back

1070
00:45:38,116 --> 00:45:41,876
between these modes so as to use
the C base sequel lite library,

1071
00:45:42,186 --> 00:45:44,816
while still using it
in objective C context.

1072
00:45:44,816 --> 00:45:47,536
And then lastly, that we
close the database connection.

1073
00:45:47,966 --> 00:45:50,746
And the rest of the code
here which we won't trace

1074
00:45:50,746 --> 00:45:53,796
through in any detail, is pretty
much the same as last week.

1075
00:45:54,156 --> 00:45:57,026
The rest of the code just has
to do with the UI table view

1076
00:45:57,026 --> 00:45:59,786
and somehow defining
the cells that you see

1077
00:46:00,046 --> 00:46:02,036
when asked what goes in row 0.

1078
00:46:02,036 --> 00:46:03,116
What goes in row one.

1079
00:46:03,116 --> 00:46:05,336
What goes in row
two and so forth.

1080
00:46:06,296 --> 00:46:08,966
But there's one thing I had
to do behind the scenes.

1081
00:46:09,656 --> 00:46:12,806
Recall that for quite some
time under frame works,

1082
00:46:13,136 --> 00:46:15,926
we had just UIKit.framework,
foundation.framework,

1083
00:46:15,926 --> 00:46:18,756
CoreGraphics.framework, which we
finally started using tonight.

1084
00:46:19,056 --> 00:46:22,036
Notice that in supporting
files, there's something similar

1085
00:46:22,036 --> 00:46:24,066
in spirit, but it's a C library.

1086
00:46:24,066 --> 00:46:25,806
So it's called a
dynamic library.

1087
00:46:26,216 --> 00:46:28,956
Sqllib sqlite3.dylib.

1088
00:46:29,046 --> 00:46:32,636
This is a file that I
did not drag and drop

1089
00:46:32,636 --> 00:46:33,966
into may project per se.

1090
00:46:33,966 --> 00:46:36,116
Rather, in order to
use this library,

1091
00:46:36,416 --> 00:46:39,496
and potentially any other
libraries that Apple provides,

1092
00:46:39,866 --> 00:46:42,096
I went into my target.

1093
00:46:42,476 --> 00:46:44,426
Went to build phases.

1094
00:46:44,956 --> 00:46:46,556
Went to link binary.

1095
00:46:46,556 --> 00:46:49,936
And here is where you
see the list of libraries

1096
00:46:49,976 --> 00:46:51,626
that your application is using.

1097
00:46:51,626 --> 00:46:54,426
By default, we've always
gotten those three objective

1098
00:46:54,496 --> 00:46:55,226
C libraries.

1099
00:46:55,666 --> 00:46:59,126
Today I needed a fourth library,
mainly the sequel lite library.

1100
00:46:59,336 --> 00:47:02,276
So to get there, I had to click
that plus icon and then look

1101
00:47:02,276 --> 00:47:04,026
through a list of libraries.

1102
00:47:04,026 --> 00:47:06,376
And you'll see there's an
overwhelming number of options.

1103
00:47:06,786 --> 00:47:10,506
Suggested of how much more you
can do with the environment.

1104
00:47:10,506 --> 00:47:12,546
If you really dive in
deeper, this happens

1105
00:47:12,576 --> 00:47:13,946
to be a C based library.

1106
00:47:13,946 --> 00:47:17,186
And what do you think is
inside of this library?

1107
00:47:17,896 --> 00:47:22,136
What is the point of adding this
row to this configuration table?

1108
00:47:24,216 --> 00:47:26,296
I wrote Sqlite earlier, right?

1109
00:47:26,296 --> 00:47:28,496
I wrote the various
function calls.

1110
00:47:29,576 --> 00:47:31,106
Why do I need to add
something like this?

1111
00:47:31,106 --> 00:47:35,056
What must be inside there?

1112
00:47:35,246 --> 00:47:36,986
What's that?

1113
00:47:37,196 --> 00:47:40,056
All the function definitions,
so the actual implementations.

1114
00:47:40,056 --> 00:47:42,316
The only thing I had to
do even though we glossed

1115
00:47:42,316 --> 00:47:45,256
over it earlier, is in
my ViewController.m file,

1116
00:47:45,256 --> 00:47:47,646
I did import this .h file,

1117
00:47:47,646 --> 00:47:51,156
but in a .h file is not the
implementation of some function.

1118
00:47:51,156 --> 00:47:52,716
And typically is
in some other file.

1119
00:47:52,956 --> 00:47:55,306
So, if I actually want
the bits, the 0's and 1's,

1120
00:47:55,306 --> 00:47:58,596
that collectively compose
the Sqlite statement query,

1121
00:47:58,596 --> 00:48:01,506
the close query, the
open query I need

1122
00:48:01,506 --> 00:48:05,106
to actually import those bits
at link time so to speak.

1123
00:48:05,106 --> 00:48:06,026
And the means by which you do

1124
00:48:06,026 --> 00:48:09,146
that in X code is via the
project's own properties

1125
00:48:09,146 --> 00:48:10,066
under build phases.

1126
00:48:10,336 --> 00:48:11,766
So, FYI. Yes?

1127
00:48:12,516 --> 00:48:24,646
[ Background Discussion ]

1128
00:48:25,146 --> 00:48:27,886
Short answer not as
cleanly as would be ideal.

1129
00:48:27,886 --> 00:48:29,456
Rather there's an
even higher of layer

1130
00:48:29,456 --> 00:48:31,416
of abstraction called core data,

1131
00:48:31,746 --> 00:48:34,246
which is actually a pretty
raw topic onto itself.

1132
00:48:34,356 --> 00:48:36,236
But it's essentially
an abstraction layer

1133
00:48:36,236 --> 00:48:37,496
on top of sequel.

1134
00:48:37,496 --> 00:48:40,306
Or it can be on top of something
else potentially that allows you

1135
00:48:40,306 --> 00:48:43,606
to define your entities and
your relations without going

1136
00:48:43,606 --> 00:48:45,106
into the depths of sequel.

1137
00:48:45,106 --> 00:48:46,626
All of that would be
generated for you.

1138
00:48:47,786 --> 00:48:48,976
So, short answer no.

1139
00:48:48,976 --> 00:48:52,496
No wrapper in objective C
rather apple leap frogged

1140
00:48:52,636 --> 00:48:55,286
and went one level higher.

1141
00:48:55,546 --> 00:48:56,886
Quite possibly.

1142
00:48:56,886 --> 00:48:59,556
Yes. I've not used one, but
there's not one that comes

1143
00:48:59,556 --> 00:49:00,646
out of the box officially.

1144
00:49:01,586 --> 00:49:02,546
Good question.

1145
00:49:03,916 --> 00:49:07,276
So wonderfully useful, but
also takes some getting use to.

1146
00:49:07,356 --> 00:49:08,966
So, keep that in mind.

1147
00:49:08,966 --> 00:49:10,446
But much more powerful
than something

1148
00:49:10,446 --> 00:49:12,006
like the single key list file.

1149
00:49:12,766 --> 00:49:16,516
So let me open up a
little teaser here.

1150
00:49:16,816 --> 00:49:20,566
Some of you may recall or have
at least heard of a little game,

1151
00:49:20,566 --> 00:49:22,446
that for many years was amazing.

1152
00:49:23,396 --> 00:49:24,496
And it looked like this.

1153
00:49:24,496 --> 00:49:25,536
Let me go ahead and run this.

1154
00:49:25,986 --> 00:49:30,696
I'm going to put the iPhone
into a landscape mode this time.

1155
00:49:31,266 --> 00:49:34,406
And notice that the computer
is playing on the left.

1156
00:49:34,406 --> 00:49:36,006
And the human, I'm
playing, on the right.

1157
00:49:36,176 --> 00:49:39,396
By moving the cursor or my
finger, really, up and down.

1158
00:49:40,696 --> 00:49:42,876
If I do this, I can
do this all day long.

1159
00:49:43,606 --> 00:49:46,476
This will just play and play
until I do something stupid,

1160
00:49:46,926 --> 00:49:49,576
whereby if I forget to
move, now he has the points.

1161
00:49:50,096 --> 00:49:52,236
So, why don't we go ahead and
take our five minute break.

1162
00:49:52,506 --> 00:49:53,796
I really lost fast there.

1163
00:49:53,796 --> 00:49:55,156
Why don't we take our
five minute break here

1164
00:49:55,156 --> 00:49:58,396
and when we come back we
will implement pong together.

1165
00:49:58,686 --> 00:50:04,896
All right, so first let's
resume by lowering expectations.

1166
00:50:04,896 --> 00:50:06,496
This is an example
called paddle,

1167
00:50:06,496 --> 00:50:07,966
which is among tonight's
examples,

1168
00:50:08,236 --> 00:50:10,316
whose sole purpose
is to do this.

1169
00:50:10,566 --> 00:50:12,586
But it's a good building block
if we actually want to get

1170
00:50:12,586 --> 00:50:15,736
to the point of actually having
a bit of AI, if you will.

1171
00:50:15,736 --> 00:50:18,476
You'll notice if you play the
pong game as its been written,

1172
00:50:18,676 --> 00:50:21,356
the computer will
never ever lose.

1173
00:50:21,356 --> 00:50:24,356
Because it will see the code
is written in such a way

1174
00:50:24,356 --> 00:50:26,206
that the paddle always
move to precisely

1175
00:50:26,206 --> 00:50:28,436
where the ball is no
matter where you hit it.

1176
00:50:28,436 --> 00:50:30,466
So, only the human
can lose that game.

1177
00:50:30,806 --> 00:50:33,346
But, we'll start by at least
making our own paddle here.

1178
00:50:33,346 --> 00:50:35,706
The cursor there on the screen
is what my finger would be

1179
00:50:35,706 --> 00:50:37,156
if we weren't doing
this in the simulator.

1180
00:50:37,406 --> 00:50:39,226
But first, we need a
little bit of context.

1181
00:50:39,226 --> 00:50:41,236
So let me switch over
here for just a moment.

1182
00:50:41,546 --> 00:50:44,726
Just to paint a picture of how
your mental model should be

1183
00:50:44,726 --> 00:50:45,826
when it comes to graphics.

1184
00:50:45,826 --> 00:50:47,306
So, correspond graphics
is the context.

1185
00:50:47,566 --> 00:50:49,516
We've seen this library included

1186
00:50:49,646 --> 00:50:51,526
for every example
we've done thus far.

1187
00:50:51,526 --> 00:50:53,656
But this is the first night
where we're actually using it.

1188
00:50:53,966 --> 00:50:59,406
And what's worth keeping in mind
is this system got to get better

1189
00:50:59,406 --> 00:51:01,066
at this this coordinate
system here.

1190
00:51:01,546 --> 00:51:04,576
So I looked for newer image, but
even Apple documentation uses

1191
00:51:04,576 --> 00:51:06,146
like the iPhone three
for this example.

1192
00:51:06,426 --> 00:51:07,856
But it's really just
to paint a picture

1193
00:51:07,856 --> 00:51:09,566
of the coordinate system in iOS.

1194
00:51:10,036 --> 00:51:14,266
Which is this plain, where we
have X coordinates on the right,

1195
00:51:14,396 --> 00:51:16,356
Y coordinates on the vertical.

1196
00:51:16,526 --> 00:51:18,476
And this is just the
take away here is

1197
00:51:18,476 --> 00:51:19,746
that the coordinate
system begins

1198
00:51:19,746 --> 00:51:21,146
on the top left hand corners.

1199
00:51:21,146 --> 00:51:24,626
So, ten comma ten means
ten over and ten down.

1200
00:51:24,626 --> 00:51:26,106
Not the opposite
as you might know

1201
00:51:26,106 --> 00:51:29,686
from say typical [inaudible]
coordinates and algebra.

1202
00:51:30,156 --> 00:51:34,756
So, the catch is as Apple's
hardware has advanced over time,

1203
00:51:34,756 --> 00:51:36,966
that resolution have
started to change, right?

1204
00:51:36,966 --> 00:51:39,526
There was the retina
display and the iPhone four,

1205
00:51:39,526 --> 00:51:41,586
when the resolution
essentially doubled.

1206
00:51:41,946 --> 00:51:44,206
And unfortunately, this
could have broken a whole lot

1207
00:51:44,206 --> 00:51:45,006
of applications.

1208
00:51:45,216 --> 00:51:48,736
But Apple actually anticipated
something like this in the sense

1209
00:51:48,736 --> 00:51:52,256
that you don't think of graphics
in the two dimensional world

1210
00:51:52,256 --> 00:51:54,616
of iOS as pixels, but
instead as points.

1211
00:51:54,616 --> 00:51:56,726
And a point is still just a dot.

1212
00:51:57,196 --> 00:52:01,166
But it might be one pixel,
or maybe it's four pixels.

1213
00:52:01,166 --> 00:52:02,586
It depends on your perspective.

1214
00:52:02,586 --> 00:52:05,066
So they introduce this layer
of abstraction called points.

1215
00:52:05,456 --> 00:52:08,086
So that you're respective
of the actual resolution.

1216
00:52:08,336 --> 00:52:12,116
The operating system will
double your graphics as needed

1217
00:52:12,116 --> 00:52:13,486
or shrink them as needed.

1218
00:52:13,486 --> 00:52:15,126
Now this has it's
a two edge sword.

1219
00:52:15,126 --> 00:52:17,676
It's on the one hand, super
convenient, on the other hand

1220
00:52:17,676 --> 00:52:20,806
if you've ever used an IO
an iPhone only application

1221
00:52:20,906 --> 00:52:23,396
on an iPad, it just looks kind
of ridiculous when you zoom

1222
00:52:23,466 --> 00:52:26,066
in at two X. But that's really
the only alternative would be

1223
00:52:26,066 --> 00:52:27,616
to not let the user
play it at all.

1224
00:52:28,016 --> 00:52:31,066
So now if we scroll over
to this system here,

1225
00:52:31,476 --> 00:52:34,436
you'll see the iPhone
four and the iPhone five.

1226
00:52:34,436 --> 00:52:35,806
So the annoying thing here is

1227
00:52:35,806 --> 00:52:38,926
that Apple didn't just double
the resolution, they just kind

1228
00:52:38,926 --> 00:52:40,266
of stretched it a little bit.

1229
00:52:40,326 --> 00:52:42,296
So there were a few more
pixels now on the screen.

1230
00:52:42,296 --> 00:52:43,686
So this was more problematic.

1231
00:52:43,816 --> 00:52:45,656
And there's still some apps
out there that you might have

1232
00:52:45,656 --> 00:52:48,756
on your own phones that now
have letter boxing on the bottom

1233
00:52:48,756 --> 00:52:50,666
or on the top with
just black bars.

1234
00:52:50,666 --> 00:52:52,036
If you have an iPhone five

1235
00:52:52,036 --> 00:52:53,506
and you're using
somewhat older software

1236
00:52:53,506 --> 00:52:54,936
that the developers
hadn't updated.

1237
00:52:55,286 --> 00:52:57,146
So in this case,
the number of points

1238
00:52:57,146 --> 00:52:58,706
on the screen has
actually changed.

1239
00:52:58,706 --> 00:53:00,826
It's still 320 pixels across,

1240
00:53:01,326 --> 00:53:06,326
but it's now 568 tall
instead of 480 tall.

1241
00:53:06,606 --> 00:53:07,676
So this is why Apple,

1242
00:53:07,676 --> 00:53:10,356
as in aside introduced
something called auto layout

1243
00:53:10,476 --> 00:53:12,576
with the most recent
version of X code.

1244
00:53:12,726 --> 00:53:15,016
And we saw me use it
ever so briefly earlier.

1245
00:53:15,016 --> 00:53:17,746
When I said to vertically
center the label that I dragged

1246
00:53:17,746 --> 00:53:19,706
and dropped by choosing
a vertical constraint.

1247
00:53:20,226 --> 00:53:23,446
This is the new means by which
you can essentially lay things

1248
00:53:23,446 --> 00:53:24,666
out dynamically.

1249
00:53:24,666 --> 00:53:26,506
Unfortunately it doesn't
quite work as easily.

1250
00:53:26,506 --> 00:53:28,446
If you're implementing
something like Angry Birds

1251
00:53:28,446 --> 00:53:31,396
or something graphical where
there's a pixel precision

1252
00:53:31,466 --> 00:53:34,276
when it comes to your graphics.

1253
00:53:34,616 --> 00:53:35,856
So some people actually have

1254
00:53:35,856 --> 00:53:37,976
to use different graphics
for different modes.

1255
00:53:37,976 --> 00:53:38,946
And that's why we started

1256
00:53:38,946 --> 00:53:41,596
to see more [inaudible]
among the supporting files

1257
00:53:41,596 --> 00:53:42,426
and all the projects.

1258
00:53:42,426 --> 00:53:43,826
One is a bigger splash screen.

1259
00:53:43,826 --> 00:53:45,876
One is a smaller
splash screen depending

1260
00:53:45,876 --> 00:53:47,286
on the device that
someone's using.

1261
00:53:47,286 --> 00:53:49,216
So it's starting to get
a little more android

1262
00:53:49,216 --> 00:53:50,916
like in its new sense.

1263
00:53:50,916 --> 00:53:53,036
So we'll see what happens next
with the iPad, which is like,

1264
00:53:53,036 --> 00:53:55,526
would become, right
now before long as well

1265
00:53:55,756 --> 00:53:57,246
at a higher resolution.

1266
00:53:57,646 --> 00:53:58,206
All right.

1267
00:53:58,206 --> 00:53:59,886
So how do we go about
implementing something.

1268
00:53:59,886 --> 00:54:02,266
It's relatively straight
forward as this.

1269
00:54:02,306 --> 00:54:03,566
There's some new ingredients.

1270
00:54:03,846 --> 00:54:09,366
But what are some now
familiar ingredients if we want

1271
00:54:09,366 --> 00:54:10,816
to implement something
like this?

1272
00:54:12,086 --> 00:54:15,146
What concepts or code can we
steal from recent examples

1273
00:54:15,186 --> 00:54:16,336
to implement this paddle?

1274
00:54:16,336 --> 00:54:18,236
The sole purpose in life
is to go up and down.

1275
00:54:18,666 --> 00:54:22,486
Yes? Yes, so maybe a
pan gesture recognizer

1276
00:54:22,486 --> 00:54:24,436
so that we can actually
detect the user moving his

1277
00:54:24,436 --> 00:54:26,526
or her finger up or
down in this case.

1278
00:54:26,526 --> 00:54:27,776
And just ignore their finger

1279
00:54:27,776 --> 00:54:30,936
if it moves along
the left right axis.

1280
00:54:30,936 --> 00:54:31,716
All right.

1281
00:54:31,716 --> 00:54:33,926
So, let's take a look
at how this begins.

1282
00:54:34,056 --> 00:54:35,056
AppDelegate?

1283
00:54:35,056 --> 00:54:35,696
Same as usual.

1284
00:54:35,696 --> 00:54:37,896
AppDelegate.m, same as usual.

1285
00:54:37,896 --> 00:54:38,806
So, no magic there.

1286
00:54:38,806 --> 00:54:40,966
So everything must be
going on in interesting.

1287
00:54:41,466 --> 00:54:43,816
I have a new file
altogether this time.

1288
00:54:43,816 --> 00:54:45,936
A pair of files called
PaddleView.h,

1289
00:54:46,266 --> 00:54:49,756
PaddleView.m. Let's take
a look at the H file first

1290
00:54:49,756 --> 00:54:51,646
to see what this class is.

1291
00:54:51,646 --> 00:54:53,866
And it looks actually
pretty trivial.

1292
00:54:54,236 --> 00:54:57,116
So I'm just importing new UI
kit, which is pretty typical.

1293
00:54:57,116 --> 00:54:59,436
And then I'm declaring a
class called paddle view.

1294
00:54:59,666 --> 00:55:01,176
And it's of type of UI view.

1295
00:55:01,436 --> 00:55:03,886
So this is the first time
we've actually declared

1296
00:55:03,886 --> 00:55:06,616
in code our own UI views.

1297
00:55:06,616 --> 00:55:09,776
We've had UI view controllers,
map main ViewController,

1298
00:55:09,776 --> 00:55:11,916
flip side ViewController,
ViewController.

1299
00:55:12,096 --> 00:55:14,436
But we've not declared
our own UI views.

1300
00:55:14,436 --> 00:55:16,486
To date, where of our
UI views come from?

1301
00:55:16,976 --> 00:55:19,846
Often the nib file.

1302
00:55:19,846 --> 00:55:21,016
By dragging and dropping.

1303
00:55:21,016 --> 00:55:23,776
And in our no nib example,
a couple of weeks ago,

1304
00:55:23,776 --> 00:55:27,636
we did instantiate UI
view objects ourselves

1305
00:55:27,636 --> 00:55:28,726
in code manually.

1306
00:55:28,886 --> 00:55:31,086
But even those were
Apple's own UI views.

1307
00:55:31,086 --> 00:55:32,806
UI button and the UI text field.

1308
00:55:33,026 --> 00:55:35,986
So this is the first time where
we are defining our own view.

1309
00:55:36,186 --> 00:55:40,366
Because Apple iOS doesn't come
with a white rectangular paddle.

1310
00:55:40,366 --> 00:55:42,356
So we have to create
that somehow ourselves.

1311
00:55:42,696 --> 00:55:44,266
So the means by which
we've done this

1312
00:55:44,266 --> 00:55:50,456
in the .m file is fairly simply
by taking advantage of a method

1313
00:55:50,746 --> 00:55:52,356
that is called automatically,

1314
00:55:52,406 --> 00:55:56,246
whenever a UI view
object is instantiated.

1315
00:55:56,716 --> 00:56:00,386
This is essentially an
analog of like viewDidLoad.

1316
00:56:00,386 --> 00:56:02,276
But that's at the UI
ViewController level.

1317
00:56:02,476 --> 00:56:04,646
Now we're at a lower level
at the UI view level.

1318
00:56:04,646 --> 00:56:08,306
So draw rect for draw rectangle
is what's called when it's time

1319
00:56:08,306 --> 00:56:11,096
to initialize one of
those little widgets

1320
00:56:11,096 --> 00:56:12,986
that we've thus far been
dragging and dropping.

1321
00:56:13,406 --> 00:56:15,866
So here again, we're
commingling some C code

1322
00:56:15,866 --> 00:56:19,426
and some objective
C. CGRect is the name

1323
00:56:19,556 --> 00:56:22,466
of a core graphics
rectangle, which is a C struck.

1324
00:56:22,726 --> 00:56:24,056
A container with just data.

1325
00:56:24,196 --> 00:56:24,846
No methods.

1326
00:56:24,846 --> 00:56:26,526
I'm going to call this square.

1327
00:56:26,526 --> 00:56:28,946
And on the right hand side
we have a function called

1328
00:56:28,946 --> 00:56:32,586
CGRectMake which just
returns a C structure.

1329
00:56:32,586 --> 00:56:34,476
So a container with
a few fields.

1330
00:56:34,786 --> 00:56:38,446
And those fields are
apparently four in number.

1331
00:56:38,446 --> 00:56:40,396
The first two are going
to be initialized as 0.

1332
00:56:40,726 --> 00:56:41,926
Third is 10.0.

1333
00:56:41,926 --> 00:56:43,496
And the last is 60.0.

1334
00:56:43,766 --> 00:56:48,696
Any guesses as to what those
numbers are referring to?

1335
00:56:48,696 --> 00:56:51,146
Close. Not color, in this case.

1336
00:56:51,186 --> 00:56:52,406
But dimensions.

1337
00:56:52,406 --> 00:56:57,336
And one other detail the XY the
initial placement of this thing.

1338
00:56:57,336 --> 00:57:00,036
So, 0 comma 0 is just implying

1339
00:57:00,036 --> 00:57:01,316
that it's not going
to be offset at all.

1340
00:57:01,316 --> 00:57:02,626
It's just going to
be in the top corner

1341
00:57:02,626 --> 00:57:04,406
of whatever rectangle
we're creating.

1342
00:57:04,406 --> 00:57:06,216
The width is going
to be ten points.

1343
00:57:06,216 --> 00:57:09,306
And the height of it is
going to be 60 points.

1344
00:57:09,306 --> 00:57:09,986
All right?

1345
00:57:09,986 --> 00:57:10,986
But that's not enough.

1346
00:57:10,986 --> 00:57:12,626
Now we've just created
essentially a

1347
00:57:12,626 --> 00:57:13,666
rectangular widget.

1348
00:57:13,916 --> 00:57:17,236
Something that could be if Apple
really liked our paddle, dragged

1349
00:57:17,236 --> 00:57:19,206
and dropped in some future
version of X code, right?

1350
00:57:19,206 --> 00:57:20,666
That's really all
we've done here.

1351
00:57:20,706 --> 00:57:21,956
But there's more
complexity certainly

1352
00:57:21,956 --> 00:57:23,316
for something like
the UI button.

1353
00:57:23,806 --> 00:57:25,166
But now let's see
how we use this.

1354
00:57:25,666 --> 00:57:27,416
In my ViewController.nib,

1355
00:57:27,726 --> 00:57:31,206
notice I've done nothing
except change the orientation.

1356
00:57:31,376 --> 00:57:32,916
So if I actually click
on that thing and go

1357
00:57:32,916 --> 00:57:35,836
to the attributes inspector,
one of those various check boxes

1358
00:57:35,836 --> 00:57:37,186
and drop down menus
would let me change

1359
00:57:37,186 --> 00:57:39,446
from portrait to landscape mode.

1360
00:57:39,446 --> 00:57:41,306
And that's the only
change I made in addition

1361
00:57:41,306 --> 00:57:43,306
to then changing
the background color

1362
00:57:43,306 --> 00:57:45,106
from that default
of gray to black.

1363
00:57:45,376 --> 00:57:47,426
So this is going to be my
game board, so to speak.

1364
00:57:47,826 --> 00:57:50,016
But if I now go to
ViewController.h,

1365
00:57:50,246 --> 00:57:51,606
nothing interesting in there.

1366
00:57:52,226 --> 00:57:55,516
So the remaining
magic must be in here.

1367
00:57:55,876 --> 00:57:58,396
So notice inside of
my ViewController,

1368
00:57:58,616 --> 00:58:01,606
I'm declaring a property
that's of type paddle view.

1369
00:58:01,606 --> 00:58:03,816
Which is my own class
that I created.

1370
00:58:04,096 --> 00:58:05,416
And it's going to be
called PaddleView.

1371
00:58:05,416 --> 00:58:08,886
Lower case P, capital V.
Now let's take one step

1372
00:58:08,886 --> 00:58:09,626
back quickly.

1373
00:58:09,626 --> 00:58:12,326
Where did PaddleView.h
and .m come from?

1374
00:58:12,706 --> 00:58:14,046
Well, we haven't
done this that often.

1375
00:58:14,046 --> 00:58:16,006
And we did do it earlier
with the strings file.

1376
00:58:16,186 --> 00:58:19,316
Earlier when creating
this, I went to new, file,

1377
00:58:19,316 --> 00:58:23,186
and then I just went up
to [inaudible] touch.

1378
00:58:23,746 --> 00:58:25,816
And started with an
objective C class.

1379
00:58:26,246 --> 00:58:27,246
Went to new.

1380
00:58:27,436 --> 00:58:31,156
The class name I gave
it was PaddleView.

1381
00:58:31,156 --> 00:58:33,426
And I didn't have to
send it from NS object.

1382
00:58:33,426 --> 00:58:35,426
I had it to send from UI view.

1383
00:58:35,666 --> 00:58:38,486
When I hit enter earlier, I
got those two files for free.

1384
00:58:38,486 --> 00:58:40,246
And that's when I
dove in and then began

1385
00:58:40,246 --> 00:58:41,866
to implement DrawRect.

1386
00:58:42,476 --> 00:58:45,496
All right, so now, in this
file, we have a few methods.

1387
00:58:45,626 --> 00:58:47,066
In initWithNibName.

1388
00:58:47,366 --> 00:58:49,246
And this looks pretty
familiar except

1389
00:58:49,246 --> 00:58:51,186
for some new core graphics code.

1390
00:58:51,386 --> 00:58:53,676
So in initWithNibName is
again what's called as soon

1391
00:58:53,676 --> 00:58:55,266
as the nib is loaded from disk.

1392
00:58:55,266 --> 00:58:57,566
But that nib by default
is just rotated

1393
00:58:57,566 --> 00:58:59,676
in landscape mode
and painted black.

1394
00:58:59,986 --> 00:59:01,746
Now I want to do one
other thing to it.

1395
00:59:02,056 --> 00:59:05,026
Self.PaddleView, means
assign to my property what?

1396
00:59:05,256 --> 00:59:07,506
The result of allocating
a PaddleView object

1397
00:59:07,996 --> 00:59:09,936
and initializing
it with a frame.

1398
00:59:10,426 --> 00:59:12,916
So here there's a
bit of a dichotomy.

1399
00:59:12,916 --> 00:59:16,826
Now I am initializing
this PaddleView object

1400
00:59:17,186 --> 00:59:18,426
to be inside of a canvas.

1401
00:59:18,876 --> 00:59:20,926
So whereas before, if you're
familiar with Photoshop,

1402
00:59:20,926 --> 00:59:22,216
I created like an image.

1403
00:59:22,466 --> 00:59:25,306
Now I'm creating the canvas
on which to place that image.

1404
00:59:25,646 --> 00:59:29,266
So, the image can be
offset in the canvas itself.

1405
00:59:29,266 --> 00:59:30,326
The canvas can be bigger.

1406
00:59:30,546 --> 00:59:34,706
And in this case, the canvas is
going to have this image view,

1407
00:59:34,706 --> 00:59:37,736
this PaddleView placed on
it ten pixels to the right.

1408
00:59:38,246 --> 00:59:39,566
Ten pixels down.

1409
00:59:39,846 --> 00:59:43,256
And then the width of this
over lay is going to be

1410
00:59:43,256 --> 00:59:45,316
as we'd expect, ten
pick else sorry,

1411
00:59:45,316 --> 00:59:49,716
not pixels points wide
and 60 points tall.

1412
00:59:50,126 --> 00:59:51,946
So what does that
mean in real terms?

1413
00:59:51,946 --> 00:59:54,236
This is why when we start
this thing let me quit

1414
00:59:54,236 --> 00:59:55,056
this simulator.

1415
00:59:55,626 --> 00:59:57,636
So if [inaudible] familiar,
we can double tap there.

1416
00:59:57,636 --> 00:59:58,416
Click it how old.

1417
00:59:58,656 --> 00:59:59,426
Quit paddle.

1418
01:00:00,376 --> 01:00:01,396
Or you can just click stop.

1419
01:00:01,396 --> 01:00:03,756
And then you can hit run
again to rerun this thing.

1420
01:00:04,056 --> 01:00:06,596
Notice that it starts in
the top left hand corner.

1421
01:00:06,826 --> 01:00:10,076
But the projector is kind
of the contrast isn't great.

1422
01:00:10,706 --> 01:00:13,146
Take my word for it that
that paddle is not truly

1423
01:00:13,146 --> 01:00:15,326
in the top left hand
corner of the iPhone.

1424
01:00:15,326 --> 01:00:17,886
It's instead ten pixels
down, ten pixels over.

1425
01:00:18,116 --> 01:00:20,576
So in itself is with
respect to itself

1426
01:00:20,576 --> 01:00:22,176
in its own top left hand corner.

1427
01:00:22,176 --> 01:00:24,936
But that's just because the
image itself was only ten by 60.

1428
01:00:24,936 --> 01:00:26,626
Now we're painting
it on the canvas

1429
01:00:26,866 --> 01:00:29,636
by offsetting at ten by ten.

1430
01:00:29,636 --> 01:00:32,646
And why? I just thought it
looked marginally prettier

1431
01:00:32,646 --> 01:00:34,896
to offset it slightly from
the edge of the phone.

1432
01:00:35,026 --> 01:00:36,076
No other reason.

1433
01:00:36,446 --> 01:00:39,796
All right, so if we now go
back into the ViewController.m,

1434
01:00:40,086 --> 01:00:41,446
what more is happening here?

1435
01:00:42,196 --> 01:00:43,966
This line of code, addSubview.

1436
01:00:43,966 --> 01:00:45,256
We've not done this before.

1437
01:00:45,256 --> 01:00:48,866
But we've kind of felt
the results of the line

1438
01:00:48,866 --> 01:00:50,036
of code like this before.

1439
01:00:50,036 --> 01:00:52,516
So thus far when we've dragged
and dropped things like buttons

1440
01:00:52,516 --> 01:00:55,126
and text fields and sliders
from that little menu

1441
01:00:55,126 --> 01:00:56,836
and interface builder
and dropped it,

1442
01:00:57,036 --> 01:00:59,846
we've been adding a
view on top of another.

1443
01:01:00,016 --> 01:01:01,386
In other words, adding
a sub view.

1444
01:01:01,716 --> 01:01:04,116
This is the corresponding
line of code to dragging

1445
01:01:04,116 --> 01:01:05,696
and dropping in that interface.

1446
01:01:05,696 --> 01:01:08,006
I'm taking my paddle
and laying it on top

1447
01:01:08,006 --> 01:01:09,896
of the game board itself.

1448
01:01:10,006 --> 01:01:14,566
Which is just that big black
rectangle by the default.

1449
01:01:14,566 --> 01:01:18,366
Okay. So now, turns out, making
this super simple and kind

1450
01:01:18,366 --> 01:01:20,266
of pointless game is as simple

1451
01:01:20,266 --> 01:01:23,486
as implementing the
touchesMoved method.

1452
01:01:23,816 --> 01:01:26,296
So the touchesMoved method
is a little different

1453
01:01:26,296 --> 01:01:28,486
from the pan gesture
of recognizer

1454
01:01:28,486 --> 01:01:29,706
that we implemented earlier.

1455
01:01:29,996 --> 01:01:32,866
TouchesMoved actually allows
you to dissect all sorts

1456
01:01:32,866 --> 01:01:33,986
of touches on the screen.

1457
01:01:33,986 --> 01:01:37,366
Multiple fingers, touches
on different locations.

1458
01:01:37,526 --> 01:01:40,396
And it turns out, this actually
makes it even easier to respond

1459
01:01:40,396 --> 01:01:41,886
to those key presses that
we could have done this

1460
01:01:41,886 --> 01:01:42,686
in different ways.

1461
01:01:43,076 --> 01:01:44,556
So touchesMoved is going

1462
01:01:44,556 --> 01:01:48,446
to be fired anytime a UI view
is touched on the screen.

1463
01:01:48,706 --> 01:01:51,006
And what's going to
happen here is this.

1464
01:01:51,006 --> 01:01:53,266
When this method,
touchesMoved is called,

1465
01:01:53,266 --> 01:01:55,566
actually the method is called
touchesMoved with event.

1466
01:01:56,086 --> 01:01:59,456
I first ask the event
that I've been passed

1467
01:01:59,456 --> 01:02:02,686
as my second argument,
give me all of the touches

1468
01:02:03,136 --> 01:02:05,346
and then give me any object.

1469
01:02:05,656 --> 01:02:09,136
This essentially gives me in
this case, the only object

1470
01:02:09,136 --> 01:02:10,216
that could have been touched.

1471
01:02:10,216 --> 01:02:12,626
If there had been a whole lot
of things on top of one another,

1472
01:02:12,826 --> 01:02:15,036
it's possible that multiple
things would have been touched

1473
01:02:15,036 --> 01:02:18,006
because of the various
Z axis, so to speak.

1474
01:02:18,286 --> 01:02:20,256
But in this case, there's
only one paddle on the screen.

1475
01:02:20,256 --> 01:02:23,206
So I only care to get
whatever is in that set.

1476
01:02:23,206 --> 01:02:25,046
So any object will do.

1477
01:02:25,506 --> 01:02:30,056
I then with this line of
code ask it for its location.

1478
01:02:30,056 --> 01:02:32,316
What are its XY coordinates
essentially.

1479
01:02:32,466 --> 01:02:34,736
And I store those in
something called a CGPoint.

1480
01:02:34,766 --> 01:02:38,436
A CGPoint is just a
[inaudible] X comma Y. So where

1481
01:02:38,436 --> 01:02:41,126
on the screen was
that figure touched?

1482
01:02:41,546 --> 01:02:42,736
Now, what do I want to do?

1483
01:02:43,126 --> 01:02:46,136
So, I don't care where the
user's finger is along the

1484
01:02:46,136 --> 01:02:46,926
X axis.

1485
01:02:46,926 --> 01:02:49,126
I only care where
its on the Y axis.

1486
01:02:49,126 --> 01:02:51,206
So I don't care if the user
goes up, down over here

1487
01:02:51,356 --> 01:02:52,606
or goes up, down over here.

1488
01:02:52,766 --> 01:02:53,976
He or she is is only
going to be able

1489
01:02:53,976 --> 01:02:56,176
to move the paddle
along some fixed axis.

1490
01:02:56,686 --> 01:02:57,466
So which value?

1491
01:02:57,466 --> 01:02:59,706
Dot X or dot Y is of
interest to me here?

1492
01:03:03,956 --> 01:03:09,406
The location dot Y. So, if
I want to center the paddle,

1493
01:03:09,406 --> 01:03:10,556
notice what I'm doing here,

1494
01:03:10,556 --> 01:03:14,206
turns out that center
is a property associated

1495
01:03:14,206 --> 01:03:16,276
with the PaddleView
or more generally,

1496
01:03:16,276 --> 01:03:18,036
any UI view has a center.

1497
01:03:18,276 --> 01:03:21,266
And I need to assign it
in X comma Y coordinate.

1498
01:03:21,756 --> 01:03:24,066
I'm actually not
going to bother.

1499
01:03:24,586 --> 01:03:27,316
I'm actually going to
change its Y location.

1500
01:03:27,596 --> 01:03:30,236
But I'm not going to
change its X location.

1501
01:03:30,426 --> 01:03:33,916
Because I don't want the paddle
to start moving along the X axis

1502
01:03:33,916 --> 01:03:35,066
in this landscape mode.

1503
01:03:35,246 --> 01:03:37,076
I only want to update
the Y axis.

1504
01:03:37,596 --> 01:03:40,986
What I need to assign its
center in X comma Y coordinate.

1505
01:03:41,326 --> 01:03:43,506
So I have to actually
give it a point,

1506
01:03:43,606 --> 01:03:46,546
a CG point make gives
me that [inaudible].

1507
01:03:46,546 --> 01:03:47,806
Gives me an XY pair.

1508
01:03:48,936 --> 01:03:52,646
So, in the end, we get this very
simple, kind of pointless game,

1509
01:03:52,896 --> 01:03:56,486
where the thing follows my mouse
or my finger perfectly no matter

1510
01:03:56,486 --> 01:04:00,016
where on the screen my mouse
is without actually responding

1511
01:04:00,016 --> 01:04:02,796
to the lateral movements.

1512
01:04:02,876 --> 01:04:02,966
Yes?

1513
01:04:03,516 --> 01:04:11,306
[ Background Discussion ]

1514
01:04:11,806 --> 01:04:12,526
Absolutely.

1515
01:04:12,526 --> 01:04:15,676
We could constrain the touch
to only work, for instance,

1516
01:04:15,676 --> 01:04:17,206
if actually touching
the white box.

1517
01:04:17,496 --> 01:04:21,536
By actually looking at the X
coordinate and the Y coordinate

1518
01:04:21,536 --> 01:04:23,416
and saying, are you
within some sort of bounds,

1519
01:04:23,416 --> 01:04:25,796
if so, move, if not, ignore.

1520
01:04:26,066 --> 01:04:26,736
Absolutely.

1521
01:04:27,126 --> 01:04:29,316
And we can kind of
change the functionality

1522
01:04:29,316 --> 01:04:32,806
of this thing altogether if I
instead change this line here

1523
01:04:32,986 --> 01:04:34,926
from the same X that
it currently is

1524
01:04:34,926 --> 01:04:37,406
to Location.x. What's
going to happen

1525
01:04:37,406 --> 01:04:38,686
if I now run this version?

1526
01:04:39,356 --> 01:04:42,806
Should follow my finger, or in
this case, the mouse pointer.

1527
01:04:43,346 --> 01:04:44,876
If we go to the simulator here.

1528
01:04:45,536 --> 01:04:53,206
Put this up and this is
kind of a stupider game now.

1529
01:04:53,456 --> 01:04:55,086
Well, actually, you might
have an advantage now,

1530
01:04:55,086 --> 01:04:55,756
if playing pong.

1531
01:04:56,306 --> 01:04:57,606
So, all right.

1532
01:04:57,646 --> 01:04:59,376
So what remains to
be implemented?

1533
01:04:59,576 --> 01:05:01,286
You saw pong a moment ago.

1534
01:05:01,286 --> 01:05:03,086
And you might've
played pong years ago.

1535
01:05:03,276 --> 01:05:04,636
So, we've got the
beginnings of it.

1536
01:05:04,636 --> 01:05:06,436
We've got the users
half of the game.

1537
01:05:06,436 --> 01:05:08,596
What more do we need to do?

1538
01:05:08,986 --> 01:05:13,266
Yes? Yes, so we need
to implement some kind

1539
01:05:13,266 --> 01:05:16,206
of little white ball that's
going to bounce back and forth.

1540
01:05:16,536 --> 01:05:18,846
In fact, the bouncing
sounds kind of interesting.

1541
01:05:18,846 --> 01:05:20,346
Because if it hits
the top or the bottom,

1542
01:05:20,346 --> 01:05:23,406
we need to do some kind of
reflection, like on a pool table

1543
01:05:23,406 --> 01:05:24,626
or like from geometry.

1544
01:05:24,626 --> 01:05:25,856
So we have to think about that.

1545
01:05:26,116 --> 01:05:27,396
What else has to be implemented?

1546
01:05:27,986 --> 01:05:32,086
So the tally, we have
a big score at the top.

1547
01:05:32,086 --> 01:05:33,456
So maybe that's a UI label.

1548
01:05:33,456 --> 01:05:35,086
We can kind of cut some corners

1549
01:05:35,086 --> 01:05:36,566
and not do everything
in graphics.

1550
01:05:36,566 --> 01:05:39,396
We can actually just use a font
and actually update two labels

1551
01:05:39,396 --> 01:05:41,186
for the left guy's score
and the right guy's score.

1552
01:05:41,736 --> 01:05:43,816
It's collision detection
of what?

1553
01:05:44,516 --> 01:05:50,476
[ Background Discussion ]

1554
01:05:50,976 --> 01:05:51,846
Yes, exactly.

1555
01:05:51,846 --> 01:05:54,666
In addition to the top walls
from which we want some bouncing

1556
01:05:54,666 --> 01:05:57,086
to happen, the end walls mean
appoint has to be scored.

1557
01:05:57,086 --> 01:05:59,186
So we have to somehow detect
if you've gone too far left

1558
01:05:59,186 --> 01:05:59,996
or right with the ball.

1559
01:06:00,196 --> 01:06:01,816
And we have got to detect
if if you've hit the left

1560
01:06:01,886 --> 01:06:04,476
or the right paddle and
that ball have made contact.

1561
01:06:04,476 --> 01:06:06,676
So there's a lot
more to think about

1562
01:06:06,826 --> 01:06:09,576
but these are all probably
buildings blocks we can start

1563
01:06:09,576 --> 01:06:10,496
to piece together.

1564
01:06:10,496 --> 01:06:14,066
So let me go ahead and open
a final form of this and see

1565
01:06:14,066 --> 01:06:16,356
if we can pluck off
piece by piece.

1566
01:06:16,886 --> 01:06:21,526
And see what the origins
of each trick are.

1567
01:06:21,526 --> 01:06:24,726
So here is, I propose,
a working solution.

1568
01:06:24,816 --> 01:06:27,326
And even I kind of
cut a corner here.

1569
01:06:27,326 --> 01:06:28,806
Based on the files you see here,

1570
01:06:29,086 --> 01:06:30,906
what corners have
I cut thus far?

1571
01:06:32,026 --> 01:06:34,756
Really just in the interest
simplifying things we've already

1572
01:06:35,596 --> 01:06:38,026
looked at.

1573
01:06:38,276 --> 01:06:43,456
Yes? Yes, exactly.

1574
01:06:43,456 --> 01:06:45,276
I have a pong view,
which we'll see,

1575
01:06:45,276 --> 01:06:46,746
kind of manages the whole game.

1576
01:06:47,096 --> 01:06:49,166
But I don't have a
PaddleView anymore

1577
01:06:49,166 --> 01:06:52,306
or I don't have a ball view
because I realized along the way

1578
01:06:52,306 --> 01:06:54,276
that you know, it'd actually be
a lot easier to make a paddle

1579
01:06:54,276 --> 01:06:56,116
in Photoshop and a
ball in Photoshop

1580
01:06:56,116 --> 01:06:56,796
and just import [inaudible].

1581
01:06:56,796 --> 01:06:59,256
And so, I seem to have
done exactly that.

1582
01:06:59,256 --> 01:07:01,616
Paddle dot ping and ball
dot ping are are just going

1583
01:07:01,616 --> 01:07:02,436
to be graphics.

1584
01:07:02,676 --> 01:07:03,666
But that's enough.

1585
01:07:03,666 --> 01:07:05,636
I just can't put out
pings on the screen.

1586
01:07:05,636 --> 01:07:09,846
What object what class do I
have to wrap around these images

1587
01:07:10,086 --> 01:07:11,376
as we saw with Rob before?

1588
01:07:12,226 --> 01:07:14,656
So a UI image view.

1589
01:07:14,656 --> 01:07:16,856
So we're just using a
different UI image view rather

1590
01:07:16,856 --> 01:07:19,406
than making absolutely
everything from scratch.

1591
01:07:19,676 --> 01:07:22,006
So, we'll start as always
in the app delegates.

1592
01:07:22,006 --> 01:07:23,206
Nothing going on there.

1593
01:07:23,206 --> 01:07:27,496
AppDelegate.m, nothing new going
on there other than actually,

1594
01:07:27,956 --> 01:07:29,406
this is one good
thing to highlight.

1595
01:07:29,746 --> 01:07:32,166
We've used the AppDelegate
for terribly little other

1596
01:07:32,166 --> 01:07:33,716
than the built in functionality.

1597
01:07:34,286 --> 01:07:35,756
But what do I seem to be doing

1598
01:07:35,756 --> 01:07:38,656
with this application
will resign active?

1599
01:07:39,706 --> 01:07:41,516
A bit out of context
now, but take a guess.

1600
01:07:41,776 --> 01:07:43,606
What does this mean
and what am I doing

1601
01:07:43,606 --> 01:07:44,886
in response to it, do you think.

1602
01:07:45,516 --> 01:07:50,676
[ Background Noise ]

1603
01:07:51,176 --> 01:07:52,596
How about the first
question first.

1604
01:07:52,596 --> 01:07:54,206
When does this method,

1605
01:07:54,206 --> 01:07:56,936
applicationWillResignActive
likely get invoked?

1606
01:07:59,676 --> 01:08:02,166
When I what?

1607
01:08:03,256 --> 01:08:10,726
Close. Just the . Will resign.

1608
01:08:10,926 --> 01:08:16,716
Go ahead? So, it's not actually
orientation, it's instead

1609
01:08:16,716 --> 01:08:18,516
when the app is background.

1610
01:08:18,516 --> 01:08:21,396
So if I get a call and I take it
or if I push the home but done

1611
01:08:21,626 --> 01:08:23,556
and I resign active state.

1612
01:08:24,006 --> 01:08:27,816
Remember when we make key
made the key an active

1613
01:08:27,816 --> 01:08:28,536
window earlier?

1614
01:08:28,536 --> 01:08:30,006
This is the same idea.

1615
01:08:30,006 --> 01:08:31,346
The opposite of that.

1616
01:08:31,806 --> 01:08:33,726
So, what am I doing?

1617
01:08:33,726 --> 01:08:35,896
I'm apparently passing
a message called kickOff

1618
01:08:35,896 --> 01:08:37,446
to self.viewController.

1619
01:08:37,446 --> 01:08:39,836
And I only know this
intelligently in hindsight,

1620
01:08:40,066 --> 01:08:42,516
the first time I sat down to
implement something like this,

1621
01:08:42,676 --> 01:08:44,936
anytime I did get a call
or anytime any background

1622
01:08:44,936 --> 01:08:46,646
to the application
then came back

1623
01:08:46,646 --> 01:08:48,456
to the application,
I immediately lost.

1624
01:08:48,456 --> 01:08:50,296
Because I had no recollection
of where the ball was.

1625
01:08:50,296 --> 01:08:51,446
My brain wasn't quick enough

1626
01:08:51,606 --> 01:08:53,396
to actually move
the I tell my finger

1627
01:08:53,396 --> 01:08:54,976
to move the paddle
to catch the ball.

1628
01:08:55,086 --> 01:08:56,166
So then I've realized
wait a minute.

1629
01:08:56,166 --> 01:08:59,016
If the user has to effectively
pause the game to take a call

1630
01:08:59,016 --> 01:09:01,016
or respond to an SMS,
background and whatever,

1631
01:09:01,196 --> 01:09:03,126
it'd be a nice courtesy
to pause the game.

1632
01:09:03,366 --> 01:09:05,346
So kickOff does effectively
that.

1633
01:09:05,346 --> 01:09:08,096
It just moves the ball back
to the kickOff location.

1634
01:09:08,096 --> 01:09:10,076
The idea being I
figured, let's just start

1635
01:09:10,076 --> 01:09:12,006
from the let's not
reset the score.

1636
01:09:12,096 --> 01:09:14,426
Let's just reset the ball's
location to the middle.

1637
01:09:14,426 --> 01:09:17,056
Like you might have in a
soccer or football game.

1638
01:09:17,516 --> 01:09:17,926
All right.

1639
01:09:17,926 --> 01:09:19,846
So that's the only
difference there.

1640
01:09:20,086 --> 01:09:23,246
PongView.h doesn't seem to
have much going on here.

1641
01:09:23,826 --> 01:09:27,026
PongView.m looks like this.

1642
01:09:27,026 --> 01:09:31,366
Up too much, but a little
of this low level stuff.

1643
01:09:31,366 --> 01:09:33,026
And I thought I'd draw
something different.

1644
01:09:33,296 --> 01:09:34,786
Let me open up the game again.

1645
01:09:35,596 --> 01:09:39,096
And in the simulator there
was one other design element

1646
01:09:39,096 --> 01:09:39,716
on the screen.

1647
01:09:39,716 --> 01:09:40,796
Does anybody remember what?

1648
01:09:41,426 --> 01:09:46,026
[Inaudible] yes, the
dash line in the middle.

1649
01:09:46,026 --> 01:09:48,346
So this is surprisingly
non trivial to do.

1650
01:09:48,606 --> 01:09:50,936
And I didn't want to resort
to Photoshop for everything.

1651
01:09:50,936 --> 01:09:51,826
But I thought that
would kind of look

1652
01:09:51,826 --> 01:09:53,976
like a nice line
down the middle.

1653
01:09:53,976 --> 01:09:57,336
And we can draw this using core
graphics on top of my canvas.

1654
01:09:57,646 --> 01:10:01,026
So in this case, I first need to
get something called a context.

1655
01:10:01,026 --> 01:10:03,816
And the context you can kind
of think of as like the canvas.

1656
01:10:03,896 --> 01:10:05,486
The current context
for your graphics.

1657
01:10:05,836 --> 01:10:08,376
And now we have some
sort of weird use of C.

1658
01:10:08,376 --> 01:10:10,726
But in the end it's
fairly straight forward.

1659
01:10:10,966 --> 01:10:14,206
I'm first declaring a
variable called dashes.

1660
01:10:14,346 --> 01:10:15,486
That's of what data type?

1661
01:10:16,196 --> 01:10:21,086
It's sub type CGFloat,

1662
01:10:21,086 --> 01:10:24,396
but specifically it's
an array of CG floats.

1663
01:10:24,396 --> 01:10:25,056
Whatever that is.

1664
01:10:25,056 --> 01:10:26,076
Core graphics float.

1665
01:10:26,076 --> 01:10:28,586
So it's some representation
of floating point values

1666
01:10:28,586 --> 01:10:29,876
for this particular library.

1667
01:10:30,136 --> 01:10:33,366
One comma one is essentially
as we're going to see,

1668
01:10:33,546 --> 01:10:35,356
it's going to mean,
draw a little bit

1669
01:10:35,356 --> 01:10:37,066
of white then have blank space.

1670
01:10:37,106 --> 01:10:37,886
White blank.

1671
01:10:37,886 --> 01:10:38,526
White blank.

1672
01:10:38,526 --> 01:10:41,076
And that's how we get this sort
of zipper affect of the screen.

1673
01:10:41,546 --> 01:10:45,216
All right so,
CGContextSetLineDash.

1674
01:10:45,546 --> 01:10:49,826
So this function is essentially
saying, what's your canvas?

1675
01:10:50,046 --> 01:10:52,566
Dashes is what pattern
do you want to use?

1676
01:10:52,946 --> 01:10:54,996
And two just means how
big was that array?

1677
01:10:55,786 --> 01:10:58,446
Next line here, CG
set stroke color

1678
01:10:58,446 --> 01:11:00,236
with color what's your canvas?

1679
01:11:00,236 --> 01:11:01,896
What color do you
want me to draw in?

1680
01:11:02,076 --> 01:11:04,326
So in this case, this is a
bit of a commingling of C

1681
01:11:04,326 --> 01:11:06,526
and objective C.
UIColor's a class.

1682
01:11:06,586 --> 01:11:09,676
WhiteColor is a convenience
method or class method inside

1683
01:11:09,676 --> 01:11:11,396
of that class that
returns to you some

1684
01:11:11,396 --> 01:11:13,806
of objective C representation
of the color white.

1685
01:11:14,286 --> 01:11:19,966
.CG color converts
that NS UIColor object

1686
01:11:20,146 --> 01:11:24,076
to a C style struct for
the core graphics library.

1687
01:11:24,486 --> 01:11:25,916
Down here we set the line width

1688
01:11:25,916 --> 01:11:28,606
to be fairly arbitrarily
five points wide.

1689
01:11:28,946 --> 01:11:31,576
We move to the point,
240 comma 0.

1690
01:11:31,576 --> 01:11:33,746
So we're essentially going
to the middle of the screen.

1691
01:11:33,746 --> 01:11:37,736
If we assume 480
pixel, 480 points total.

1692
01:11:37,866 --> 01:11:39,616
AddLineToPoint, this is saying,

1693
01:11:39,616 --> 01:11:42,366
go from where you are all
the way up to the top.

1694
01:11:42,366 --> 01:11:44,446
So sort of draw that dash line.

1695
01:11:44,626 --> 01:11:47,306
And then lastly,
fill in the dots,

1696
01:11:47,526 --> 01:11:49,796
so paint along the
trail you just left.

1697
01:11:50,086 --> 01:11:52,426
So if you remember like a
language like a logo years ago.

1698
01:11:52,426 --> 01:11:54,116
The little turtle turning
up, down, left, right.

1699
01:11:54,116 --> 01:11:55,676
And drawing things
or leaving a trail?

1700
01:11:55,926 --> 01:11:58,796
It's the same kind of idea that
where you move a cursor around

1701
01:11:58,796 --> 01:12:01,566
and you tell it when to put
the marker down and draw.

1702
01:12:01,566 --> 01:12:03,536
When to let go and so forth.

1703
01:12:03,596 --> 01:12:06,006
We've essentially drawn
a dash line in that way.

1704
01:12:06,416 --> 01:12:09,866
And now the whole point, was
again, to over lay on top

1705
01:12:09,866 --> 01:12:12,256
of our view, this pong view.

1706
01:12:12,546 --> 01:12:14,966
So here we have
ViewController.h. We're almost

1707
01:12:14,966 --> 01:12:16,056
into the brains of the game.

1708
01:12:16,316 --> 01:12:19,986
ViewController.h apparently
declares one method

1709
01:12:19,986 --> 01:12:20,786
called kickOff.

1710
01:12:21,516 --> 01:12:23,646
Why did I put it in my .h file?

1711
01:12:23,646 --> 01:12:27,386
I feel like I'm regressing
to our previous techniques.

1712
01:12:27,826 --> 01:12:27,976
Yes?

1713
01:12:28,516 --> 01:12:32,496
[ Background Discussion ]

1714
01:12:32,996 --> 01:12:37,616
Exactly. In my ViewController,
rather in my AppDelegate.h,

1715
01:12:37,616 --> 01:12:41,486
recall that I called
AppDelegate.m recall

1716
01:12:41,486 --> 01:12:44,626
that I called the kickOff
method in this line here.

1717
01:12:44,776 --> 01:12:48,566
And that's why I imported the
ViewController.h. And that's why

1718
01:12:48,566 --> 01:12:50,376
in ViewController.h,

1719
01:12:50,496 --> 01:12:56,506
I'm actually declaring this
method publicly, so to speak,

1720
01:12:56,566 --> 01:12:59,286
in the .h file and not
in some nameless category

1721
01:12:59,586 --> 01:13:00,706
in the .m file.

1722
01:13:01,006 --> 01:13:01,586
All right?

1723
01:13:01,586 --> 01:13:03,786
So, the nib file
looks like this.

1724
01:13:03,906 --> 01:13:05,566
It's a little different
this time.

1725
01:13:05,736 --> 01:13:07,796
And then I've seem to
have laid out in advance,

1726
01:13:07,796 --> 01:13:09,736
a few different widgets,
so to speak.

1727
01:13:09,776 --> 01:13:11,326
What appears to be
on the screen here?

1728
01:13:11,946 --> 01:13:14,326
So some text.

1729
01:13:14,726 --> 01:13:17,116
So I con conjecture
this is a UI label.

1730
01:13:17,336 --> 01:13:18,566
That's another UI label

1731
01:13:18,566 --> 01:13:20,656
and I just put some default
text there even though the human

1732
01:13:20,656 --> 01:13:21,436
never sees it.

1733
01:13:22,126 --> 01:13:23,226
What else is on this screen?

1734
01:13:24,046 --> 01:13:26,916
Yes? Yes, so the image views.

1735
01:13:26,916 --> 01:13:27,716
So let's take a look.

1736
01:13:27,716 --> 01:13:29,816
If I first expand to
the hierarchy here,

1737
01:13:29,816 --> 01:13:32,106
I can see what I've laid
down on this canvas.

1738
01:13:32,106 --> 01:13:34,226
And indeed, there's
three image views

1739
01:13:34,226 --> 01:13:36,176
or UI image views,
the class name.

1740
01:13:36,446 --> 01:13:37,366
And to labels.

1741
01:13:37,656 --> 01:13:39,636
And if I actually
click on these things,

1742
01:13:39,636 --> 01:13:40,816
with we can see how
they're configured.

1743
01:13:40,816 --> 01:13:42,556
Let me click on the ball
in the middle there.

1744
01:13:42,756 --> 01:13:44,646
It's ten pixels by
ten pixels according

1745
01:13:44,646 --> 01:13:45,906
to what I made in Photoshop.

1746
01:13:46,146 --> 01:13:49,766
And it's in data UI image view
whose image source has been

1747
01:13:49,766 --> 01:13:51,706
specified to be that
ping in question.

1748
01:13:51,706 --> 01:13:54,406
Just like we did with
Rob [inaudible] earlier.

1749
01:13:54,406 --> 01:13:55,766
Same deal for the others.

1750
01:13:55,766 --> 01:13:57,296
And score left and score right,

1751
01:13:57,296 --> 01:14:00,386
if we go to the identity
inspector, is indeed a UI label.

1752
01:14:00,586 --> 01:14:02,216
So in this case,
what I literally did

1753
01:14:02,216 --> 01:14:06,036
in advance was I dragged and
dropped three UI image views

1754
01:14:06,036 --> 01:14:07,876
from the pallet of
options down there.

1755
01:14:08,086 --> 01:14:10,796
And I configure them, just
like I did with Rob earlier

1756
01:14:10,916 --> 01:14:13,466
to be ball.ping or paddle.ping.

1757
01:14:13,796 --> 01:14:14,756
So as to lay that out.

1758
01:14:15,026 --> 01:14:17,016
And then the scores I
just manually typed.

1759
01:14:17,546 --> 01:14:19,636
Previously, they
just said label.

1760
01:14:19,676 --> 01:14:21,026
And they could still say label.

1761
01:14:21,026 --> 01:14:22,456
I just thought it was a
little more instructive

1762
01:14:22,456 --> 01:14:24,636
to give them left and
right names, that's all.

1763
01:14:24,636 --> 01:14:25,806
All right.

1764
01:14:26,186 --> 01:14:28,176
So now if we go to
ViewController.m,

1765
01:14:28,476 --> 01:14:30,536
here is where all the
interesting stuff must

1766
01:14:30,536 --> 01:14:31,186
be happening.

1767
01:14:31,526 --> 01:14:34,806
So first, I decided just to make
it easy to tinker with my game,

1768
01:14:35,186 --> 01:14:38,756
to declare a velocity,
constant at the top of the file.

1769
01:14:38,956 --> 01:14:43,396
Initialized to 10.0 in
a floating point value.

1770
01:14:43,396 --> 01:14:45,626
So this is like the speed,
ten pounds per second.

1771
01:14:45,626 --> 01:14:46,766
And or some unit of time.

1772
01:14:47,256 --> 01:14:48,506
And then I have inside

1773
01:14:48,506 --> 01:14:51,896
of my nameless category,
a CG point velocity.

1774
01:14:51,896 --> 01:14:54,116
So, somewhere in this
class, I need to keep track

1775
01:14:54,116 --> 01:14:55,636
of what is my current velocity.

1776
01:14:55,856 --> 01:14:59,836
Because a velocity recall was
essentially a vector telling me

1777
01:14:59,836 --> 01:15:00,936
how fast to go.

1778
01:15:00,936 --> 01:15:04,506
Up to straight up or to the
right or the opposite thereof.

1779
01:15:04,506 --> 01:15:07,536
So it's some kind of speed,
a change in rate, DYDX.

1780
01:15:07,536 --> 01:15:12,236
So I need to store my current
one so I know at every second

1781
01:15:12,236 --> 01:15:15,016
of the game how fast
should the ball be moving.

1782
01:15:15,396 --> 01:15:18,006
Now I have a whole bunch
of private properties here.

1783
01:15:18,006 --> 01:15:19,286
But most of it is expected.

1784
01:15:19,286 --> 01:15:21,886
Then I've got IB
outlets for all three

1785
01:15:21,886 --> 01:15:24,326
of the UI image views
that we saw earlier.

1786
01:15:24,586 --> 01:15:27,656
And I've got two IB
outlets for the UI labels

1787
01:15:27,656 --> 01:15:28,776
that we dragged and dropped.

1788
01:15:29,096 --> 01:15:31,786
So that leaves a few
here, an NSU integer.

1789
01:15:32,016 --> 01:15:32,776
What might that mean?

1790
01:15:33,286 --> 01:15:37,526
Yes, so it's an unsigned
integer, why?

1791
01:15:37,526 --> 01:15:39,426
I figured the score never
needs to go negative.

1792
01:15:39,426 --> 01:15:42,466
So just to be proper, I'm going
to specify that it's an unsigned

1793
01:15:42,626 --> 01:15:44,246
that is non 0 integer.

1794
01:15:44,536 --> 01:15:47,586
I could have just done
little U, unsigned int.

1795
01:15:47,926 --> 01:15:50,766
But, just to be consistent
with iOS practices,

1796
01:15:50,766 --> 01:15:53,856
I gave it the NSU integer, which
is just the it's not a class,

1797
01:15:54,426 --> 01:15:58,216
it's just a type depth, it's
a synonym for unsigned int.

1798
01:15:58,216 --> 01:16:00,216
All right, I've got one for
the left and one for the right.

1799
01:16:00,216 --> 01:16:01,626
And [inaudible] for pause.

1800
01:16:01,626 --> 01:16:03,486
I needed some variable just
to keep track of whether

1801
01:16:03,486 --> 01:16:06,976
or not the game is paused and
when does it seem to pause based

1802
01:16:06,976 --> 01:16:08,406
on our tinkering earlier.

1803
01:16:08,916 --> 01:16:10,616
What's that?

1804
01:16:10,806 --> 01:16:15,786
When it's in the background
and also in the beginning,

1805
01:16:15,786 --> 01:16:16,946
when the ball is
just sitting there

1806
01:16:16,946 --> 01:16:19,276
in the middle before I actually
start interacting with the app

1807
01:16:19,276 --> 01:16:21,966
or conversely every time
there's a score made,

1808
01:16:22,096 --> 01:16:24,346
then the ball goes back to the
center and I have to touch it

1809
01:16:24,346 --> 01:16:25,576
for the game so resume.

1810
01:16:26,126 --> 01:16:28,026
All right, so now, in
the ViewController,

1811
01:16:28,216 --> 01:16:30,496
some of this is a lot of
this is now just logic.

1812
01:16:30,496 --> 01:16:34,016
So, after initializing the
object with the nib name,

1813
01:16:34,296 --> 01:16:37,036
I'm initializing the
score left and right to 0.

1814
01:16:37,406 --> 01:16:39,326
I'm first declaring a velocity.

1815
01:16:39,326 --> 01:16:41,516
So a velocity has
to do with motion.

1816
01:16:41,726 --> 01:16:43,316
And you can represent
it with a point.

1817
01:16:43,546 --> 01:16:46,676
If a point is just X comma
Y, you can just treat the X

1818
01:16:46,756 --> 01:16:50,406
as delta X and the Y as delta
Y. Change in X, change in Y.

1819
01:16:50,696 --> 01:16:53,866
So I just used them now
familiar CG point make velocity

1820
01:16:53,866 --> 01:16:54,776
comma velocity.

1821
01:16:54,776 --> 01:16:57,706
And this just means
if it's 10.0,

1822
01:16:57,806 --> 01:16:59,956
what did we say it was
earlier, the constant.

1823
01:17:00,276 --> 01:17:02,936
10.0 this just means that
for every unit of time,

1824
01:17:02,936 --> 01:17:05,186
move ten points this
way, ten points that way,

1825
01:17:05,186 --> 01:17:07,746
effectively going on
a straight diagonal.

1826
01:17:08,196 --> 01:17:11,296
All right, so what happens
next in this initializer?

1827
01:17:11,736 --> 01:17:14,626
This is how the game
actually has motion.

1828
01:17:15,156 --> 01:17:17,576
So we declared what's
called an NS timer.

1829
01:17:17,886 --> 01:17:21,016
We schedule it with a
time interval of .05.

1830
01:17:21,466 --> 01:17:24,356
So every five hundredth of
a second I want something

1831
01:17:24,356 --> 01:17:26,916
to happen and I just decided
on that by trial and error

1832
01:17:26,916 --> 01:17:27,976
to see what would feel right.

1833
01:17:28,346 --> 01:17:30,756
Targeting myself with
a selector of play.

1834
01:17:30,886 --> 01:17:32,466
So apparently, I
want what method

1835
01:17:32,466 --> 01:17:35,206
to get called every .05 seconds?

1836
01:17:36,056 --> 01:17:37,716
The play method, all right?

1837
01:17:37,716 --> 01:17:40,646
And beyond that and it
repeats, in that, if you recall

1838
01:17:40,646 --> 01:17:42,916
from Java Script,
they're set interval

1839
01:17:42,916 --> 01:17:43,916
and they're set time out.

1840
01:17:43,976 --> 01:17:46,506
This is like set interval,
given that I'm passing

1841
01:17:46,506 --> 01:17:48,606
in repeat, a value of yes.

1842
01:17:49,066 --> 01:17:51,246
So now, what happens next?

1843
01:17:51,246 --> 01:17:53,796
Nothing seems to happen thereby
default, let me scroll down,

1844
01:17:53,996 --> 01:17:55,196
there's a play method.

1845
01:17:55,196 --> 01:17:57,256
A lot of math there,
touchesMoved.

1846
01:17:57,426 --> 01:17:58,736
So touchesBegan.

1847
01:17:59,176 --> 01:18:03,596
So it looks like what I'm doing
here is when there's a touch

1848
01:18:03,596 --> 01:18:08,486
on the screen, I am changing
the value of paused to no.

1849
01:18:08,706 --> 01:18:10,756
So this is my main way of
kick starting the game.

1850
01:18:10,756 --> 01:18:12,696
As soon as touches begin on
the screen, doesn't matter

1851
01:18:12,696 --> 01:18:15,266
where the human touches,
that means kick the ball.

1852
01:18:15,266 --> 01:18:16,916
Let's start the game
of pong playing.

1853
01:18:17,096 --> 01:18:18,666
And I change that
[inaudible] field.

1854
01:18:18,996 --> 01:18:22,816
So presumably, my play method
is going to check that value.

1855
01:18:22,816 --> 01:18:24,146
So let's go into play here.

1856
01:18:24,146 --> 01:18:27,516
And indeed, if the game is
paused, just return immediately.

1857
01:18:27,596 --> 01:18:28,986
Don't play anything.

1858
01:18:28,986 --> 01:18:32,206
Don't move any mouse movements
or cursor movements or ball

1859
01:18:32,206 --> 01:18:35,506
or paddle movements
otherwise move the ball.

1860
01:18:35,686 --> 01:18:38,056
So this is very similar
behavior to before.

1861
01:18:38,056 --> 01:18:40,266
Even though this is being called
on a timer not in response

1862
01:18:40,266 --> 01:18:45,616
to user action, what do I
want to do every unit of time?

1863
01:18:45,766 --> 01:18:47,046
I want to move the ball how?

1864
01:18:47,176 --> 01:18:50,296
Using its velocity.

1865
01:18:50,296 --> 01:18:54,486
So if its velocity is ten comma
ten, every time the clock fires,

1866
01:18:54,746 --> 01:18:56,906
I want to move it
over ten and up ten,

1867
01:18:57,076 --> 01:18:58,486
if that's its current velocity.

1868
01:18:58,706 --> 01:18:59,536
And that's what I'm doing.

1869
01:18:59,536 --> 01:19:00,636
I'm making a new point.

1870
01:19:00,716 --> 01:19:02,606
Taking the ball's
current X location,

1871
01:19:02,656 --> 01:19:04,416
adding the velocity's X values.

1872
01:19:04,786 --> 01:19:07,436
Then comma, the ball's
current Y location.

1873
01:19:07,436 --> 01:19:10,236
And adding the velocity's
Y value.

1874
01:19:10,686 --> 01:19:13,466
But now I have to somehow detect
when the ball's in the goals

1875
01:19:13,466 --> 01:19:14,886
as was proposed earlier.

1876
01:19:15,476 --> 01:19:18,046
So, what is this
line of code saying?

1877
01:19:18,886 --> 01:19:21,426
If self.ball.center.x
less than 5,

1878
01:19:21,456 --> 01:19:23,846
what's the implication
of that logic play?

1879
01:19:24,516 --> 01:19:35,246
[ Background Discussion ]

1880
01:19:35,746 --> 01:19:40,546
Exactly. So recall that 0 comma
0 is the top left hand corner.

1881
01:19:40,756 --> 01:19:44,106
So if the ball goes
within five pixels of 0,

1882
01:19:44,296 --> 01:19:46,836
it's really all the way over
to the left at which point,

1883
01:19:46,836 --> 01:19:48,216
I'm just going to
say that's the goal.

1884
01:19:48,216 --> 01:19:49,986
It went over the boundary.

1885
01:19:50,256 --> 01:19:51,616
So who should get the score?

1886
01:19:52,756 --> 01:19:53,626
The guy on the right.

1887
01:19:53,626 --> 01:19:55,406
So score right should
be plus plus.

1888
01:19:55,406 --> 01:19:57,806
Because he's the one who would
have kicked it into that end.

1889
01:19:58,116 --> 01:20:00,366
And then I called self kickOff.

1890
01:20:00,366 --> 01:20:01,586
Well, what does kickOff do?

1891
01:20:01,586 --> 01:20:04,716
Let's come back to this function
this method in just a moment.

1892
01:20:04,986 --> 01:20:06,076
KickOff does a few things.

1893
01:20:06,076 --> 01:20:07,686
It pauses the game, apparently.

1894
01:20:07,976 --> 01:20:13,936
It then updates the scores based
on what's in the NSU integer.

1895
01:20:14,066 --> 01:20:16,096
So the unsign integers
are numbers.

1896
01:20:16,286 --> 01:20:19,366
But I want to turn them into
strings so that I can paint them

1897
01:20:19,366 --> 01:20:21,216
on the screen in
terms of those labels.

1898
01:20:21,216 --> 01:20:23,896
So that's using some building
blocks from a few weeks ago.

1899
01:20:24,306 --> 01:20:25,886
Now I want to center the ball.

1900
01:20:25,886 --> 01:20:28,026
And I'm going to go
ahead and center this

1901
01:20:28,026 --> 01:20:30,466
at that particular
location here.

1902
01:20:30,466 --> 01:20:32,436
And then I'm going to go
ahead and align the paddles,

1903
01:20:32,436 --> 01:20:33,896
which is just a bit
of trial and error.

1904
01:20:33,896 --> 01:20:36,516
Figuring out exactly what
made sense on the screen.

1905
01:20:36,856 --> 01:20:40,296
And now if I scroll back to
play, what happens otherwise

1906
01:20:40,296 --> 01:20:43,176
if there's no goal on
the left or on the right?

1907
01:20:43,176 --> 01:20:45,456
Well, bouncing is kind
of an interesting thing.

1908
01:20:45,836 --> 01:20:48,936
So what is this, if
condition, handling?

1909
01:20:49,416 --> 01:20:53,886
The highlighted lines
are doing what and how?

1910
01:20:53,886 --> 01:20:53,976
Yes?

1911
01:20:54,516 --> 01:21:00,986
[ Background Discussion ]

1912
01:21:01,486 --> 01:21:02,116
Okay, good.

1913
01:21:02,116 --> 01:21:03,436
So as the comment
says, this has to do

1914
01:21:03,436 --> 01:21:05,336
with bouncing off the
top and bottom, but how?

1915
01:21:05,586 --> 01:21:09,776
Well, if the Y coordinate of the
ball center is less than five,

1916
01:21:09,836 --> 01:21:11,776
that means it's really
close to the top.

1917
01:21:12,026 --> 01:21:15,676
And if its velocity at
that point is some value,

1918
01:21:15,826 --> 01:21:17,946
how do you make it
stop going upward?

1919
01:21:18,546 --> 01:21:22,056
Well, just change the
velocity to the negative.

1920
01:21:22,176 --> 01:21:24,156
So if we effectively
want to make right angles

1921
01:21:24,156 --> 01:21:26,786
when we hit the side of the
wall, it actually suffices.

1922
01:21:26,786 --> 01:21:29,046
If again, you think of
the motion as X component

1923
01:21:29,046 --> 01:21:31,656
and a Y component, if the
ball is going up this way,

1924
01:21:31,826 --> 01:21:33,296
you don't want to
change the X motion.

1925
01:21:33,296 --> 01:21:34,416
Like, you don't want
it to go this way,

1926
01:21:34,416 --> 01:21:35,996
because that would be
weird if the ball hit here

1927
01:21:35,996 --> 01:21:36,766
and then went this way.

1928
01:21:37,006 --> 01:21:39,466
You want the ball to go this
way and keep going to the right,

1929
01:21:39,726 --> 01:21:41,256
but you want it to
start coming down.

1930
01:21:41,256 --> 01:21:44,796
So all you have to do is flip
the Y from positive to negative

1931
01:21:44,796 --> 01:21:46,556
or conversely negative
to positive.

1932
01:21:46,556 --> 01:21:49,256
And that's exactly what we're
doing inside of this condition.

1933
01:21:49,256 --> 01:21:52,676
If we get within five pixels of
the top of that screen, go ahead

1934
01:21:52,676 --> 01:21:56,486
and flip the Y's
velocity as with

1935
01:21:56,486 --> 01:21:59,636
that negation there
in that line of code.

1936
01:21:59,856 --> 01:22:02,676
And the [inaudible] is
just handling the bottom

1937
01:22:02,676 --> 01:22:03,966
of the wall as well.

1938
01:22:03,966 --> 01:22:05,696
And the fact that I'm using
a negative sign here means

1939
01:22:05,696 --> 01:22:07,226
that it doesn't matter
if the ball is going up

1940
01:22:07,226 --> 01:22:08,856
and now would have come
down, or if it's going down,

1941
01:22:09,166 --> 01:22:10,366
now it's going to go up.

1942
01:22:10,716 --> 01:22:13,166
The left paddle is a
little more interesting.

1943
01:22:13,596 --> 01:22:16,196
And how are we apparently
detecting intersection?

1944
01:22:16,376 --> 01:22:18,186
Well it turns out in the
core graphics library,

1945
01:22:18,186 --> 01:22:21,356
there's a helper function
called CGRectIntersectsRect.

1946
01:22:21,586 --> 01:22:23,286
And you can pass
in two rectangles.

1947
01:22:23,286 --> 01:22:24,356
And it will return true

1948
01:22:24,356 --> 01:22:26,806
if they're overlapping,
which is perfect.

1949
01:22:26,806 --> 01:22:29,356
And this is why I didn't
quite make the ball a circle

1950
01:22:29,356 --> 01:22:30,616
and decided it'd be easier

1951
01:22:30,616 --> 01:22:32,356
to just make it a
ten by ten square.

1952
01:22:32,356 --> 01:22:34,426
So this way no matter
where it touches,

1953
01:22:34,616 --> 01:22:37,226
it's sort of geometrically
reasonable to assume

1954
01:22:37,226 --> 01:22:38,166
that it's going to bounce.

1955
01:22:38,526 --> 01:22:42,276
And so in this case, if the
frame intersects the frame

1956
01:22:42,276 --> 01:22:46,876
of the ball intersects the frame
of the paddle then, go ahead

1957
01:22:46,876 --> 01:22:52,046
and inverse the velocity, from
negative to positive or positive

1958
01:22:52,096 --> 01:22:55,326
to negative, depending on
which paddle you have just hit.

1959
01:22:55,456 --> 01:22:57,286
If you're on the left
or you're on the right.

1960
01:22:57,836 --> 01:22:57,966
Yes?

1961
01:22:58,516 --> 01:23:03,296
[ Background Discussion ]

1962
01:23:03,796 --> 01:23:07,156
If you increase the
velocity of the ball,

1963
01:23:07,416 --> 01:23:08,446
would you get a problem?

1964
01:23:08,446 --> 01:23:09,686
Define problem.

1965
01:23:10,516 --> 01:23:15,236
[ Background Discussion ]

1966
01:23:15,736 --> 01:23:17,206
Oh, good question.

1967
01:23:17,206 --> 01:23:19,836
Yes. So, potentially, I have
made certain assumptions

1968
01:23:20,106 --> 01:23:22,736
about the thickness of
the ball, the velocity

1969
01:23:22,736 --> 01:23:24,176
at which the ball is moving

1970
01:23:24,436 --> 01:23:27,426
and how frequently I'm
firing the clock timer.

1971
01:23:27,426 --> 01:23:31,246
I could absolutely come up with
values whereby the ball could be

1972
01:23:31,246 --> 01:23:32,976
here at one firing of the clock.

1973
01:23:33,256 --> 01:23:35,106
And then here at one
firing in the clock.

1974
01:23:35,436 --> 01:23:37,186
And the paddle could have
been here in the middle.

1975
01:23:37,306 --> 01:23:39,866
So that would just be a
mathematical mistake on my part.

1976
01:23:40,076 --> 01:23:42,286
And something that
could I'd run the risk

1977
01:23:42,286 --> 01:23:44,106
of if I had variable velocities.

1978
01:23:44,106 --> 01:23:47,346
But all I'm doing with my
velocity here is just inverting

1979
01:23:47,346 --> 01:23:48,666
it, positive or negative.

1980
01:23:49,576 --> 01:23:50,296
Good question.

1981
01:23:50,726 --> 01:23:53,736
Other questions you have?

1982
01:23:54,696 --> 01:23:57,266
All right, so, here is my
artificial intelligence,

1983
01:23:57,266 --> 01:23:59,956
if you recall want to have
basic AI in your game.

1984
01:24:00,306 --> 01:24:02,506
Really, all I have to
do is tell the paddle

1985
01:24:02,506 --> 01:24:05,336
to move toward the
ball along that Y axis.

1986
01:24:05,686 --> 01:24:08,476
And as long as he can move
just as quickly as the ball,

1987
01:24:08,476 --> 01:24:09,986
he will never make a mistake.

1988
01:24:09,986 --> 01:24:10,846
So what am I doing?

1989
01:24:10,846 --> 01:24:16,166
So, if the velocity at which
I'm moving is negative,

1990
01:24:16,506 --> 01:24:19,656
what does that actually mean?

1991
01:24:20,946 --> 01:24:24,636
If the ball is moving left so
that means that it's coming

1992
01:24:24,636 --> 01:24:26,176
at the computer's paddle.

1993
01:24:26,176 --> 01:24:28,096
My paddle was on the
right for this version.

1994
01:24:28,296 --> 01:24:29,296
Computer's on the left.

1995
01:24:29,436 --> 01:24:32,166
So if the ball is moving this
way, that's the indicator,

1996
01:24:32,166 --> 01:24:35,366
according to this code the
computer AI should start

1997
01:24:35,366 --> 01:24:36,146
doing something.

1998
01:24:36,466 --> 01:24:39,736
So if the ball's center
Y component is lower

1999
01:24:39,736 --> 01:24:42,316
than the paddle's Y component,

2000
01:24:42,526 --> 01:24:44,236
the paddle should
per the next line

2001
01:24:44,236 --> 01:24:47,596
of code move its
center toward the ball.

2002
01:24:47,996 --> 01:24:51,426
Conversely, if the ball center
is higher than the paddle,

2003
01:24:51,716 --> 01:24:54,106
the paddle should move
up toward the ball.

2004
01:24:54,446 --> 01:24:56,246
And so, no matter what it seems,

2005
01:24:56,696 --> 01:24:59,506
this paddle will always
keep pace with the ball

2006
01:24:59,676 --> 01:25:03,286
and really only I, the human,
am ever at risk of losing.

2007
01:25:04,086 --> 01:25:07,486
So let's see if this
is indeed the case.

2008
01:25:07,486 --> 01:25:09,266
If I run this version
of the game.

2009
01:25:10,586 --> 01:25:12,046
We now have two paddles
on the right.

2010
01:25:12,046 --> 01:25:14,056
If I click, that's when
the kickOff starts.

2011
01:25:14,386 --> 01:25:18,026
And notice, he only moves when
the ball is coming back at him,

2012
01:25:18,026 --> 01:25:20,026
because of that check.

2013
01:25:21,096 --> 01:25:23,736
Though we could add some
randomness if we really wanted

2014
01:25:23,736 --> 01:25:25,426
to give the human
a fighting chance,

2015
01:25:25,426 --> 01:25:27,666
we could have the paddle keep
moving somewhat randomly.

2016
01:25:27,666 --> 01:25:28,896
We could change its speed.

2017
01:25:29,576 --> 01:25:32,776
But for the most part, we
have a pretty boring game.

2018
01:25:33,306 --> 01:25:36,766
But we can make it more
interesting if we go back here.

2019
01:25:38,176 --> 01:25:40,266
And what can make
it more interesting?

2020
01:25:40,266 --> 01:25:44,476
How about we change this to
30 points per unit of time.

2021
01:25:44,976 --> 01:25:46,616
Now, if we rerun the program,

2022
01:25:47,936 --> 01:25:49,736
we'll get a game
that's a little harder.

2023
01:25:50,336 --> 01:26:00,926
And come on now,
if I click damn it.

2024
01:26:01,316 --> 01:26:01,976
Damn it [chuckles].

2025
01:26:02,516 --> 01:26:08,426
[ Chuckles ]

2026
01:26:08,926 --> 01:26:09,626
There we go.

2027
01:26:09,626 --> 01:26:09,976
Thank you [chuckles].

2028
01:26:09,976 --> 01:26:13,006
Okay. So it's really hard now.

2029
01:26:13,386 --> 01:26:16,846
I mean, if you can imagine
making this into even more

2030
01:26:16,846 --> 01:26:18,906
of a game, maybe a utility
app where it flips over.

2031
01:26:19,056 --> 01:26:20,576
You can change the
size of the paddle,

2032
01:26:20,576 --> 01:26:22,686
kind of like a game
arachnoid years ago,

2033
01:26:22,686 --> 01:26:23,616
where things get harder

2034
01:26:23,616 --> 01:26:24,966
or easier depending
on the settings.

2035
01:26:25,216 --> 01:26:27,086
So there's a number of
things you can do with this.

2036
01:26:27,086 --> 01:26:29,356
But at the end of the day,
we've really didn't write all

2037
01:26:29,356 --> 01:26:30,246
that much code, right?

2038
01:26:30,246 --> 01:26:31,756
We asked iOS to inform us

2039
01:26:31,966 --> 01:26:34,636
when is the movement
happening with the touches?

2040
01:26:34,636 --> 01:26:35,876
So we could respond to that.

2041
01:26:36,146 --> 01:26:37,716
Then we drew some
things in advance.

2042
01:26:37,716 --> 01:26:40,486
But we've seen that we could
totally skip the Photoshop step

2043
01:26:40,486 --> 01:26:42,916
and just draw these
paddles as their own classes

2044
01:26:42,916 --> 01:26:43,696
and instantiate them

2045
01:26:43,696 --> 01:26:45,396
and do something almost
identical with the ball.

2046
01:26:45,396 --> 01:26:46,756
Just making it a little smaller.

2047
01:26:46,926 --> 01:26:49,196
And at the end of the
day, the only thing

2048
01:26:49,196 --> 01:26:51,606
that I'm doing here is
I'm borrowing some code

2049
01:26:51,606 --> 01:26:52,876
from my paddle example.

2050
01:26:52,976 --> 01:26:56,286
Anytime the touches
move, method is called.

2051
01:26:56,496 --> 01:26:58,486
And that means something
has happened on the glass

2052
01:26:58,486 --> 01:26:59,456
where the human's touched.

2053
01:26:59,736 --> 01:27:02,196
I'm going to ask, give
me one of those touches.

2054
01:27:02,196 --> 01:27:04,026
Figure out what its
X comma Y is.

2055
01:27:04,286 --> 01:27:07,476
And move the right hand paddle
to that side of the screen.

2056
01:27:07,476 --> 01:27:09,326
So, really, the human
side of things boils

2057
01:27:09,326 --> 01:27:11,816
down to just those
three lines of codes.

2058
01:27:11,816 --> 01:27:15,566
We have yet another few pieces
of buildings blocks there.

2059
01:27:16,116 --> 01:27:18,966
So any questions on our
first two dimensional game?

2060
01:27:19,516 --> 01:27:25,986
[ Background Discussion ]

2061
01:27:26,486 --> 01:27:28,576
Good question.

2062
01:27:28,576 --> 01:27:30,036
Am I doing anything
to prevent the paddle

2063
01:27:30,036 --> 01:27:30,946
from pushing off the screen?

2064
01:27:31,306 --> 01:27:36,926
Yes, I am in the sense that my
code is only ever altering the Y

2065
01:27:37,146 --> 01:27:38,246
axis of the paddle.

2066
01:27:38,486 --> 01:27:40,576
I'm only allowing it
to move up and down.

2067
01:27:40,966 --> 01:27:44,406
So notice here, recall
this line of code

2068
01:27:44,406 --> 01:27:45,676
from our previous example.

2069
01:27:46,136 --> 01:27:48,326
The paddle on the
right, his center,

2070
01:27:48,506 --> 01:27:52,876
is only ever being updated
according to the Y axis.

2071
01:27:53,426 --> 01:27:56,176
So notice, this value
here, the X value,

2072
01:27:56,616 --> 01:27:59,566
this is literally the
paddle's current X location.

2073
01:27:59,816 --> 01:28:02,386
Because it's
self.paddleRight.center.x. So,

2074
01:28:02,386 --> 01:28:03,886
what is your current X location?

2075
01:28:04,196 --> 01:28:06,636
And the fact that I've pasted
that as the first argument

2076
01:28:06,726 --> 01:28:09,836
to CGPointMake, means whatever
your X location is now,

2077
01:28:10,026 --> 01:28:11,126
it's going to stay that way,

2078
01:28:11,276 --> 01:28:12,956
because that's the new
point that I'm making.

2079
01:28:13,326 --> 01:28:15,446
But location.y is
coming from what?

2080
01:28:15,996 --> 01:28:18,746
From the human touches based
on these two previous lines.

2081
01:28:19,076 --> 01:28:21,276
So in short, this third
and final line of code

2082
01:28:21,276 --> 01:28:23,106
in here is just ensuring

2083
01:28:23,106 --> 01:28:25,466
that the paddle's center
will absolutely be able

2084
01:28:25,466 --> 01:28:26,566
to go up and down.

2085
01:28:26,986 --> 01:28:29,536
But it will never respond
to left, right movements.

2086
01:28:29,536 --> 01:28:30,926
But with we can decouple those.

2087
01:28:31,206 --> 01:28:34,286
If I go back, just like I did
last time, and say, "Go ahead

2088
01:28:34,286 --> 01:28:37,976
and let the user have
location.x," and now run this.

2089
01:28:38,756 --> 01:28:42,916
Now this game's I can't do
30 points per second, ten?

2090
01:28:43,626 --> 01:28:46,856
Now this game gets a little more
interesting in that I have a bit

2091
01:28:46,856 --> 01:28:49,166
of advantage where
I can just kind

2092
01:28:49,166 --> 01:28:53,316
of chase this oh damn it
[chuckles] over there.

2093
01:28:53,546 --> 01:28:56,796
So that has to do with the
refresh rate, so to speak.

2094
01:28:56,796 --> 01:28:58,216
So now the math a little off

2095
01:28:58,216 --> 01:28:59,946
in that I can't assume
a certain access.

2096
01:29:00,226 --> 01:29:07,246
But now I have decoupled
it from that axis.

2097
01:29:07,316 --> 01:29:07,976
Oh, it is.

2098
01:29:07,976 --> 01:29:09,026
I'm just stopping.

2099
01:29:09,236 --> 01:29:11,826
My mouse can't quite
pull it all the up there.

2100
01:29:11,916 --> 01:29:13,946
But yes, it's going off
the screen somewhat.

2101
01:29:14,856 --> 01:29:15,926
And with he can detect that too,

2102
01:29:15,926 --> 01:29:17,066
because we know the
height of the thing.

2103
01:29:17,066 --> 01:29:17,906
And we could just ensure

2104
01:29:17,906 --> 01:29:19,646
that you couldn't go any
higher than the glass.

2105
01:29:20,066 --> 01:29:25,356
In this case, but if
you've ever been bored

2106
01:29:25,356 --> 01:29:28,226
like what do I usually
do on my phone?

2107
01:29:28,226 --> 01:29:29,946
Sometimes when you're
really bored in iOS,

2108
01:29:29,946 --> 01:29:31,766
you can start using your
thumbs and like start pulling

2109
01:29:31,766 --> 01:29:33,396
down on Safari to see
how far [chuckles].

2110
01:29:33,396 --> 01:29:36,266
So other people have
done this yes?

2111
01:29:36,266 --> 01:29:38,086
Okay. So someone has
checked for that in Safari,

2112
01:29:38,086 --> 01:29:39,446
we have not checked
for that here.

2113
01:29:39,446 --> 01:29:41,506
So, in theory, you could
get it to go off the screen

2114
01:29:41,506 --> 01:29:44,296
and probably get it such
that you can't, maybe,

2115
01:29:44,296 --> 01:29:46,826
can't get it back depending

2116
01:29:46,826 --> 01:29:48,466
on where it's detecting
the fingerprints.

2117
01:29:49,176 --> 01:29:51,386
I'm glad that's normal
behavior [chuckles].

2118
01:29:52,116 --> 01:29:53,006
All right.

2119
01:29:53,576 --> 01:29:55,866
Any questions then?

2120
01:29:56,226 --> 01:29:57,746
All right, so what
the lies ahead?

2121
01:29:57,746 --> 01:29:59,606
Well, evil hang man is
still in front of us.

2122
01:29:59,806 --> 01:30:02,936
On Wednesday, we are
going to take a direction

2123
01:30:02,936 --> 01:30:06,516
in a lab that's not specifically
about the final project

2124
01:30:06,516 --> 01:30:08,466
because there is no
one specification.

2125
01:30:08,466 --> 01:30:09,816
It's up to you guys
to propose this.

2126
01:30:10,146 --> 01:30:12,596
We'll have the specification
posted for it on Wednesday.

2127
01:30:12,596 --> 01:30:15,566
But it'll essentially boil down
to come up with an amazing idea.

2128
01:30:15,566 --> 01:30:20,396
Propose it to your TF and await
his confirmation or request

2129
01:30:20,516 --> 01:30:21,906
for modification to the idea.

2130
01:30:21,906 --> 01:30:24,066
And the request won't be,
"We don't like your idea,"

2131
01:30:24,066 --> 01:30:26,846
we'll be more, "We don't think
that's realistic in two weeks."

2132
01:30:26,846 --> 01:30:28,806
Or we think "That's too
realistic in two weeks."

2133
01:30:29,096 --> 01:30:30,766
Just to give you a
sense of calibration

2134
01:30:30,766 --> 01:30:32,916
so you can bite off something
that you can indeed chew.

2135
01:30:33,156 --> 01:30:34,776
And what we'll do is
try to calibrate you

2136
01:30:34,776 --> 01:30:37,286
so you have a threshold,
a quality threshold,

2137
01:30:37,286 --> 01:30:38,296
that you'll definitely need.

2138
01:30:38,486 --> 01:30:42,086
And we'll also try to push you a
little bit to have, say, a good,

2139
01:30:42,086 --> 01:30:44,176
better, best version
of your application.

2140
01:30:44,176 --> 01:30:45,846
Or it'd be amazing if
you get the best version.

2141
01:30:46,016 --> 01:30:48,006
But we'll be quite pleased
if you get the good version

2142
01:30:48,086 --> 01:30:49,776
out the door in time
for that app party.

2143
01:30:49,776 --> 01:30:52,506
So in lab this week, what Chris
Gerber will do is introduce you

2144
01:30:52,506 --> 01:30:54,656
to some more advanced
techniques in iOS

2145
01:30:55,086 --> 01:30:57,436
to further seed your
minds with opportunities.

2146
01:30:57,436 --> 01:30:59,996
Even though the proposal will
be due shortly thereafter.

2147
01:30:59,996 --> 01:31:01,516
Realize that you can
change your mind.

2148
01:31:01,516 --> 01:31:03,856
If you realize, "Wow, I
love the accelerometer.

2149
01:31:03,856 --> 01:31:04,946
I really want to
do this instead."

2150
01:31:05,216 --> 01:31:07,386
Just make sure to have a two
way conversation with your TF

2151
01:31:07,386 --> 01:31:09,586
to make sure it sounds
like a reasonable change.

2152
01:31:09,946 --> 01:31:11,716
Why don't we officially an
adjourn here for tonight

2153
01:31:11,716 --> 01:31:14,996
and we'll see you
next on Wednesday.

