1
00:00:00,506 --> 00:00:06,586
[ Silence ]

2
00:00:07,086 --> 00:00:11,076
>> Today, we're going to
be looking at Mobile Local

3
00:00:11,156 --> 00:00:13,086
which you of course
have already seen.

4
00:00:13,416 --> 00:00:16,206
But basically over the last few
days what I did was I rewrote

5
00:00:16,206 --> 00:00:18,776
Mobile Local in my
own interpretation

6
00:00:18,776 --> 00:00:20,116
as iOS application.

7
00:00:20,546 --> 00:00:22,486
And I'm going to use
that as a demonstration

8
00:00:22,486 --> 00:00:25,476
of what your iOS
application might look like,

9
00:00:26,166 --> 00:00:28,416
some advanced topics that
you might want to use

10
00:00:28,416 --> 00:00:29,766
as you're developing
your application.

11
00:00:30,206 --> 00:00:33,806
I just want to walk you through
how you might take some sample

12
00:00:33,806 --> 00:00:37,326
code that you seen and sort of
deconstruct and learn from it.

13
00:00:38,196 --> 00:00:41,996
So, let's jump over
to the slides.

14
00:00:41,996 --> 00:00:47,576
And actually I'm just
going to present like this

15
00:00:47,576 --> 00:00:53,656
so it doesn't mess with me
if I can find my cursor.

16
00:00:53,746 --> 00:00:55,426
Here we go.

17
00:00:56,246 --> 00:00:57,986
All right.

18
00:00:58,226 --> 00:01:02,096
So, with this example app, I've
got several things that I want

19
00:01:02,096 --> 00:01:04,746
to sort of present and give you
sort of high level of overview

20
00:01:04,746 --> 00:01:06,576
of how you might use them
in your applications.

21
00:01:07,326 --> 00:01:09,446
I've started by using
a tab bar controller.

22
00:01:09,736 --> 00:01:12,666
They explicitly use models
to store some of my data.

23
00:01:13,506 --> 00:01:16,176
I used a singleton patterns so
it give you an idea of what--

24
00:01:16,176 --> 00:01:17,546
how you might use
design patterns

25
00:01:17,546 --> 00:01:18,676
in your Objective-C code.

26
00:01:18,996 --> 00:01:21,786
I've got a view that
uses table views.

27
00:01:21,976 --> 00:01:25,276
I'm going to programmatically
instantiation

28
00:01:25,536 --> 00:01:29,236
which is basically just creating
a view dynamically in the code

29
00:01:29,236 --> 00:01:30,396
and then presenting it rather

30
00:01:30,396 --> 00:01:32,646
than pre-building it
in interface builder.

31
00:01:32,646 --> 00:01:36,276
We're going to look a little
bit at blocks and callbacks

32
00:01:36,276 --> 00:01:38,876
which I think was one slide
in the lecture so far.

33
00:01:38,876 --> 00:01:40,096
Tonight we're actually
going to use them

34
00:01:40,096 --> 00:01:42,656
to use asynchronous HTTP calls.

35
00:01:43,466 --> 00:01:45,406
I'm going to use a
little call location.

36
00:01:45,406 --> 00:01:48,176
I just did reverse geo location

37
00:01:48,176 --> 00:01:52,226
to translate my current
location to a zip code.

38
00:01:52,346 --> 00:01:54,006
We're going to use
storyboard constraints.

39
00:01:54,006 --> 00:01:59,016
So, you can look at how you
can pin things dynamically

40
00:01:59,016 --> 00:02:01,556
to your interface and
then, for example,

41
00:02:01,556 --> 00:02:02,716
when you rotate the display,

42
00:02:02,716 --> 00:02:05,466
things end up in a logical
location as supposed

43
00:02:05,466 --> 00:02:07,176
to just some are random.

44
00:02:07,796 --> 00:02:10,766
And then I quickly show you
how you can use unit test

45
00:02:10,806 --> 00:02:13,266
to help test your application
as you're going along.

46
00:02:14,166 --> 00:02:15,036
Is that sound good so far?

47
00:02:15,516 --> 00:02:16,116
You got a question?

48
00:02:16,376 --> 00:02:19,696
>> In our project does it matter
if we did this programmatical--

49
00:02:20,206 --> 00:02:21,246
>> Instantiation.

50
00:02:21,306 --> 00:02:24,266
>> Or just use the
interface building?

51
00:02:24,866 --> 00:02:26,906
>> So the question is for
the project should you use

52
00:02:26,956 --> 00:02:29,546
programmatical instantiation
or interface builder.

53
00:02:29,546 --> 00:02:31,306
And you can certainly
use interface builder.

54
00:02:31,676 --> 00:02:33,986
This is just-- if you find
yourself in a situation

55
00:02:33,986 --> 00:02:37,686
where you think it be better
to dynamically generate stuff,

56
00:02:37,686 --> 00:02:40,646
you'll at least have an
example of how to do it.

57
00:02:40,646 --> 00:02:42,226
I would do it in
one small place.

58
00:02:42,706 --> 00:02:46,836
Any other questions
before we jump in?

59
00:02:47,036 --> 00:02:48,006
All right.

60
00:02:49,036 --> 00:02:51,886
Now, the first I want to do
is just show you what the app

61
00:02:51,886 --> 00:02:52,776
actually looks like.

62
00:02:53,316 --> 00:02:54,666
If you're interested in check it

63
00:02:54,666 --> 00:02:56,446
out that slides will
be posted online,

64
00:02:56,446 --> 00:02:58,796
the links will we posted online,
but I've just throwing it

65
00:02:58,796 --> 00:03:00,886
up on GitHub under my
personal account gerbercj

66
00:03:00,886 --> 00:03:03,246
and it's simply called
Mobile Local.

67
00:03:03,396 --> 00:03:06,686
If you haven't used Git, it's a
great software development tool.

68
00:03:07,166 --> 00:03:09,366
I have not fully
exploited in this project

69
00:03:09,366 --> 00:03:11,906
but you can do group
development very easily.

70
00:03:12,036 --> 00:03:14,516
You can do revision
histories over time.

71
00:03:14,936 --> 00:03:16,736
I've just got a single
snapshot of my code

72
00:03:16,736 --> 00:03:18,636
but it certainly
worth checking out.

73
00:03:18,836 --> 00:03:21,056
And if you install the
command line tool is part

74
00:03:21,056 --> 00:03:23,346
of installing Xcode, the get
command should already be there.

75
00:03:24,506 --> 00:03:29,416
So, let's look at
what this app is.

76
00:03:29,616 --> 00:03:29,946
All right.

77
00:03:30,036 --> 00:03:32,326
So, I've got my standard
project.

78
00:03:32,326 --> 00:03:33,726
I'm just going to
hit the run button.

79
00:03:34,516 --> 00:03:49,476
[ Pause ]

80
00:03:49,976 --> 00:03:51,326
And I'm going to bring the
simulator to the right screen

81
00:03:51,356 --> 00:03:51,986
and make it little bigger.

82
00:03:52,016 --> 00:03:52,976
100 percent might be too much.

83
00:03:53,516 --> 00:03:57,136
[ Pause ]

84
00:03:57,636 --> 00:03:58,226
All right.

85
00:03:58,766 --> 00:04:00,316
So, I've got my standard
iOS app.

86
00:04:00,316 --> 00:04:01,346
It's already started running.

87
00:04:02,306 --> 00:04:05,816
You can see my location
is changing over time.

88
00:04:05,816 --> 00:04:08,916
This is actually one of
the standard pathways

89
00:04:08,976 --> 00:04:10,796
that Apple's predefined.

90
00:04:10,796 --> 00:04:16,166
If you've gone into the
debug menu and then location

91
00:04:16,166 --> 00:04:19,076
which you can't see here,
you can actually see

92
00:04:19,076 --> 00:04:23,136
that this one is called Apple
Stores and it just moving slowly

93
00:04:23,136 --> 00:04:27,046
from location to location
visiting every Apple Store.

94
00:04:27,246 --> 00:04:30,466
So, as it's going, you'll see
the zip code is also changing.

95
00:04:31,016 --> 00:04:34,616
I've got some tabs setup
here at the bottom.

96
00:04:34,616 --> 00:04:37,746
I've got location, whether and
news which you will remember

97
00:04:37,786 --> 00:04:39,446
from the previous project.

98
00:04:39,726 --> 00:04:42,146
>> Sir, how do you
going to change the--

99
00:04:42,146 --> 00:04:46,106
'cause in mine it
defaults to Cupertino,

100
00:04:46,106 --> 00:04:46,966
California or something.

101
00:04:47,466 --> 00:04:49,966
>> So, the question is how
you get it change location.

102
00:04:50,016 --> 00:04:53,336
And the way I've done is
simply under the debug menu

103
00:04:53,336 --> 00:04:55,356
when you choose location
I've pick one

104
00:04:55,356 --> 00:04:57,146
that does move automatically.

105
00:04:57,666 --> 00:05:01,236
So, they have things like custom
location which is a fixed spot.

106
00:05:02,226 --> 00:05:04,756
Apple Stores happens to be
one that travels around.

107
00:05:05,146 --> 00:05:06,816
If you want something
out of smaller scale,

108
00:05:06,816 --> 00:05:08,376
they have one that
is bicycle ride.

109
00:05:08,776 --> 00:05:11,076
So, it's a slower pace but
it does move around the city

110
00:05:11,416 --> 00:05:13,476
and you could play around
with the ones in there.

111
00:05:13,476 --> 00:05:14,536
>> Where is that?

112
00:05:14,536 --> 00:05:17,676
>> In iOS simulator under
debug and then location.

113
00:05:20,706 --> 00:05:26,426
OK. And where's my cursor.

114
00:05:26,546 --> 00:05:30,446
So, the weather tab.

115
00:05:30,656 --> 00:05:33,386
I had to brand it.

116
00:05:33,386 --> 00:05:35,386
I use whether underground
as part

117
00:05:35,386 --> 00:05:37,196
of their agreement
to use their data.

118
00:05:37,196 --> 00:05:39,056
I have agreed to put
their logo on my page.

119
00:05:40,266 --> 00:05:44,056
Well, you'll see it's currently
sunny in wherever this is 85320,

120
00:05:44,056 --> 00:05:45,796
it's 103 degrees so
I'm happy to be here

121
00:05:45,796 --> 00:05:46,956
in Boston, much better today.

122
00:05:47,836 --> 00:05:50,596
And I've thrown out the
same temperature in Celsius.

123
00:05:51,126 --> 00:05:55,486
And I can also pull up the news
from my current location which--

124
00:05:55,646 --> 00:05:59,626
I though I fixed
this last night.

125
00:06:00,006 --> 00:06:03,866
But I happen to pick a location
that doesn't have any news

126
00:06:03,976 --> 00:06:04,816
so I got an exception.

127
00:06:05,696 --> 00:06:10,576
So, for the proof that I
can [inaudible] code just

128
00:06:10,576 --> 00:06:12,006
as well as anyone else.

129
00:06:14,116 --> 00:06:15,696
But you people get
the basic idea

130
00:06:15,696 --> 00:06:17,136
of how the app works how close.

131
00:06:17,636 --> 00:06:19,096
All right.

132
00:06:19,526 --> 00:06:22,976
Let's look at how some of these
things are actually implemented.

133
00:06:23,516 --> 00:06:30,496
[ Pause ]

134
00:06:30,996 --> 00:06:31,626
All right.

135
00:06:31,626 --> 00:06:34,416
So, first I want to talk
about is Tab Bar Controller.

136
00:06:34,866 --> 00:06:36,696
I've put it-- in each
case I put a link

137
00:06:36,696 --> 00:06:38,416
to the Apple documentation
where its applicable

138
00:06:38,416 --> 00:06:39,436
so you can actually go back

139
00:06:39,436 --> 00:06:42,106
and see how I learned
how to do these things.

140
00:06:42,536 --> 00:06:44,616
For this the only part
we really need to look

141
00:06:44,616 --> 00:06:48,376
at is the storyboards
at least at this level.

142
00:06:48,376 --> 00:06:54,006
So, we can go to my project.

143
00:06:58,396 --> 00:06:59,846
It's around here somewhere.

144
00:07:00,366 --> 00:07:01,266
There he is.

145
00:07:03,956 --> 00:07:06,546
So, you see broken things out
to model view and controller.

146
00:07:07,146 --> 00:07:08,956
In this case it's
part of the view.

147
00:07:09,866 --> 00:07:11,646
So, we look at the
storyboard for my app.

148
00:07:11,646 --> 00:07:19,406
And we can hide this for now,
we can hide this for now.

149
00:07:19,406 --> 00:07:23,466
So, the tab bar controller,
I've just dropped--

150
00:07:24,086 --> 00:07:26,476
actually, I just
created by default

151
00:07:26,986 --> 00:07:29,226
when I did the file
new for my project.

152
00:07:29,226 --> 00:07:33,826
I chose this as my name
type of controller.

153
00:07:34,486 --> 00:07:36,586
And it created two of
these views for me.

154
00:07:37,476 --> 00:07:38,846
And you'll see it's
automatically created

155
00:07:38,846 --> 00:07:39,606
the segways.

156
00:07:40,106 --> 00:07:42,726
When you create an
additional view,

157
00:07:43,296 --> 00:07:47,206
you can actually do the same
thing we've been doing all

158
00:07:47,206 --> 00:07:50,416
semester where you can
control click and drag,

159
00:07:50,746 --> 00:07:51,996
in this case it's
already in there.

160
00:07:52,346 --> 00:07:55,526
But it will drop your
new view into the tab

161
00:07:55,526 --> 00:07:56,616
for you automatically.

162
00:07:57,356 --> 00:08:00,096
It's surprisingly
easy to get setup.

163
00:08:01,226 --> 00:08:03,236
So, theoretically
if we pick another

164
00:08:03,236 --> 00:08:07,896
like table view controller
rather

165
00:08:08,616 --> 00:08:16,486
than we could-- where
do I do that?

166
00:08:17,516 --> 00:08:22,946
[ Pause ]

167
00:08:23,446 --> 00:08:25,226
Add that to the controller
as well.

168
00:08:25,786 --> 00:08:30,116
I'm going to take that back out.

169
00:08:30,866 --> 00:08:32,636
Some of the interesting
properties

170
00:08:32,636 --> 00:08:35,866
that have used here is
you'll see I've added icons

171
00:08:35,866 --> 00:08:36,486
to each thing.

172
00:08:37,636 --> 00:08:40,686
Theses thing are simple as
going into the properties

173
00:08:40,686 --> 00:08:41,936
and putting an icon in.

174
00:08:42,456 --> 00:08:43,726
I've changed the name.

175
00:08:44,346 --> 00:08:48,006
This was actually one of the
easiest parts of the app for me,

176
00:08:48,006 --> 00:08:50,776
it was basically all
drag and drop, GUI stuff.

177
00:08:51,286 --> 00:08:53,026
The magic of using
interface builder.

178
00:08:53,026 --> 00:08:55,366
So, this is the e exciting
part of using a like Xcode

179
00:08:55,366 --> 00:08:56,786
where you can drag
these things together

180
00:08:56,786 --> 00:09:00,696
and make your UI very quickly.

181
00:09:00,876 --> 00:09:04,026
Basically all I wanted
to show you in that.

182
00:09:04,146 --> 00:09:05,836
We'll get to things that
actually have more code

183
00:09:05,836 --> 00:09:07,156
and those get a little
more interesting.

184
00:09:12,036 --> 00:09:14,656
So, models, we've
talked about models.

185
00:09:15,146 --> 00:09:17,286
I saw some of you in your
Evil Hangman, did a good job

186
00:09:17,286 --> 00:09:19,656
of [inaudible] some
code out in the models.

187
00:09:20,136 --> 00:09:22,296
But I want to talk about,
you know, how it might work

188
00:09:22,296 --> 00:09:23,766
in an application like this.

189
00:09:24,526 --> 00:09:26,716
So, broken out of few ideas
that we're going to look at,

190
00:09:27,626 --> 00:09:31,116
we obviously have the
concepts of the news,

191
00:09:31,366 --> 00:09:33,616
the weather, the
current location.

192
00:09:34,196 --> 00:09:36,866
So, consider those to be
sources of data, and therefore,

193
00:09:36,866 --> 00:09:38,396
made them a model
in my application.

194
00:09:39,116 --> 00:09:41,446
News is actually composed
of a bunch of articles.

195
00:09:41,446 --> 00:09:43,216
I made news article
class as well.

196
00:09:43,466 --> 00:09:48,326
And we can start to look
at what this look like.

197
00:09:48,466 --> 00:09:53,086
So, in my models, you'll
see the same things we just

198
00:09:53,086 --> 00:09:53,676
talked about.

199
00:09:54,496 --> 00:09:57,216
If we look at a news
article, I probably going

200
00:09:57,216 --> 00:09:58,976
to have to zoom this in.

201
00:09:59,516 --> 00:10:04,096
[ Pause ]

202
00:10:04,596 --> 00:10:10,016
Let's makes it easier and
start with header file.

203
00:10:10,196 --> 00:10:12,006
So, we're used to the interface.

204
00:10:12,006 --> 00:10:13,536
I think that should
be straight forward.

205
00:10:14,056 --> 00:10:17,246
I simply got two properties
and news article has a headline

206
00:10:17,446 --> 00:10:19,846
and a URL, that's all I
cared about in this case.

207
00:10:20,546 --> 00:10:22,346
And I've built a constructor

208
00:10:22,346 --> 00:10:25,116
where I can create a new
news article with init

209
00:10:25,116 --> 00:10:26,826
with headline and URL.

210
00:10:27,706 --> 00:10:30,806
And behind the scenes, this
should then make articles

211
00:10:30,806 --> 00:10:33,096
that I know how to ask them
what their headline is,

212
00:10:33,096 --> 00:10:34,706
ask them what their URL is.

213
00:10:35,546 --> 00:10:38,786
And ultimately it should read--
lead to more readable code.

214
00:10:39,206 --> 00:10:42,876
Just at this level, does it sort

215
00:10:42,876 --> 00:10:45,896
of makes sense what this
thing is, what it looks like,

216
00:10:45,896 --> 00:10:47,366
what this might feel
like in code?

217
00:10:47,866 --> 00:10:50,796
Getting at least
one head nodding.

218
00:10:51,886 --> 00:10:54,206
All right, it sounds good.

219
00:10:55,376 --> 00:11:01,036
As we move on to-- let's
move to location neck, well,

220
00:11:01,036 --> 00:11:02,626
let's move to news next.

221
00:11:04,036 --> 00:11:06,716
So, news should be all
the news articles right.

222
00:11:07,276 --> 00:11:08,946
So, this one is actually
pretty simple as well,

223
00:11:09,276 --> 00:11:11,656
it's going to have
some sort of collection

224
00:11:11,656 --> 00:11:15,046
in this case a mutable array
that contains articles.

225
00:11:15,906 --> 00:11:17,986
So, I'm not thinking
about this is an array

226
00:11:17,986 --> 00:11:20,436
of strings and stuff like that.

227
00:11:20,696 --> 00:11:24,056
All I'm thinking about is
news is composed of articles.

228
00:11:24,296 --> 00:11:26,926
So, I feel like this already
has in a layer of obstruction

229
00:11:26,926 --> 00:11:27,736
that makes it easier

230
00:11:27,736 --> 00:11:29,326
to understand what's
going on with the app.

231
00:11:30,876 --> 00:11:33,716
It's also got this
refresh with location

232
00:11:33,796 --> 00:11:38,156
with call back call back, I
don't want to worry too much

233
00:11:38,156 --> 00:11:42,296
about that yet but refresh with
location, location sounds to me

234
00:11:42,296 --> 00:11:45,346
like when I know
there's a new location,

235
00:11:45,346 --> 00:11:46,426
refresh your data right.

236
00:11:46,426 --> 00:11:50,076
It's-- that will get a little
more magical with call back,

237
00:11:50,646 --> 00:11:52,226
we'll come back to
because that's

238
00:11:52,286 --> 00:11:56,506
where things get a little
weird in this example.

239
00:11:56,506 --> 00:11:59,496
Whether it's going to
look very much the same

240
00:11:59,496 --> 00:12:00,536
but we've got a lot more data.

241
00:12:01,246 --> 00:12:04,176
So, we've got temperatures,
conditions, observations times,

242
00:12:04,236 --> 00:12:06,646
we've got image name
and image URL.

243
00:12:07,186 --> 00:12:09,986
Not too bad.

244
00:12:09,986 --> 00:12:12,856
Those should feel
pretty logical.

245
00:12:13,016 --> 00:12:14,976
We've got the same sort
of refresh load location.

246
00:12:14,976 --> 00:12:18,016
I want to make my code
mirror self as much

247
00:12:18,016 --> 00:12:19,376
as possible for consistencies.

248
00:12:19,376 --> 00:12:21,876
So, when you see
refresh load location,

249
00:12:22,036 --> 00:12:23,406
you get the same idea again.

250
00:12:24,246 --> 00:12:26,446
I've also got this sort of
help of function down here.

251
00:12:27,406 --> 00:12:31,366
Is night time and this was a
function that I wasn't sure

252
00:12:31,366 --> 00:12:33,066
that it really was
part of the weather.

253
00:12:33,906 --> 00:12:37,026
But I didn't want to make
another class it was getting too

254
00:12:37,026 --> 00:12:37,636
late last night.

255
00:12:38,016 --> 00:12:40,766
So, I stop here and the
weather knows what time

256
00:12:40,766 --> 00:12:42,606
of day it is for some reason.

257
00:12:43,106 --> 00:12:45,676
Does this feel OK so far?

258
00:12:45,966 --> 00:12:51,076
OK. And the last one
then is location.

259
00:12:51,656 --> 00:12:55,096
And location is the
weirdest one.

260
00:12:56,376 --> 00:13:03,036
All it's got is a zip code and a
class method that is singleton.

261
00:13:03,566 --> 00:13:07,156
And this probably does
not look at all familiar

262
00:13:07,656 --> 00:13:10,066
and probably seems a little odd.

263
00:13:11,276 --> 00:13:16,956
I'm going to mute my sound
again now that we don't need it.

264
00:13:17,516 --> 00:13:25,426
[ Pause ]

265
00:13:25,926 --> 00:13:27,306
Actually I was also
going to look

266
00:13:27,306 --> 00:13:29,166
at the details of one class.

267
00:13:29,166 --> 00:13:31,826
So, we mentioned news
article was just the headline

268
00:13:31,826 --> 00:13:32,516
in the URL.

269
00:13:32,846 --> 00:13:36,566
We've got a quick and
meet with headline in URL.

270
00:13:37,516 --> 00:13:39,746
[ Pause ]

271
00:13:40,246 --> 00:13:42,966
Does this pattern look
familiar to folks?

272
00:13:43,026 --> 00:13:44,456
We've got the basic idea of it.

273
00:13:45,156 --> 00:13:47,486
Initializes its super
if that worked.

274
00:13:48,086 --> 00:13:51,006
We can set the headline to the
headline, the URL to the URL.

275
00:13:51,586 --> 00:13:53,916
Do folks remember why I'm
using an underscore here.

276
00:13:53,996 --> 00:13:54,066
Yeah.

277
00:13:54,116 --> 00:13:58,206
>> All of this by default
[inaudible] before the name

278
00:14:01,856 --> 00:14:02,316
of the property.

279
00:14:02,316 --> 00:14:02,806
>> Exactly.

280
00:14:02,806 --> 00:14:04,446
So, the answer was
the property is

281
00:14:04,446 --> 00:14:06,266
by default are putting
it underscore

282
00:14:06,486 --> 00:14:07,456
in front of the property.

283
00:14:07,956 --> 00:14:10,156
Sort of behind the
scenes, I was magic stuff

284
00:14:10,326 --> 00:14:14,456
but that basically says I'm
accessing the property directly

285
00:14:14,456 --> 00:14:15,886
without going through
its setter,

286
00:14:16,106 --> 00:14:17,316
directly manipulating the data.

287
00:14:17,356 --> 00:14:17,423
>> Sir.

288
00:14:17,466 --> 00:14:17,556
>> Yes.

289
00:14:17,806 --> 00:14:20,876
>> What's the difference
between this underscore

290
00:14:21,036 --> 00:14:23,226
and where is this
with a self dot?

291
00:14:23,796 --> 00:14:25,276
>> So, the question is
what's the difference

292
00:14:25,276 --> 00:14:27,586
between using underscore
and using self dot?

293
00:14:27,816 --> 00:14:31,026
If you use underscore, you're
going to get direct access

294
00:14:31,026 --> 00:14:33,436
to the variable and
you can manipulate it.

295
00:14:33,436 --> 00:14:35,706
If you use self dot,
it's actually going

296
00:14:35,706 --> 00:14:38,996
to use the setter
method, so a lot of times

297
00:14:38,996 --> 00:14:40,876
when you create a property
you don't bother setting--

298
00:14:41,416 --> 00:14:42,506
creating a setter method.

299
00:14:42,506 --> 00:14:46,236
It just uses the magic one which
doesn't do anything special.

300
00:14:46,816 --> 00:14:49,076
But you could have a setter
method that does things

301
00:14:49,076 --> 00:14:52,756
like check to make sure the
data is valid before it actually

302
00:14:52,756 --> 00:14:54,236
makes a change to
it things like that.

303
00:14:54,566 --> 00:14:57,136
So, by using underscore,
I'm making sure

304
00:14:57,136 --> 00:15:00,056
that if there's any
other magical stuff going

305
00:15:00,056 --> 00:15:01,676
on I'm ignoring it in this case.

306
00:15:02,176 --> 00:15:04,176
>> Is this a set
of function here?

307
00:15:04,626 --> 00:15:06,446
>> This is the constructor.

308
00:15:06,716 --> 00:15:09,206
So, at this point,
I know I'm in charge

309
00:15:09,206 --> 00:15:11,456
and I'm doing everything
I want to do.

310
00:15:11,946 --> 00:15:13,786
So, I didn't want to kill that.

311
00:15:13,786 --> 00:15:17,146
>> So, we are setting the header
lines rather than (inaudible)

312
00:15:17,536 --> 00:15:19,616
and this four header
line goes for heading?

313
00:15:19,616 --> 00:15:22,596
>> Yes. So, I'm still just
setting the headline value here.

314
00:15:23,596 --> 00:15:26,906
>> And self dot headline
also give the setter right?

315
00:15:27,876 --> 00:15:29,606
>> Yes. If I had
used self to headline

316
00:15:29,606 --> 00:15:31,636
in this example it would have
done the exact same thing.

317
00:15:32,516 --> 00:15:35,276
[ Pause ]

318
00:15:35,776 --> 00:15:36,686
All right.

319
00:15:37,466 --> 00:15:40,786
I'm going to stop, I
thought I muted you.

320
00:15:41,376 --> 00:15:43,376
[ Pause ]

321
00:15:43,736 --> 00:15:46,716
Apparently I can't mute,
that's interesting.

322
00:15:47,026 --> 00:15:47,576
All right.

323
00:15:47,576 --> 00:15:54,796
So, I wanted to look
at singletons.

324
00:15:54,926 --> 00:15:57,166
So, you saw I had that
singleton in there.

325
00:15:58,026 --> 00:16:01,586
So, this is the idea of
using a designed pattern.

326
00:16:02,046 --> 00:16:04,916
So, the one design pattern
was seen a lot already is the

327
00:16:04,916 --> 00:16:05,696
delegate pattern.

328
00:16:06,346 --> 00:16:10,866
That's pervasive in objective
C especially in iOS development

329
00:16:11,626 --> 00:16:14,246
where you can say that
another class is going

330
00:16:14,246 --> 00:16:15,666
to handle a method for you.

331
00:16:16,406 --> 00:16:20,646
The singleton pattern as for
Wikipedia is a design pattern

332
00:16:20,646 --> 00:16:24,436
that restricts the instantiation
of the class to one object.

333
00:16:25,396 --> 00:16:29,956
So, what this basically says
is I ask to create the object

334
00:16:30,396 --> 00:16:31,386
and it gives me the object.

335
00:16:31,386 --> 00:16:32,816
I ask to create the
object again,

336
00:16:33,036 --> 00:16:34,816
no matter where I am in my code.

337
00:16:35,246 --> 00:16:38,656
It gives me back the same
exact object as the first time.

338
00:16:39,556 --> 00:16:42,556
Now, you might start thinking
why would I want to do that like

339
00:16:42,556 --> 00:16:44,746
in the idea of a string
that doesn't make any sense.

340
00:16:44,746 --> 00:16:46,866
I want difference
strings within values.

341
00:16:47,636 --> 00:16:49,606
Where I'm going to
use it is in location.

342
00:16:49,786 --> 00:16:53,066
And the reason I'm going to
use it there is it's an example

343
00:16:53,066 --> 00:16:56,576
of how I can have
my news controller

344
00:16:56,906 --> 00:17:01,166
and my weather controller
and my location controller,

345
00:17:01,476 --> 00:17:04,836
all ask for location
object that has a zip code.

346
00:17:05,406 --> 00:17:06,906
But they all get
the same objects.

347
00:17:06,906 --> 00:17:09,766
So, if the location controller
is changing my zip code.

348
00:17:10,636 --> 00:17:14,276
When the news controller or
the weather controller asks

349
00:17:14,276 --> 00:17:18,516
for the zip code, it's going
to get the same point in memory

350
00:17:18,686 --> 00:17:20,686
and therefore get the
shared piece of data.

351
00:17:21,416 --> 00:17:23,906
So, in a way creating
a global variable,

352
00:17:24,696 --> 00:17:26,826
I don't like global variables
but this is an example

353
00:17:26,826 --> 00:17:28,316
of how you can use
a designed pattern

354
00:17:28,316 --> 00:17:30,336
in your code more than that.

355
00:17:30,336 --> 00:17:31,596
So, let's see what
this looks like

356
00:17:31,596 --> 00:17:36,996
and this is I hope the ugliest
code I show you tonight.

357
00:17:37,106 --> 00:17:41,176
And it's not my code,
it's attributed in here.

358
00:17:42,436 --> 00:17:44,236
And that was in location.

359
00:17:45,516 --> 00:17:50,296
[ Pause ]

360
00:17:50,796 --> 00:17:52,716
So, this came from
a guy who told me

361
00:17:52,716 --> 00:17:55,546
that I'm apparently doing them
wrong and this is the right way.

362
00:17:55,896 --> 00:17:56,936
And I trust them.

363
00:17:56,936 --> 00:18:01,766
This is actually a pretty
good approach to how to do it.

364
00:18:02,276 --> 00:18:04,076
So, remember its class level.

365
00:18:04,606 --> 00:18:06,756
And the reason it's class
level is we can only have

366
00:18:06,846 --> 00:18:07,836
one instance.

367
00:18:08,816 --> 00:18:11,286
And if I'm first trying
to get that instance

368
00:18:11,326 --> 00:18:14,666
if I don't already have it, you
sort again to this sketch 22.

369
00:18:14,666 --> 00:18:16,626
You need some way that
you can get to this.

370
00:18:16,626 --> 00:18:19,556
So, the class let's
me get there no matter

371
00:18:19,556 --> 00:18:21,306
where I'm starting from.

372
00:18:22,656 --> 00:18:24,256
They're creating a predicate

373
00:18:25,296 --> 00:18:31,366
and a shared instantiation
of the class.

374
00:18:32,816 --> 00:18:35,906
Don't get too bugged down in how
much this makes sense to you.

375
00:18:35,906 --> 00:18:37,636
It took me a few reads
through last night

376
00:18:37,636 --> 00:18:38,646
when I was looking at this.

377
00:18:39,556 --> 00:18:41,146
But understand that this works.

378
00:18:41,456 --> 00:18:43,846
And what it's doing actually
is it's creating a block

379
00:18:44,976 --> 00:18:49,316
that allocates the
location and initializes it

380
00:18:49,456 --> 00:18:51,326
and then returns
the shared value.

381
00:18:52,266 --> 00:18:55,146
The bottom line is when
you call this function,

382
00:18:56,456 --> 00:18:59,556
it checks if the location has
already been instantiated,

383
00:18:59,556 --> 00:19:01,056
if it has it gives it to you.

384
00:19:01,056 --> 00:19:03,316
If it hasn't it makes
it and gives it to you.

385
00:19:04,206 --> 00:19:05,286
Bottom line, no matter what,

386
00:19:05,576 --> 00:19:07,986
it always gives you
the same exact object.

387
00:19:09,436 --> 00:19:11,166
Does this make enough sense?

388
00:19:11,586 --> 00:19:13,186
You don't have to use
this in your code.

389
00:19:13,306 --> 00:19:15,936
It's just awareness of how you
can start applying these ideas

390
00:19:15,936 --> 00:19:16,366
in your code.

391
00:19:16,736 --> 00:19:16,836
OK.

392
00:19:17,516 --> 00:19:23,486
>> So, the shared in
there never change?

393
00:19:23,656 --> 00:19:25,436
>> So, the question is
shared can never changed.

394
00:19:25,436 --> 00:19:30,496
Exactly, shared, once it's set
to value because of the way

395
00:19:30,496 --> 00:19:32,156
that this dispatch once set

396
00:19:32,156 --> 00:19:36,766
up it will always
evaluate to the same thing.

397
00:19:37,516 --> 00:19:41,016
[ Pause ]

398
00:19:41,516 --> 00:19:41,746
All right.

399
00:19:41,926 --> 00:19:49,386
I'm going to try to go
relatively quickly tonight

400
00:19:49,386 --> 00:19:51,826
because I figured the
best use of the most

401
00:19:51,826 --> 00:19:53,556
of our time is helping
people with projects.

402
00:19:53,906 --> 00:19:55,566
So, we're just clausing
over some

403
00:19:55,566 --> 00:19:57,176
of this but we'll keep going.

404
00:19:57,746 --> 00:20:01,966
So, table views, table
views are list of data.

405
00:20:01,966 --> 00:20:04,196
You might have seen it
on your phone as contacts

406
00:20:04,196 --> 00:20:06,446
or something like that.

407
00:20:07,326 --> 00:20:10,596
I'm going to show you where
I've used it for the news

408
00:20:11,066 --> 00:20:17,226
and then we can look at
how-- how do we get there.

409
00:20:17,406 --> 00:20:19,776
There it is, so this time
we actually got news.

410
00:20:19,776 --> 00:20:22,126
So, the Table view
has a number of rows.

411
00:20:22,656 --> 00:20:25,466
Those rows are coming from
some sort of data source

412
00:20:26,336 --> 00:20:29,296
and in this case, I also
have disclosure indicators.

413
00:20:30,656 --> 00:20:32,876
By conventions, those say
when you click on this,

414
00:20:32,906 --> 00:20:35,326
it is going to take
you somewhere else.

415
00:20:36,176 --> 00:20:39,506
Additional details should be
provided at that time so it's

416
00:20:39,506 --> 00:20:43,076
like your list of contacts,
the details for each contact,

417
00:20:43,556 --> 00:20:46,706
the list of songs, the
actual details for that song.

418
00:20:46,706 --> 00:20:49,086
In my case it's the
list of news articles

419
00:20:49,166 --> 00:20:50,776
and the actual article
will pop up.

420
00:20:51,516 --> 00:20:56,196
[ Pause ]

421
00:20:56,696 --> 00:20:58,216
So, I've got the documentation.

422
00:20:58,276 --> 00:21:00,546
Let's look at story board
and [inaudible], OK.

423
00:21:01,516 --> 00:21:08,296
[ Pause ]

424
00:21:08,796 --> 00:21:11,036
So, this is my news controller.

425
00:21:12,316 --> 00:21:15,526
It's got something that's
apparently a giant table view

426
00:21:16,256 --> 00:21:19,946
and prototype cell
and the way this works

427
00:21:19,946 --> 00:21:21,046
in any interface builder

428
00:21:21,326 --> 00:21:24,446
with story boards is you
basically tell it how

429
00:21:24,446 --> 00:21:27,016
to build one cell and it
can reuse that pattern

430
00:21:27,016 --> 00:21:28,316
to build the rest of the cells.

431
00:21:28,846 --> 00:21:31,006
So, if I know what one
piece of news looks

432
00:21:31,006 --> 00:21:32,946
like on the screen
it can replicate

433
00:21:32,946 --> 00:21:34,806
that for every piece of news.

434
00:21:35,236 --> 00:21:37,236
[ Pause ]

435
00:21:37,456 --> 00:21:41,336
This stuff-- I didn't use the
built-in table view controller.

436
00:21:41,336 --> 00:21:43,476
I took an existing
controller actually

437
00:21:43,536 --> 00:21:47,756
and there is a table
view control somewhere--

438
00:21:47,756 --> 00:21:49,136
there it is, somewhere
in this list.

439
00:21:50,506 --> 00:21:53,366
Just drag it in and then I
drag the table view cell in.

440
00:21:54,326 --> 00:21:56,046
I've got this.

441
00:21:56,366 --> 00:21:58,356
I'll set up with the
title in separately

442
00:21:58,506 --> 00:22:00,436
but that's not a big deal.

443
00:22:01,146 --> 00:22:02,786
If we look at some
of the properties

444
00:22:02,966 --> 00:22:04,096
of the Table view itself,

445
00:22:04,096 --> 00:22:09,986
I don't think I set any
properties for what I was doing.

446
00:22:10,146 --> 00:22:11,736
For the prototype cell-- this is

447
00:22:11,736 --> 00:22:13,586
where things got a
little more interesting.

448
00:22:14,586 --> 00:22:17,156
So, the first thing I had to
do is actually name this cell

449
00:22:17,156 --> 00:22:19,026
so you'll see this
is a new cell.

450
00:22:20,146 --> 00:22:21,946
So, in my code I can then say,

451
00:22:22,956 --> 00:22:25,396
"I want another new
cell to put news in.

452
00:22:25,396 --> 00:22:26,476
I want another new cell."

453
00:22:26,956 --> 00:22:29,886
You could have tables with
different types of cells.

454
00:22:30,306 --> 00:22:32,546
I don't know if a single table
could have more than one type

455
00:22:32,546 --> 00:22:34,496
of cell but if I
have multiple tables,

456
00:22:34,496 --> 00:22:36,746
those would certainly want
different types of data.

457
00:22:38,066 --> 00:22:41,766
This disclosure indicator
came from the accessory.

458
00:22:42,316 --> 00:22:44,346
I picked the one that looks
like a little gray arrow.

459
00:22:44,696 --> 00:22:49,556
There's one that has a
blue circle with an arrow.

460
00:22:50,246 --> 00:22:53,206
That generally-- it means if you
hit that button specifically,

461
00:22:53,206 --> 00:22:58,396
it will do something different
than if you hit the text.

462
00:22:58,396 --> 00:23:01,556
And there's one other whatever
you have-- oh, check mark.

463
00:23:01,706 --> 00:23:03,746
So, if you're doing some sort
of task list or something,

464
00:23:03,746 --> 00:23:05,246
that you could use that.

465
00:23:05,796 --> 00:23:09,446
I also dropped the cell on
and the one thing I had to do

466
00:23:09,446 --> 00:23:12,566
with the cell, so actually
I did a couple of things

467
00:23:12,566 --> 00:23:13,896
with the cells so we
can look at all these.

468
00:23:14,516 --> 00:23:19,496
[ Pause ]

469
00:23:19,996 --> 00:23:22,956
I chose for line
breaks truncate tail.

470
00:23:23,206 --> 00:23:26,016
So, basically what that does
is if there's too much text

471
00:23:26,016 --> 00:23:28,916
in this cell, at the very end
it will just do dot, dot, dot,

472
00:23:29,646 --> 00:23:31,256
which I thought was
useful for this project.

473
00:23:32,936 --> 00:23:36,566
Slightly up from there
I set lines to one.

474
00:23:37,446 --> 00:23:39,766
If I didn't have lines to
one, it would actually try

475
00:23:39,766 --> 00:23:41,436
to wrap the text and
do multiple lines

476
00:23:41,436 --> 00:23:44,556
so I could have used s
smaller font and set lines two.

477
00:23:44,816 --> 00:23:48,956
I could add two lines
of text there.

478
00:23:49,156 --> 00:23:52,516
The other thing I had
to do is I used a tag.

479
00:23:52,686 --> 00:23:55,956
So, I set my tag to one
just as an arbitrary number

480
00:23:56,166 --> 00:23:58,416
and I'm going to use
that later in the code

481
00:23:58,416 --> 00:24:00,056
to actually reference the cell.

482
00:24:00,586 --> 00:24:05,056
And I think that's
the quick tour

483
00:24:05,056 --> 00:24:06,906
of everything that's
in the story board.

484
00:24:08,236 --> 00:24:10,066
If we look at the actual
controller for this,

485
00:24:10,066 --> 00:24:11,976
so we're finally getting
down to the controllers.

486
00:24:12,326 --> 00:24:14,326
[ Pause ]

487
00:24:14,636 --> 00:24:16,196
We can look at the header first

488
00:24:16,506 --> 00:24:20,676
and there's really
not a whole lot here.

489
00:24:21,006 --> 00:24:22,456
Nothing-- nothing
too interesting.

490
00:24:22,456 --> 00:24:24,696
But one thing we do notice
is I've got some protocols

491
00:24:24,696 --> 00:24:25,166
setup here.

492
00:24:26,266 --> 00:24:29,356
So, chosen to use the
UI Table view delegate

493
00:24:30,206 --> 00:24:32,256
which basically gives
me added functionality

494
00:24:32,256 --> 00:24:33,506
around manipulating that table,

495
00:24:34,426 --> 00:24:37,406
and its cut off here
by UIWebViewDelegate.

496
00:24:37,636 --> 00:24:39,496
We don't have to
worry about that yet

497
00:24:39,876 --> 00:24:41,976
but we'll just remember
that's there for now.

498
00:24:42,516 --> 00:24:45,676
[ Pause ]

499
00:24:46,176 --> 00:24:48,976
The code gets a lot
more interesting now.

500
00:24:49,516 --> 00:24:53,836
[ Pause ]

501
00:24:54,336 --> 00:24:59,776
Let me see if I can
get this closer.

502
00:25:02,116 --> 00:25:02,546
There we go.

503
00:25:02,926 --> 00:25:04,256
So, I've got a few things.

504
00:25:04,256 --> 00:25:10,736
So, I've moved my-- what I'm
calling my private properties

505
00:25:11,176 --> 00:25:12,996
into the interface here.

506
00:25:13,806 --> 00:25:18,086
Certainly, we can do this is the
dot h file no matter what these

507
00:25:18,086 --> 00:25:21,236
properties will be
exposed to another object

508
00:25:21,236 --> 00:25:22,196
that knows about them.

509
00:25:22,956 --> 00:25:25,336
But I sort of like the idea
of when I get my header file

510
00:25:25,336 --> 00:25:27,336
to someone else, they
only know about the things

511
00:25:27,336 --> 00:25:28,536
that I want them to know about.

512
00:25:29,456 --> 00:25:30,476
So, I've included them here.

513
00:25:30,716 --> 00:25:31,596
I've got a few things.

514
00:25:31,596 --> 00:25:35,296
I've got my location which
is a location object--

515
00:25:35,296 --> 00:25:38,376
we saw that before, and my
news which is a news object,

516
00:25:38,766 --> 00:25:40,356
which we know will
then later be composed

517
00:25:40,356 --> 00:25:41,696
of news article objects.

518
00:25:42,176 --> 00:25:45,616
I've got two IBOutlets.

519
00:25:46,466 --> 00:25:49,026
One for the title, I
sort of gloss stuff

520
00:25:49,026 --> 00:25:51,816
that there was a title
at the top but obviously,

521
00:25:51,816 --> 00:25:54,116
if we want to change the
title, we need access to that,

522
00:25:55,186 --> 00:25:57,726
and access to modify
the table itself.

523
00:25:59,086 --> 00:26:00,296
Any surprises there so far?

524
00:26:01,666 --> 00:26:01,956
All right.

525
00:26:06,016 --> 00:26:08,816
We've got some standard
stuff when view loads--

526
00:26:09,896 --> 00:26:12,746
I create a new location with
my special singleton method

527
00:26:13,566 --> 00:26:15,326
which is probably
not a new location.

528
00:26:15,326 --> 00:26:16,326
It's probably the same location

529
00:26:16,326 --> 00:26:17,556
that someone else
already requested.

530
00:26:18,496 --> 00:26:20,596
And I allocate some
space for my news.

531
00:26:21,726 --> 00:26:26,726
I broke-- a part view will
appear from viewDidLoad just

532
00:26:26,726 --> 00:26:28,446
because they are
suddenly different.

533
00:26:29,056 --> 00:26:32,686
When the view loads, that's a
great place to do manipulation

534
00:26:32,686 --> 00:26:35,766
of your data to get things
into a configured state.

535
00:26:36,336 --> 00:26:39,016
When viewWillAppear
happens, that is great

536
00:26:39,016 --> 00:26:40,306
as the views about to appear.

537
00:26:40,556 --> 00:26:43,206
So, wait to that point of my
code to actually do my updates.

538
00:26:43,556 --> 00:26:45,636
And I've written a separate
method for that because I want

539
00:26:45,636 --> 00:26:47,086
to call that from
several places.

540
00:26:49,776 --> 00:26:53,796
You could, in theory call
viewWillAppear from other places

541
00:26:53,796 --> 00:26:56,686
in your code but it's really
poor practice so I've factored

542
00:26:56,686 --> 00:26:58,586
that out into its own method.

543
00:26:59,366 --> 00:27:01,366
[ Pause ]

544
00:27:01,716 --> 00:27:06,416
The update has this magical
news refresh complete block.

545
00:27:06,416 --> 00:27:08,366
We don't know if that is

546
00:27:08,366 --> 00:27:10,786
yet so we're not going
to worry about that.

547
00:27:10,856 --> 00:27:13,956
There's some stuff about
refreshing the location.

548
00:27:13,956 --> 00:27:17,366
We'll come back to that.

549
00:27:17,566 --> 00:27:20,836
Setting the title
doesn't seem too bad.

550
00:27:20,836 --> 00:27:23,196
We-- at some point, a zip
code is going to be set.

551
00:27:24,136 --> 00:27:28,006
We can set the title to news for
zip code or unknown zip code.

552
00:27:29,016 --> 00:27:31,996
But this is where things
start to get interesting.

553
00:27:31,996 --> 00:27:34,266
These are functions that
we don't normally see

554
00:27:34,266 --> 00:27:35,026
in our code, right?

555
00:27:35,026 --> 00:27:38,346
We've got number of sections
in table view, number of rows

556
00:27:38,346 --> 00:27:40,406
in sections, [inaudible]
index path.

557
00:27:40,976 --> 00:27:42,596
I knew we looked at
this quickly in lecture.

558
00:27:42,596 --> 00:27:47,586
Do you folks remember
what number of sections

559
00:27:47,586 --> 00:27:49,816
in table view does or
number of rows in section?

560
00:27:50,516 --> 00:27:52,546
[ Pause ]

561
00:27:53,046 --> 00:27:53,346
Ray [phonetic].

562
00:27:54,516 --> 00:28:03,036
[ Inaudible Remark ]

563
00:28:03,536 --> 00:28:04,716
>> Yes. The first
part of the answer--

564
00:28:04,716 --> 00:28:08,196
sections are groups and
I've got mine set to one

565
00:28:08,196 --> 00:28:09,986
which basically means
I just have one group

566
00:28:09,986 --> 00:28:10,886
for all my records.

567
00:28:12,126 --> 00:28:14,646
The other one was number
of rows and section.

568
00:28:16,096 --> 00:28:16,976
So, this is going to be--

569
00:28:17,516 --> 00:28:19,586
[ Inaudible Remark ]

570
00:28:20,086 --> 00:28:22,416
>> Yeah. The number of rows in
that section or in this case,

571
00:28:22,416 --> 00:28:24,336
the number of news articles
that I want to display.

572
00:28:24,806 --> 00:28:30,536
So, that will be as you might
read, my news articles count

573
00:28:31,546 --> 00:28:34,246
so this is another place
where I see the idea

574
00:28:34,246 --> 00:28:37,516
of using these classes,

575
00:28:37,516 --> 00:28:40,856
these models upfront gives you
some readability in your code.

576
00:28:40,856 --> 00:28:41,996
I sort of like the idea

577
00:28:41,996 --> 00:28:45,776
of return my news
articles, their count.

578
00:28:45,926 --> 00:28:48,496
That sort of reads to me
almost like a sentence.

579
00:28:48,966 --> 00:28:51,996
I don't know.

580
00:28:52,316 --> 00:28:52,966
It makes me happy.

581
00:28:53,516 --> 00:28:55,996
[ Pause ]

582
00:28:56,496 --> 00:29:01,246
For the actual cell at any
given row, it basically--

583
00:29:01,906 --> 00:29:05,696
I'm getting a call through
this delegate where it says,

584
00:29:06,376 --> 00:29:08,646
"I don't know what to put in
these cells as I create them."

585
00:29:08,826 --> 00:29:12,816
You tell me, for example row
three, what goes in row three?

586
00:29:13,146 --> 00:29:16,456
So, it comes to me and I say,
"OK, I will make you a cell

587
00:29:17,736 --> 00:29:25,596
that is a new cell and I'll
populate it by setting the--

588
00:29:26,346 --> 00:29:31,476
so, I will get my headline which
is my-- from my news articles,

589
00:29:31,636 --> 00:29:34,176
the object at index,
index path row.

590
00:29:34,176 --> 00:29:36,446
So, there's a lot things
going on right there

591
00:29:36,566 --> 00:29:37,856
but it's not too bad, right?

592
00:29:38,956 --> 00:29:40,956
We've been told I
want row number three

593
00:29:42,066 --> 00:29:45,956
so get me the news
article at index three

594
00:29:46,446 --> 00:29:47,836
which should be the
third news article.

595
00:29:48,436 --> 00:29:51,366
I'm just telling it
for sure that yes,

596
00:29:51,546 --> 00:29:52,866
this is going to
be a news article.

597
00:29:53,766 --> 00:30:00,616
And in news article,
I know has a headline.

598
00:30:01,546 --> 00:30:02,816
So, let's use that
as my headline.

599
00:30:03,626 --> 00:30:06,206
So, it's a lot in
one line of code,

600
00:30:06,666 --> 00:30:11,046
but hopefully it still make
sense what's going on there.

601
00:30:11,046 --> 00:30:13,236
Does-- do people sort of
get what that's doing?

602
00:30:13,456 --> 00:30:14,686
All right.

603
00:30:15,266 --> 00:30:19,246
And then find the
label in my cell,

604
00:30:19,376 --> 00:30:21,196
this is where I mentioned
I had to tag the cell.

605
00:30:21,836 --> 00:30:23,956
So, I find cell 1, tag 1.

606
00:30:24,496 --> 00:30:28,686
And then I can set for
that label, set the text

607
00:30:28,926 --> 00:30:33,616
to the headline I've just looked
up, and then return that cell.

608
00:30:34,136 --> 00:30:36,786
So, they've asked me what
does cell 3 look like, I say,

609
00:30:37,176 --> 00:30:39,376
"It's this cell with
this headline filled

610
00:30:39,376 --> 00:30:41,386
in here, here you go."

611
00:30:42,326 --> 00:30:43,406
Does that feel good to people?

612
00:30:44,476 --> 00:30:45,266
All right.

613
00:30:46,996 --> 00:30:49,746
The other side of that is, you
know, I click on these cells,

614
00:30:49,746 --> 00:30:51,506
I want the news to show up.

615
00:30:52,556 --> 00:30:54,686
We're not going to get
into this part yet,

616
00:30:55,496 --> 00:30:58,806
but upfront you can see that
an article for an object

617
00:30:58,806 --> 00:31:01,036
at index row also has a URL.

618
00:31:01,646 --> 00:31:05,836
I want to be able
to show that URL.

619
00:31:06,736 --> 00:31:10,776
And we'll get back to how I
actually did that shortly.

620
00:31:11,406 --> 00:31:16,066
Do people see how the table view
controller is roughly working?

621
00:31:16,186 --> 00:31:17,736
Those four methods
are sort of the core

622
00:31:17,736 --> 00:31:19,026
of what you need to know.

623
00:31:20,156 --> 00:31:24,486
How many sections, how many
rows, what's in each given row

624
00:31:24,616 --> 00:31:26,046
and what happens when
I click on a row.

625
00:31:26,706 --> 00:31:29,096
That's 90 percent of your
used case right there, right?

626
00:31:29,096 --> 00:31:30,746
All right.

627
00:31:31,516 --> 00:31:41,206
[ Pause ]

628
00:31:41,706 --> 00:31:43,796
So, let's jump to
the next topic.

629
00:31:44,276 --> 00:31:50,656
So, programmatical instantiation
which I just love typing out.

630
00:31:50,926 --> 00:31:52,736
It even comes up as
spelled wrong even

631
00:31:52,736 --> 00:31:53,886
if I swear that's
got to be right.

632
00:31:54,456 --> 00:31:56,656
It may not actually be a word.

633
00:31:56,656 --> 00:32:03,106
I could be making
things up at this point.

634
00:32:03,106 --> 00:32:07,446
So, when we quickly looked at
my story board, I don't know

635
00:32:07,446 --> 00:32:10,886
if you noticed but there was
nothing continuing on from here.

636
00:32:10,886 --> 00:32:13,076
When you got to the news
controller, that was it.

637
00:32:14,746 --> 00:32:17,816
But when you actually
click on a news article,

638
00:32:18,706 --> 00:32:21,826
this window pops up, the
web page renders like this,

639
00:32:22,036 --> 00:32:23,276
this is magically happening.

640
00:32:24,476 --> 00:32:25,936
Where does this come from?

641
00:32:26,476 --> 00:32:30,746
And this is the code we were
actually just looking at.

642
00:32:31,266 --> 00:32:34,826
Let's come back to this.

643
00:32:35,516 --> 00:32:37,636
[ Noise ]

644
00:32:38,136 --> 00:32:39,516
Shift my thumb by one.

645
00:32:39,856 --> 00:32:40,806
All right.

646
00:32:41,716 --> 00:32:43,026
So, how did I do that?

647
00:32:44,456 --> 00:32:47,936
Basically, I'm going
to build a web view

648
00:32:48,096 --> 00:32:49,496
because I want to
show web content.

649
00:32:49,856 --> 00:32:53,486
I'm going to build a controller
to put that web view in

650
00:32:53,946 --> 00:32:55,426
and then I'm actually
going to show

651
00:32:55,426 --> 00:32:56,476
that controller on the screen.

652
00:32:57,426 --> 00:33:00,196
So, on a very basic level, do
those three ideas make sense?

653
00:33:01,006 --> 00:33:03,806
Get the view, put in
controller, controller pops up.

654
00:33:04,536 --> 00:33:09,926
To do this, basically, all
the things I would've done

655
00:33:10,106 --> 00:33:11,996
in the gooey, I'm
doing here manually.

656
00:33:12,576 --> 00:33:14,666
So, I create a view,
so that's just the same

657
00:33:14,666 --> 00:33:16,846
as dragging one into the pane.

658
00:33:16,966 --> 00:33:20,426
I'm going to set the size to
the full size of the view.

659
00:33:20,476 --> 00:33:23,206
So, that's just going to
be as big as my screen.

660
00:33:23,756 --> 00:33:27,116
I'm going to set my
delegate to myself

661
00:33:27,616 --> 00:33:32,386
so I can send messages
back to this controller

662
00:33:33,456 --> 00:33:35,656
which is the same as
drawing, holding down control,

663
00:33:35,656 --> 00:33:37,956
dragging back to
the files owner.

664
00:33:38,536 --> 00:33:41,996
I'm going to set my
view.autoresizingMask.

665
00:33:42,316 --> 00:33:45,106
This is just something
that I found helpful.

666
00:33:45,176 --> 00:33:49,626
It makes sure that the
view is exactly the size--

667
00:33:50,176 --> 00:33:51,176
full size of the display.

668
00:33:51,406 --> 00:33:55,086
So, if I calculated my view run
before, this will stretch it

669
00:33:55,086 --> 00:33:57,686
down to make sure it fits.

670
00:33:57,836 --> 00:34:00,786
And this view, because it's a
web view, needs some content.

671
00:34:00,986 --> 00:34:04,086
And the way I do that and the
way you would do this even

672
00:34:04,086 --> 00:34:06,006
if you had created a web view

673
00:34:06,006 --> 00:34:09,966
in the interface builder
is just tell that view

674
00:34:09,966 --> 00:34:14,196
to load a request, it
needs an NSURL request,

675
00:34:14,746 --> 00:34:19,916
and the request is for a URL.

676
00:34:20,086 --> 00:34:26,246
So, we knew my URL is the
http:somenewsite/somearticle.

677
00:34:26,246 --> 00:34:30,186
I just passed that along to
load request in the view,

678
00:34:30,186 --> 00:34:32,126
will load that content
and deal with rendering

679
00:34:32,126 --> 00:34:33,226
and all the magic for me.

680
00:34:33,746 --> 00:34:35,896
Does that work good?

681
00:34:36,826 --> 00:34:40,546
Okay. The controller is this
wrapper that's actually going

682
00:34:40,546 --> 00:34:42,426
to handle everything else.

683
00:34:42,976 --> 00:34:44,206
And it's pretty straightforward.

684
00:34:44,206 --> 00:34:47,316
I'm just going to initiate
a new view controller.

685
00:34:47,886 --> 00:34:50,736
I don't have a nib file.

686
00:34:50,736 --> 00:34:52,846
I could have a nib
file but this is--

687
00:34:52,846 --> 00:34:55,786
I'm just creating one
dynamically out of nowhere

688
00:34:57,296 --> 00:34:58,586
and there's no content.

689
00:34:58,586 --> 00:35:00,346
This is just an empty
view controller.

690
00:35:00,926 --> 00:35:04,386
I'm setting the view to view.

691
00:35:04,466 --> 00:35:05,906
Let's see if I can get
that to scroll back.

692
00:35:06,516 --> 00:35:10,276
[ Pause ]

693
00:35:10,776 --> 00:35:14,016
Too far. But I'm setting
that controller's view

694
00:35:14,076 --> 00:35:17,406
to the view I created so
it knows to plug that in.

695
00:35:18,266 --> 00:35:22,506
I'm also setting a controller
navigation item left bar button

696
00:35:22,896 --> 00:35:25,866
to an init with bar
button systems.

697
00:35:27,596 --> 00:35:29,916
Basically, at the top
of that controller,

698
00:35:29,916 --> 00:35:31,096
you saw there's a title bar.

699
00:35:31,676 --> 00:35:33,616
A view controller will
have that title bar.

700
00:35:34,456 --> 00:35:36,806
I want that title bar to
have a done button in it.

701
00:35:36,896 --> 00:35:38,996
So, in the upper left,
there was a done button.

702
00:35:40,006 --> 00:35:44,926
That means my left bar
button item is a done button.

703
00:35:45,666 --> 00:35:47,116
It says, system item done.

704
00:35:48,036 --> 00:35:49,746
And what happens when
I hit that button?

705
00:35:50,356 --> 00:35:53,076
It's going to look to me as
the delegate to do something

706
00:35:53,186 --> 00:35:54,566
and that something that's
going to look for me

707
00:35:54,566 --> 00:35:59,066
to do is execute a method
called dismiss URL modal.

708
00:35:59,466 --> 00:36:01,956
This is how I think about it.

709
00:36:01,956 --> 00:36:03,456
It probably would
have been easier

710
00:36:03,456 --> 00:36:05,496
to call it close the window
or something like that,

711
00:36:05,496 --> 00:36:10,736
but we're dismissing the
URL view and it was modal,

712
00:36:10,736 --> 00:36:11,796
it was on top of the screen.

713
00:36:12,576 --> 00:36:14,606
I've probably been
doing this too long.

714
00:36:14,816 --> 00:36:19,246
Except for the naming
of that selector,

715
00:36:19,546 --> 00:36:20,516
does the idea make sense?

716
00:36:20,516 --> 00:36:23,566
I'm programmatically
creating a button in that bar

717
00:36:24,106 --> 00:36:27,446
on the left that
runs the method.

718
00:36:28,106 --> 00:36:28,746
All right.

719
00:36:29,136 --> 00:36:29,946
And-- yes?

720
00:36:30,516 --> 00:36:34,226
[ Inaudible Remark ]

721
00:36:34,726 --> 00:36:34,896
>> Yes.

722
00:36:35,381 --> 00:36:37,381
[ Inaudible Remark ]

723
00:36:37,746 --> 00:36:39,446
>> So, the question is
you can do all of this

724
00:36:39,446 --> 00:36:40,336
in interface builder, right?

725
00:36:41,016 --> 00:36:41,476
You could.

726
00:36:42,106 --> 00:36:46,316
There are times when interface
builder ends up being more work

727
00:36:47,046 --> 00:36:51,076
than you want or where it just
doesn't makes sense in general.

728
00:36:52,296 --> 00:36:56,196
So, this might not
be the ideal example,

729
00:36:56,516 --> 00:37:01,926
but let's say I wanted to, say,
make an array of 26 buttons

730
00:37:01,926 --> 00:37:03,386
with the letters
of the alphabet.

731
00:37:03,516 --> 00:37:05,296
I didn't want to drag them all

732
00:37:05,296 --> 00:37:07,516
onto display and
wire them all up.

733
00:37:08,346 --> 00:37:09,626
Things like that, Evil Hangman,

734
00:37:09,626 --> 00:37:12,306
you could have done those
buttons by creating a loop

735
00:37:12,836 --> 00:37:17,026
that looped and made 26
things for you and does it

736
00:37:17,026 --> 00:37:19,606
in a consistent way,
make sure that it gets A

737
00:37:19,606 --> 00:37:23,266
through Z specifically, they all
get the exact same properties,

738
00:37:23,266 --> 00:37:25,316
it's not copy-paste,
though I changed one now

739
00:37:25,316 --> 00:37:26,176
that they're out of sync.

740
00:37:26,946 --> 00:37:28,116
By doing it programmatically,

741
00:37:28,766 --> 00:37:33,736
you can do things more
consistently and do things

742
00:37:33,736 --> 00:37:36,016
that might not otherwise
be possible.

743
00:37:36,796 --> 00:37:39,296
So, actually, where
I do this at work,

744
00:37:40,016 --> 00:37:44,096
my company serves mobile
ads, we download the content,

745
00:37:44,096 --> 00:37:45,636
we create things on the fly

746
00:37:45,636 --> 00:37:47,526
and we dynamically
create the ad for you.

747
00:37:47,926 --> 00:37:50,496
So, that's the case where we
don't know what the content is

748
00:37:50,496 --> 00:37:55,266
going to be until it gets
downloaded to the device.

749
00:37:55,266 --> 00:37:55,976
You had a question?

750
00:37:56,516 --> 00:37:59,216
[ Inaudible Remark ]

751
00:37:59,716 --> 00:38:01,716
>> So, the question
is does it show

752
00:38:01,716 --> 00:38:03,356
up as a connection
in interface builder?

753
00:38:04,096 --> 00:38:05,266
It does not.

754
00:38:05,296 --> 00:38:07,786
So, interface builder
will create a nib file

755
00:38:08,056 --> 00:38:11,516
and the nib file will get
instantiated into your runtime.

756
00:38:12,826 --> 00:38:16,006
This code only exist at
runtime so it doesn't exist

757
00:38:16,006 --> 00:38:18,386
until you hit play
and it doesn't exist

758
00:38:18,386 --> 00:38:19,786
after you terminate
the application.

759
00:38:20,296 --> 00:38:22,266
So, there's no way
to like persist it.

760
00:38:22,266 --> 00:38:26,206
It's just a-- at runtime-created
state of the world.

761
00:38:26,206 --> 00:38:30,266
All right, any other questions?

762
00:38:30,946 --> 00:38:34,356
I think-- I think there's
only one last line here.

763
00:38:36,536 --> 00:38:40,976
So, the last bit is I'm
just allocating a navigation

764
00:38:40,976 --> 00:38:44,656
controller, initializing it
with the web view controller,

765
00:38:45,096 --> 00:38:47,736
and I'm saying animated so it
pops up live in the screen.

766
00:38:48,386 --> 00:38:49,846
But this is sort of
like template code,

767
00:38:49,846 --> 00:38:51,506
this is like how you do it.

768
00:38:52,096 --> 00:38:57,246
There wasn't anything
special about me doing that.

769
00:38:59,456 --> 00:39:01,826
There are few things
I schemed over.

770
00:39:03,146 --> 00:39:08,156
So, I mentioned, it's going to
callback through the delegate.

771
00:39:08,566 --> 00:39:10,886
This dismiss URL
modal, I've implement

772
00:39:10,946 --> 00:39:12,676
that because the
protocol says I will.

773
00:39:13,116 --> 00:39:15,846
The implied protocol
appears as I will do that

774
00:39:16,206 --> 00:39:18,536
and it's just going to
dismiss the view controller.

775
00:39:19,076 --> 00:39:21,776
The other things
I have down here,

776
00:39:21,776 --> 00:39:23,296
you don't necessarily need.

777
00:39:23,296 --> 00:39:27,406
I did it for completeness
because it's a table view.

778
00:39:28,026 --> 00:39:30,916
There's a method for can
edit row at index path.

779
00:39:31,346 --> 00:39:33,266
So, if you wanted to
have a list of things

780
00:39:33,266 --> 00:39:34,106
that someone could edit.

781
00:39:34,106 --> 00:39:37,716
So, we did a grocery list and
someone spelled eggs wrong.

782
00:39:37,716 --> 00:39:38,676
They only put one G in.

783
00:39:39,406 --> 00:39:40,896
And they want you
to edit that cell.

784
00:39:41,556 --> 00:39:44,016
This is how you would have to
implement that sort of content

785
00:39:44,016 --> 00:39:46,956
and it will give you a
pointer to the actual path

786
00:39:46,956 --> 00:39:48,526
and then you can think
about how you want

787
00:39:48,526 --> 00:39:49,696
to manipulate that content.

788
00:39:50,396 --> 00:39:56,086
The other one is can
move row at index path.

789
00:39:56,296 --> 00:39:59,036
Moving rows gets
potentially convoluted.

790
00:39:59,036 --> 00:40:01,426
If you're interested in it
and you're working on it

791
00:40:01,426 --> 00:40:03,006
in a project, I'm happy
to sit down with you.

792
00:40:03,766 --> 00:40:07,576
For this project, I said no,
you can't reorder the news.

793
00:40:08,186 --> 00:40:11,866
But if you had a to-do list, it
might be a useful thing to say,

794
00:40:12,266 --> 00:40:14,696
"This is now a higher
priority, I want to put

795
00:40:14,696 --> 00:40:16,616
that row above another round."

796
00:40:17,386 --> 00:40:20,826
And that's the start of how you
would start to promote that.

797
00:40:21,216 --> 00:40:23,356
You would say I'm turning
that functionality on

798
00:40:23,356 --> 00:40:26,636
and then I would have to
continue adding methods

799
00:40:26,676 --> 00:40:29,026
that implement those
parts of that protocol.

800
00:40:29,906 --> 00:40:32,936
Does that rough idea
makes sense?

801
00:40:32,936 --> 00:40:34,826
All right, moving right along.

802
00:40:35,516 --> 00:40:43,766
[ Pause ]

803
00:40:44,266 --> 00:40:46,066
So, blocks and callbacks.

804
00:40:46,556 --> 00:40:49,636
This is probably as much
as we showed you in lecture

805
00:40:50,126 --> 00:40:53,436
and it's the very rough syntax.

806
00:40:54,216 --> 00:40:56,106
I'm not going to spend a
huge amount of time here

807
00:40:56,106 --> 00:40:57,466
because it's probably
easier to see it

808
00:40:57,546 --> 00:41:01,696
with real syntax even though
there it probably will still

809
00:41:01,696 --> 00:41:02,596
look a little foreign.

810
00:41:03,826 --> 00:41:05,556
I more want you to know
that they are there,

811
00:41:06,656 --> 00:41:08,176
give you an example of
how they would work.

812
00:41:08,986 --> 00:41:11,746
You won't necessarily need to
use this anywhere in your code

813
00:41:12,106 --> 00:41:14,146
but I did find a few APIs

814
00:41:14,506 --> 00:41:17,756
where to get what I wanted
done, I had to do this.

815
00:41:18,086 --> 00:41:20,546
And this is the same
sort of idea as we used

816
00:41:20,546 --> 00:41:22,626
in our JavaScript, right?

817
00:41:22,806 --> 00:41:25,306
jQuery would go out, it
would create an Ajax request,

818
00:41:25,806 --> 00:41:27,826
it would go out to a site
to download some JSON,

819
00:41:27,826 --> 00:41:30,416
but we didn't know how
long that would take,

820
00:41:30,416 --> 00:41:31,206
when it would come back.

821
00:41:31,966 --> 00:41:36,826
So, we would actually set up
an anonymous block of code

822
00:41:36,826 --> 00:41:39,066
that would run at some
point in the future

823
00:41:39,526 --> 00:41:40,486
and then our method would end

824
00:41:40,486 --> 00:41:43,156
and this would eventually come
back and run this code for us.

825
00:41:43,916 --> 00:41:47,256
This is the same sort of idea,
I can set up a block of code

826
00:41:47,986 --> 00:41:50,066
and in my particular
examples, I'm using it

827
00:41:50,066 --> 00:41:51,716
for the same asynchronous case.

828
00:41:52,216 --> 00:41:55,026
I want to request the content
be downloaded from the internet

829
00:41:55,666 --> 00:41:58,506
and whenever that's done, I'm
going to leave you a block

830
00:41:58,506 --> 00:42:01,526
of code that will do
something with that data.

831
00:42:01,946 --> 00:42:04,986
So, in my case, when you
get the JSON back, hey,

832
00:42:04,986 --> 00:42:09,526
here is information and how you
turn that JSON into a property

833
00:42:09,526 --> 00:42:13,496
that is a zip code or a
property that is news articles

834
00:42:13,706 --> 00:42:15,496
or a property that is
weather information.

835
00:42:18,336 --> 00:42:22,096
The way these are syntactically
laid out is a lot--

836
00:42:22,226 --> 00:42:26,046
I find a lot more like
traditional C. We have some sort

837
00:42:26,046 --> 00:42:27,596
of return type, it
could be void.

838
00:42:27,996 --> 00:42:31,036
You have in parenthesis,
a caret and a name.

839
00:42:31,396 --> 00:42:33,816
So, this is sort of like
a function name vaguely

840
00:42:34,586 --> 00:42:37,906
and then you have a
list of parameter types.

841
00:42:38,656 --> 00:42:41,116
So, in a hello world
type of thing,

842
00:42:41,116 --> 00:42:44,526
you might have traditionally
seen void, hello world,

843
00:42:45,086 --> 00:42:47,296
and you might have
passed in your argc

844
00:42:47,296 --> 00:42:48,546
and argv something like that.

845
00:42:48,866 --> 00:42:53,826
That sort of maps into
the same sort of thing,

846
00:42:54,006 --> 00:42:55,196
they look more like this.

847
00:42:55,196 --> 00:42:58,596
So, you have, well, this is what
I'm actually going to do it,

848
00:42:58,596 --> 00:43:01,606
so I have a block type,
so I've created my--

849
00:43:02,796 --> 00:43:07,406
that should have been a block
type up here and give it a name

850
00:43:07,536 --> 00:43:12,246
and that is essentially
assigning a variable to code.

851
00:43:12,616 --> 00:43:16,476
Now, we're used to assigning
variables to an object

852
00:43:16,556 --> 00:43:18,536
or to an integer or
things like that.

853
00:43:18,576 --> 00:43:23,276
This expands that idea to the
idea that you can store blocks

854
00:43:23,276 --> 00:43:27,006
of code in a variable which
is kind of a neat idea.

855
00:43:27,216 --> 00:43:29,406
It's common in a lot
of other languages

856
00:43:29,916 --> 00:43:31,666
and it's a really
powerful concept.

857
00:43:31,836 --> 00:43:35,596
We've got perimeter types,
we've got perimeter names

858
00:43:35,596 --> 00:43:37,376
so whatever perimeter
names I give this,

859
00:43:37,666 --> 00:43:40,296
those are the variables
I have access to.

860
00:43:40,296 --> 00:43:44,966
So, you know, pram type
int, this is some sort

861
00:43:44,966 --> 00:43:49,636
of value X. I can then
manipulate that value X

862
00:43:49,996 --> 00:43:55,766
and return a value back to
wherever this block came from.

863
00:43:57,146 --> 00:43:59,016
>> What's the difference between
[inaudible] a new function?

864
00:44:00,346 --> 00:44:02,096
It is not as [inaudible].

865
00:44:02,366 --> 00:44:03,246
>> So, what's the difference

866
00:44:03,416 --> 00:44:05,926
between defining a new
function and defining a block?

867
00:44:06,856 --> 00:44:14,406
A function-- a function
can only exist

868
00:44:14,406 --> 00:44:17,046
in the space affronting
in, a block you can send

869
00:44:17,046 --> 00:44:20,766
to another scope and it will
run using its previous scope

870
00:44:21,686 --> 00:44:22,886
in that new location.

871
00:44:23,386 --> 00:44:27,066
>> So, basically like I said the
copy paste does interact just

872
00:44:27,066 --> 00:44:30,676
the same code you copy to
different places [inaudible]--

873
00:44:30,816 --> 00:44:32,866
>> Is it the same as copy paste?

874
00:44:32,866 --> 00:44:35,876
It's more a runtime
situation, so it's--

875
00:44:36,616 --> 00:44:42,666
I can write a function that
knows how to-- for example sort.

876
00:44:42,666 --> 00:44:47,096
If I have a function called
sort, I could say it's going

877
00:44:47,096 --> 00:44:50,596
to be passed A and B and
I could pass it a block.

878
00:44:51,426 --> 00:44:54,696
So, I could have
sort something--

879
00:44:55,326 --> 00:44:58,846
some set of values and tell
it how I'm going to sort those

880
00:44:58,846 --> 00:45:01,286
so I can create a block
that is alphabetical,

881
00:45:01,906 --> 00:45:06,916
reverse alphabetical and I could
pass the function, the values

882
00:45:07,086 --> 00:45:12,836
and the sorting method and that
same sort function would use the

883
00:45:12,836 --> 00:45:15,056
different block functionality
to do different things.

884
00:45:15,476 --> 00:45:16,506
Does that concept make sense?

885
00:45:17,136 --> 00:45:18,046
The sort of [inaudible]
with my idea

886
00:45:18,046 --> 00:45:18,976
in my head as I was talking.

887
00:45:19,516 --> 00:45:24,566
[ Inaudible Remark ]

888
00:45:25,066 --> 00:45:26,496
Yes, so this case I'm thinking

889
00:45:26,536 --> 00:45:32,186
about now is you could
tell a sort function,

890
00:45:32,186 --> 00:45:33,866
what sorting algorithm to use.

891
00:45:34,616 --> 00:45:38,796
You could have a function called
compress that takes some data

892
00:45:38,796 --> 00:45:42,156
and takes an algorithm and
that algorithm could be zip

893
00:45:42,156 --> 00:45:47,236
for zip files or uuencoding or
all sorts of different things.

894
00:45:47,236 --> 00:45:49,066
And then in the future,
if you wanted

895
00:45:49,066 --> 00:45:51,276
to add a new compression scheme,

896
00:45:51,836 --> 00:45:53,446
you would just create
the new block and pass it

897
00:45:53,446 --> 00:45:55,606
to the function and your
old code would be unchanged.

898
00:45:56,536 --> 00:45:59,916
>> Consider to something
like class [inaudible].

899
00:45:59,916 --> 00:46:01,926
>> It's similar to a class.

900
00:46:01,926 --> 00:46:04,836
You could potentially use
a class in similar ways.

901
00:46:04,836 --> 00:46:09,566
It's more of the idea that
you can package up that code

902
00:46:09,566 --> 00:46:13,086
and deliver an entire bit
of code to someone else.

903
00:46:13,526 --> 00:46:16,786
Yeah, the class would
be code and data

904
00:46:16,786 --> 00:46:19,756
so it could do a
similar sort of thing.

905
00:46:20,996 --> 00:46:24,436
The other big thing, I'll try
to-- if there's any things.

906
00:46:24,646 --> 00:46:29,566
I don't have any more good
answers, it does carry scope

907
00:46:29,566 --> 00:46:30,566
with it which is interesting.

908
00:46:30,966 --> 00:46:35,976
Well, let's take a look
at what this looks like,

909
00:46:36,986 --> 00:46:37,976
so we got the documentation--

910
00:46:38,516 --> 00:46:44,606
[ Inaudible Remark ]

911
00:46:45,106 --> 00:46:48,646
Yes, so the question is, is
it like passing a function

912
00:46:48,646 --> 00:46:51,216
in JavaScript and yeah, it's
the same sort of concept

913
00:46:51,216 --> 00:46:55,116
where you can pass
functions around there.

914
00:46:55,346 --> 00:46:57,226
Ruby [assumed spelling]
uses the same ideas,

915
00:46:57,226 --> 00:47:00,216
Liz [assumed spelling] uses the
same idea as we can use lambdas,

916
00:47:00,216 --> 00:47:03,696
things like that to
pass code around.

917
00:47:04,056 --> 00:47:08,176
All right, so this is the
second scariest code I will

918
00:47:08,176 --> 00:47:09,726
show tonight.

919
00:47:10,516 --> 00:47:16,196
[ Pause ]

920
00:47:16,696 --> 00:47:20,256
So, this was blocks.

921
00:47:20,696 --> 00:47:24,306
I put the storyboard there, I
don't think we actually need

922
00:47:24,486 --> 00:47:26,736
to look at the storyboard
for this.

923
00:47:26,736 --> 00:47:29,976
We can go right to news
view as an example.

924
00:47:30,516 --> 00:47:45,146
[ Pause ]

925
00:47:45,646 --> 00:47:47,636
So, here is the function
that we sort of schemed

926
00:47:47,636 --> 00:47:49,446
over before for update display.

927
00:47:50,826 --> 00:47:54,566
If we start-- if they ignore
that this block is created,

928
00:47:55,066 --> 00:47:59,566
it's going to set the
title as the first thing.

929
00:48:00,646 --> 00:48:08,006
It's going to check
if zip code is set.

930
00:48:08,996 --> 00:48:11,936
Why did I do that?

931
00:48:11,936 --> 00:48:14,616
I did that somewhere else.

932
00:48:14,896 --> 00:48:18,166
Yes, so it's getting--
locations are responsible

933
00:48:18,376 --> 00:48:19,386
for setting zip code.

934
00:48:19,966 --> 00:48:22,246
So, at this point if I
want to update my display,

935
00:48:22,856 --> 00:48:25,836
I need to know if the location
has actually found a zip code.

936
00:48:25,836 --> 00:48:28,416
So, first I ask location
A, do you have a zip code?

937
00:48:28,736 --> 00:48:35,896
If it does, I want the news to
refresh itself with the location

938
00:48:35,896 --> 00:48:41,226
that the zip code said and
this callback, news callback.

939
00:48:41,766 --> 00:48:44,876
So, I'm asking the news
model to do this for me

940
00:48:45,406 --> 00:48:50,606
and when it gets done, I
want you to run this code,

941
00:48:50,606 --> 00:48:53,266
news callback which
I have to find here.

942
00:48:53,396 --> 00:48:57,226
So, news callback is a news
refresh complete block,

943
00:48:57,716 --> 00:49:05,976
it's going to take-- it's going

944
00:49:05,976 --> 00:49:08,496
to pass me a parameter
of success.

945
00:49:08,896 --> 00:49:11,596
So, the news block, news
is going to call me,

946
00:49:12,056 --> 00:49:14,676
it's going to say,
"Hey, success was this."

947
00:49:17,176 --> 00:49:18,846
This is the sort of true case.

948
00:49:18,846 --> 00:49:22,116
If it was successful,
reload my data.

949
00:49:22,686 --> 00:49:27,536
Reload my data is basically just
going to ask the news object,

950
00:49:27,536 --> 00:49:28,906
hey, what's all the data.

951
00:49:30,776 --> 00:49:33,336
Does the idea make sense
that I am going to say,

952
00:49:34,496 --> 00:49:37,016
when you get done, run this
code and that code is--

953
00:49:37,816 --> 00:49:39,766
tell me if you are
successful and if

954
00:49:39,766 --> 00:49:40,816
so I'm going to rule
out my data.

955
00:49:40,816 --> 00:49:43,486
Does that basically make sense?

956
00:49:44,516 --> 00:49:52,896
[ Inaudible Remark ]

957
00:49:53,396 --> 00:49:58,036
>> So, this call back
I've specifically said

958
00:49:58,036 --> 00:50:00,976
for this function is going to be
a news refresh complete block.

959
00:50:01,826 --> 00:50:05,866
So, I specified that as the type
of data just like I've specified

960
00:50:05,866 --> 00:50:07,656
that this is going to
be a string, I think.

961
00:50:08,356 --> 00:50:11,256
>> So, can callback call
other type of things

962
00:50:11,986 --> 00:50:15,956
like callback and call function?

963
00:50:15,956 --> 00:50:19,746
>> Callbacks can only be of
the type that you specified.

964
00:50:19,926 --> 00:50:21,516
So, I defined a method signature

965
00:50:21,516 --> 00:50:22,836
for what these callbacks
will be.

966
00:50:23,336 --> 00:50:26,136
And that's because I
need to know things

967
00:50:26,136 --> 00:50:28,976
like this will pass success
as a [inaudible] to me.

968
00:50:29,516 --> 00:50:31,676
[ Pause ]

969
00:50:32,176 --> 00:50:37,366
So, let's see what's going
on in this news model

970
00:50:37,456 --> 00:50:38,686
to make this actually happen.

971
00:50:39,516 --> 00:50:45,796
[ Pause ]

972
00:50:46,296 --> 00:50:48,846
In news.h, I've defined

973
00:50:48,846 --> 00:50:52,966
that a news refresh
complete block is going

974
00:50:52,966 --> 00:50:55,696
to be given a parameter
of success,

975
00:50:56,556 --> 00:50:57,986
which is what we just
saw in that other code.

976
00:50:57,986 --> 00:51:00,186
So, it makes sense that
this exist as a thing.

977
00:51:00,256 --> 00:51:02,526
It also doesn't have a
return value, it's just void.

978
00:51:03,036 --> 00:51:04,746
Is that OK?

979
00:51:06,066 --> 00:51:06,516
OK.

980
00:51:07,516 --> 00:51:14,996
[ Pause ]

981
00:51:15,496 --> 00:51:17,026
And this is where
things get good.

982
00:51:18,456 --> 00:51:21,216
So, refresh with
location is going

983
00:51:21,216 --> 00:51:23,496
to take a string
for the location.

984
00:51:23,596 --> 00:51:27,316
So, that's going to be my zip
code, that 02140 as a string,

985
00:51:27,316 --> 00:51:29,826
something like that, and
that's going to take a callback

986
00:51:29,826 --> 00:51:32,496
of type news refresh
complete block

987
00:51:32,496 --> 00:51:35,686
which we just defined is call
the news professional complete

988
00:51:35,686 --> 00:51:38,806
block and it's going to pass
you a value called success

989
00:51:38,946 --> 00:51:41,976
that will be a Boolean.

990
00:51:42,136 --> 00:51:44,676
If I've got a location
and I'll just skim

991
00:51:44,676 --> 00:51:46,656
over how it knows
whether it has a location.

992
00:51:47,096 --> 00:51:54,436
It is going to do-- I'm sorry,
location was just 02140.

993
00:51:55,596 --> 00:51:58,486
So, my escape location
is going to be a string

994
00:51:58,586 --> 00:52:01,316
by replacing percent
escapes using encoding.

995
00:52:02,246 --> 00:52:05,456
So, this is the basic
idea that we saw

996
00:52:05,456 --> 00:52:07,996
in JavaScript before we
need to escape our strings

997
00:52:07,996 --> 00:52:09,576
or URI and code our strings.

998
00:52:09,986 --> 00:52:12,616
If I've passed into something
that has sketchy characters

999
00:52:12,616 --> 00:52:15,326
in it, I want you to
replace those with things

1000
00:52:15,326 --> 00:52:19,786
that I can send out to a
website as part of a URL.

1001
00:52:20,706 --> 00:52:25,956
So, if my string was actually
02140 dash, number, number,

1002
00:52:25,956 --> 00:52:29,156
number, number, that dash
would have been translated

1003
00:52:29,156 --> 00:52:32,176
to whatever the percent
to whatever character is

1004
00:52:32,176 --> 00:52:33,516
that was safe to
put over the wire.

1005
00:52:33,786 --> 00:52:34,986
That might not be
a good example.

1006
00:52:35,076 --> 00:52:36,366
Spaces are a good example.

1007
00:52:36,366 --> 00:52:39,026
If this was actually
accepting city names

1008
00:52:39,026 --> 00:52:42,776
and I wanted New space
York, then it would replace

1009
00:52:42,776 --> 00:52:44,696
that space with percent 20.

1010
00:52:45,636 --> 00:52:48,926
So, similar to what we saw
when we did this in JavaScript,

1011
00:52:49,616 --> 00:52:51,166
longer method name
but same idea.

1012
00:52:51,756 --> 00:52:54,666
I'm going to build up the string

1013
00:52:54,936 --> 00:52:57,366
and this string probably
looks very familiar.

1014
00:52:57,366 --> 00:53:00,326
We're going out to the
Yahoo APIs, we're using YQL,

1015
00:53:01,276 --> 00:53:03,976
we're doing a select of
the string that was built

1016
00:53:03,976 --> 00:53:06,326
up that's going out
news.google.com,

1017
00:53:06,816 --> 00:53:08,966
it's going to return
me some RSS.

1018
00:53:09,091 --> 00:53:11,091
[ Pause ]

1019
00:53:11,166 --> 00:53:15,016
I'm going to append
in my location.

1020
00:53:15,016 --> 00:53:17,706
So, I'm building this string
by appending pieces together.

1021
00:53:18,396 --> 00:53:21,076
So, after it says G-O
equals, it's going to put

1022
00:53:21,076 --> 00:53:24,126
in the 02140 in this case.

1023
00:53:24,126 --> 00:53:27,046
And at the very end, it's going
to include format equals JSON.

1024
00:53:28,046 --> 00:53:31,316
So, this was almost
probably identical

1025
00:53:31,316 --> 00:53:32,166
to what you were building

1026
00:53:32,166 --> 00:53:33,416
up when you built
your mobile local.

1027
00:53:33,996 --> 00:53:35,196
Does that look familiar?

1028
00:53:35,196 --> 00:53:36,766
Everybody remembers
that this happened?

1029
00:53:36,766 --> 00:53:40,146
And then, I'm going to
turn that into an NSURL

1030
00:53:41,436 --> 00:53:45,916
which is just how Objective-C
likes to talk about full URLs

1031
00:53:45,916 --> 00:53:47,766
and it's just going to build
that by taking that string

1032
00:53:47,766 --> 00:53:50,566
and turning it into whatever
data structure it needs.

1033
00:53:51,396 --> 00:53:56,036
I'm going to build a request off
of that which just takes the URL

1034
00:53:56,036 --> 00:53:58,836
and factors it up into
an actual HTTP request.

1035
00:53:59,126 --> 00:54:02,136
And then I'm going to
send it asynchronously.

1036
00:54:02,376 --> 00:54:05,146
So, I'm going to
send them my request.

1037
00:54:05,966 --> 00:54:11,856
I'm going to send it to the
main queue which is all we need

1038
00:54:11,856 --> 00:54:12,976
to know about at this time.

1039
00:54:14,036 --> 00:54:19,036
This came right out of template
code and you could just assume

1040
00:54:19,036 --> 00:54:23,876
that in this case, the main
queue is the main queue.

1041
00:54:24,066 --> 00:54:30,116
And this is going off the screen
so let's get a little more code.

1042
00:54:30,606 --> 00:54:32,406
And it's got a completion
handler.

1043
00:54:33,816 --> 00:54:34,776
By completion handler,

1044
00:54:34,776 --> 00:54:40,026
if you notice the caret again
is another block which is going

1045
00:54:40,026 --> 00:54:44,656
to apparently have parameters
of response, data and error.

1046
00:54:45,116 --> 00:54:49,956
So, I need to run-- I
need to give it the code

1047
00:54:49,956 --> 00:54:51,456
to run when it gets done.

1048
00:54:51,936 --> 00:54:53,726
So, we've now got a
block inside of a block.

1049
00:54:54,576 --> 00:54:56,396
But this one we sort
of done anonymously,

1050
00:54:56,396 --> 00:55:00,896
the last one we said was a
news block completion handler

1051
00:55:00,896 --> 00:55:01,526
or something like that.

1052
00:55:01,526 --> 00:55:05,166
I had a name type, it was well
structured, we knew what it was.

1053
00:55:05,426 --> 00:55:07,816
Here, this is anonymous.

1054
00:55:07,816 --> 00:55:11,886
It's just-- these are the
parameters I can expect back.

1055
00:55:11,946 --> 00:55:14,506
I don't have to create
a block externally

1056
00:55:14,506 --> 00:55:16,166
and assign it to variable.

1057
00:55:16,796 --> 00:55:18,186
I can just build one on the fly.

1058
00:55:19,516 --> 00:55:25,056
[ Pause ]

1059
00:55:25,556 --> 00:55:27,356
So, it's got its types,

1060
00:55:27,356 --> 00:55:30,596
it's actually got its
own pair of curly braces.

1061
00:55:31,156 --> 00:55:34,056
So, you see the square
brackets were still inside one

1062
00:55:34,056 --> 00:55:35,056
giant message.

1063
00:55:35,886 --> 00:55:38,996
One of the parameters I happen
to be passing in is this block

1064
00:55:39,426 --> 00:55:41,156
which has this code
as part of it.

1065
00:55:42,126 --> 00:55:46,386
So, it gets visually a little
weird to look at having blocks

1066
00:55:46,386 --> 00:55:48,776
of code inside my whole
message and everything.

1067
00:55:49,876 --> 00:55:51,886
But basically, the code is
simple when we look at it.

1068
00:55:52,026 --> 00:55:56,626
I'm going to get back some sort
of JSON data that I'm storing

1069
00:55:56,626 --> 00:55:58,696
in a dictionary called
JSON payload.

1070
00:56:00,106 --> 00:56:04,636
We are going to basically
take the data that we got

1071
00:56:06,296 --> 00:56:09,116
and we are going to use
this JSON serialization

1072
00:56:09,116 --> 00:56:11,496
to parse it into a dictionary.

1073
00:56:13,436 --> 00:56:15,346
So, it's doing all
the magic for me.

1074
00:56:15,346 --> 00:56:18,736
It says, here's your
data, mash it up,

1075
00:56:19,906 --> 00:56:21,596
here's my new value
JSON payload.

1076
00:56:22,146 --> 00:56:24,706
And I am going to
call the callback--

1077
00:56:25,516 --> 00:56:28,576
[ Pause ]

1078
00:56:29,076 --> 00:56:31,336
I'm going to give--
I'm going-- all right.

1079
00:56:32,026 --> 00:56:34,136
So, now, that's the
things in a very weird way.

1080
00:56:34,206 --> 00:56:37,416
So, I'm going to take
that payload and send it

1081
00:56:37,416 --> 00:56:39,696
to my method called
process payload.

1082
00:56:40,256 --> 00:56:41,836
That's going to return a Boolean

1083
00:56:41,836 --> 00:56:43,576
that I can pass back
as the callback.

1084
00:56:44,306 --> 00:56:48,516
So, if this method succeeds,
that other piece of code

1085
00:56:48,736 --> 00:56:51,036
over in my controller
will know that, hey,

1086
00:56:51,036 --> 00:56:51,966
new data is available.

1087
00:56:51,966 --> 00:56:55,646
If it doesn't succeed, it will
know that it shouldn't bother

1088
00:56:55,646 --> 00:56:58,156
to update display because
there's no other data.

1089
00:56:59,896 --> 00:57:01,866
This is some of the
really scary code tonight.

1090
00:57:02,426 --> 00:57:04,306
How does that roughly feel?

1091
00:57:04,306 --> 00:57:06,756
Does the basic idea make sense?

1092
00:57:07,066 --> 00:57:10,216
I mean, its like inception at
this point, we get the dream

1093
00:57:10,216 --> 00:57:12,156
within the dream,
blocks going everywhere,

1094
00:57:12,156 --> 00:57:13,796
code jumping around, yeah?

1095
00:57:15,516 --> 00:57:21,406
[ Inaudible Remark ]

1096
00:57:21,906 --> 00:57:24,026
Sure, so the syntax
of the pipe here.

1097
00:57:24,846 --> 00:57:28,916
So, basically, Options
is expecting a value

1098
00:57:29,716 --> 00:57:34,206
which is some sort of probably
giant number essentially.

1099
00:57:35,116 --> 00:57:37,466
And these are flags.

1100
00:57:38,316 --> 00:57:41,606
But they are basically just two
values and this is a binary or.

1101
00:57:42,386 --> 00:57:45,316
So, if this was the number two
and this was the number one,

1102
00:57:45,376 --> 00:57:47,466
I or them together, I get the
number three and I've built

1103
00:57:47,466 --> 00:57:51,166
up some sort of bit patterns
probably what really is being

1104
00:57:51,166 --> 00:57:51,646
used here.

1105
00:57:52,216 --> 00:57:55,226
Does that make sense?

1106
00:57:55,396 --> 00:57:59,016
People are comfortable
that if they had to,

1107
00:57:59,016 --> 00:58:04,316
they could unravel
this close enough.

1108
00:58:04,756 --> 00:58:07,346
Yeah, OK. So, the last part,

1109
00:58:07,346 --> 00:58:10,266
we go ask over was how
is it actually processing

1110
00:58:10,266 --> 00:58:10,846
this payload.

1111
00:58:11,366 --> 00:58:14,976
And that's kind of important.

1112
00:58:15,516 --> 00:58:18,236
[ Pause ]

1113
00:58:18,736 --> 00:58:22,306
So, that is just this function
which expects a dictionary,

1114
00:58:22,686 --> 00:58:25,186
returns yes or no for
whether it was successful.

1115
00:58:25,616 --> 00:58:31,016
And if you remember the data
structure, and I won't blame you

1116
00:58:31,016 --> 00:58:32,276
if you don't, for mobile local,

1117
00:58:32,276 --> 00:58:36,796
when we go out to the Google
News API, its got query

1118
00:58:36,796 --> 00:58:39,506
at the first level, results
at the level under that,

1119
00:58:39,716 --> 00:58:42,346
item under that, and then each

1120
00:58:42,346 --> 00:58:47,216
of the items is it's own little
dictionary that has a title,

1121
00:58:47,606 --> 00:58:50,026
a link, probably a
bunch of other stuff

1122
00:58:50,026 --> 00:58:51,136
that I don't really care about.

1123
00:58:52,096 --> 00:58:55,256
Can you sort of visualize how
that maps back to that data set?

1124
00:58:56,286 --> 00:58:56,846
All right, cool.

1125
00:58:57,866 --> 00:59:00,436
So, I am basically just
unraveling the layers

1126
00:59:00,436 --> 00:59:01,366
of that data here.

1127
00:59:01,886 --> 00:59:04,276
And the reason I broke it
out like this is to try

1128
00:59:04,276 --> 00:59:06,546
to do error handling which
as we saw at the beginning

1129
00:59:06,546 --> 00:59:08,136
of this night, apparently
still doesn't work

1130
00:59:08,216 --> 00:59:09,786
but I'm getting there.

1131
00:59:10,246 --> 00:59:12,246
[ Pause ]

1132
00:59:12,476 --> 00:59:15,296
So, we check for the query
object and forget that.

1133
00:59:15,426 --> 00:59:17,936
We go to the result
object, we get that.

1134
00:59:17,936 --> 00:59:20,296
We go to the items object,
we're finally at a level

1135
00:59:20,296 --> 00:59:22,526
where we've got data where
we want to work with.

1136
00:59:23,196 --> 00:59:26,676
For each item which is an NS
dictionary in that collection

1137
00:59:26,676 --> 00:59:31,126
of items, I can go through
and get the headline

1138
00:59:31,126 --> 00:59:33,486
out and set that-- sorry.

1139
00:59:33,856 --> 00:59:36,386
Yeah, get the headline
out, store that temporarily

1140
00:59:36,386 --> 00:59:40,646
for the title, create a URL
from the link and store that.

1141
00:59:41,176 --> 00:59:44,926
And then I can add to
my news, because we're--

1142
00:59:45,516 --> 00:59:47,776
[ Pause ]

1143
00:59:48,276 --> 00:59:53,466
Yeah, I can add an article
which is an allocation

1144
00:59:53,466 --> 00:59:56,176
of an article initialized
with a heading URL.

1145
00:59:56,796 --> 01:00:02,456
So, I take this news article,
build it up and then use--

1146
01:00:02,586 --> 01:00:05,876
I've got an ad article function
below that takes my news object

1147
01:00:05,936 --> 01:00:07,976
and depends that to
my list of news items.

1148
01:00:08,356 --> 01:00:11,146
I've got a little gray there.

1149
01:00:11,146 --> 01:00:12,276
Does that make sense?

1150
01:00:13,096 --> 01:00:14,646
This is just another
method I've got written

1151
01:00:14,646 --> 01:00:17,286
down at the bottom of my code.

1152
01:00:18,476 --> 01:00:18,686
All right.

1153
01:00:19,336 --> 01:00:21,346
So, if you were actually
doing something

1154
01:00:21,346 --> 01:00:23,816
where you're reparsing
JSON data, this is the kind

1155
01:00:23,816 --> 01:00:28,256
of template you can sort of cut
and paste from my code and work

1156
01:00:28,256 --> 01:00:31,946
with to get data from
some external service.

1157
01:00:34,876 --> 01:00:39,226
The actual add article
function is not super exciting.

1158
01:00:39,926 --> 01:00:42,756
If I don't have any articles
or I don't have an object

1159
01:00:42,756 --> 01:00:45,096
for the articles yet, I'm
just going to create one

1160
01:00:45,096 --> 01:00:46,706
by allocating initializing
array.

1161
01:00:46,986 --> 01:00:50,176
And once I've got it, I'm
just adding the new article

1162
01:00:50,176 --> 01:00:53,976
to the end of the list.

1163
01:00:53,976 --> 01:00:55,236
All right.

1164
01:00:55,436 --> 01:00:55,976
We're almost through it.

1165
01:00:56,516 --> 01:01:04,396
[ Pause ]

1166
01:01:04,896 --> 01:01:07,906
Whether is going to look exactly
the same, the code is going

1167
01:01:07,906 --> 01:01:09,896
to be mostly cut
and paste all over.

1168
01:01:09,896 --> 01:01:11,716
So, I wasn't going through that.

1169
01:01:12,646 --> 01:01:13,566
And four more slides.

1170
01:01:14,316 --> 01:01:15,446
So, core location.

1171
01:01:17,516 --> 01:01:20,976
[ Pause ]

1172
01:01:21,476 --> 01:01:24,046
You remember this
dot is moving around

1173
01:01:24,156 --> 01:01:27,696
and it's automatically
doing the reverse look

1174
01:01:27,696 --> 01:01:29,026
up in finding me a zip code.

1175
01:01:29,026 --> 01:01:31,406
And I'm just going
to show that portion

1176
01:01:31,406 --> 01:01:32,936
of how I did the
reverse geocode.

1177
01:01:33,476 --> 01:01:38,226
So, this is all in our
location controller.

1178
01:01:39,516 --> 01:01:46,496
[ Pause ]

1179
01:01:46,996 --> 01:01:50,686
Just looking quickly
at the header,

1180
01:01:50,686 --> 01:01:52,946
you'll see I've got
two imports here.

1181
01:01:52,946 --> 01:01:54,866
So, I've got core
location and Map Kit.

1182
01:01:55,556 --> 01:02:00,396
I also had to include this in--
I should show you that as well--

1183
01:02:01,046 --> 01:02:02,526
core location of Map
Kit that I include.

1184
01:02:03,356 --> 01:02:06,956
And the only thing in here
really is the actual MapView is

1185
01:02:06,956 --> 01:02:08,206
a Map Kit MapView.

1186
01:02:08,206 --> 01:02:15,776
The other place that I had to
include this is when you go

1187
01:02:15,776 --> 01:02:27,946
to your targets and go to-- what
I get-- targets and build faces.

1188
01:02:29,836 --> 01:02:32,696
We don't worry much about
this section in this class

1189
01:02:33,286 --> 01:02:36,626
but it's important to know that
you can link with libraries.

1190
01:02:36,796 --> 01:02:41,246
And a lot of the magic
we're getting for free

1191
01:02:41,366 --> 01:02:44,266
that Apple's provided for us
comes from these libraries.

1192
01:02:45,126 --> 01:02:47,166
You remember the
foundation.framework?

1193
01:02:47,166 --> 01:02:48,406
We use to see that all the time.

1194
01:02:49,386 --> 01:02:52,416
I've had it specifically
that I want Map Kit support

1195
01:02:52,536 --> 01:02:54,286
and I want core location
support.

1196
01:02:55,516 --> 01:02:59,426
There are all sorts of other
choices, you can get access

1197
01:02:59,426 --> 01:03:03,066
to the accelerometer,
address book, audio,

1198
01:03:03,576 --> 01:03:07,126
all the really cool
prepackage functionality,

1199
01:03:07,126 --> 01:03:08,236
the APIs that you need.

1200
01:03:09,116 --> 01:03:10,576
This is where you're
going to get them

1201
01:03:11,066 --> 01:03:13,146
if you do not have them
included by default.

1202
01:03:13,756 --> 01:03:15,366
I don't know if anybody
has got to a point

1203
01:03:15,366 --> 01:03:16,576
where they've had to this yet.

1204
01:03:16,706 --> 01:03:19,196
But if you haven't,
that would be helpful.

1205
01:03:19,746 --> 01:03:25,976
If we look at the code
for what we're doing here.

1206
01:03:26,516 --> 01:03:31,476
[ Pause ]

1207
01:03:31,976 --> 01:03:35,746
We will roll a little bit.

1208
01:03:36,906 --> 01:03:41,076
You see, one of the properties
I'd created was a core location

1209
01:03:41,076 --> 01:03:45,446
geocoder, just a convenient
place to store, I'm going to use

1210
01:03:45,726 --> 01:03:47,346
in couple places of my code.

1211
01:03:48,196 --> 01:03:51,116
As my view is loading, I'm
actually going to allocate that

1212
01:03:51,116 --> 01:03:54,026
and initialize it so it's
just available when I need it.

1213
01:03:55,496 --> 01:04:00,656
But where does this
actually start coming in?

1214
01:04:00,736 --> 01:04:03,646
I've made myself-- I didn't
point it out explicitly

1215
01:04:03,646 --> 01:04:07,886
but I made myself a delegate
of the Map Kit MapView.

1216
01:04:07,996 --> 01:04:10,946
So, there's a protocol for
that that gives me like the set

1217
01:04:10,946 --> 01:04:13,196
of tables your control
or additional methods

1218
01:04:13,196 --> 01:04:14,346
that I can choose to implement.

1219
01:04:14,856 --> 01:04:15,986
The one that I chose

1220
01:04:15,986 --> 01:04:19,976
to implement is this MapView
did update user location

1221
01:04:20,836 --> 01:04:23,516
and it will tell
me which MapView

1222
01:04:24,406 --> 01:04:27,576
and what my new location
is, which is perfect,

1223
01:04:27,576 --> 01:04:28,716
that's exactly what
I'm looking for.

1224
01:04:29,146 --> 01:04:33,876
What I did with the
geocoder is I do a reversed

1225
01:04:33,876 --> 01:04:35,016
geocode location.

1226
01:04:35,986 --> 01:04:38,666
From the MapView I can
get my explicit location,

1227
01:04:41,726 --> 01:04:42,916
scroll over to the right here.

1228
01:04:44,046 --> 01:04:48,826
And we get to this completion
handler again where it's going

1229
01:04:48,826 --> 01:04:50,946
to pass me an NSArray--

1230
01:04:51,516 --> 01:04:55,586
[ Pause ]

1231
01:04:56,086 --> 01:04:58,446
-- of place marks and
something for errors.

1232
01:04:58,966 --> 01:05:01,676
So, we're back to this idea
of blocks and callbacks again.

1233
01:05:02,476 --> 01:05:06,736
So, this callback, it
says, when you've figured

1234
01:05:06,736 --> 01:05:09,906
out where my location or when
you're don reverse geocoding my

1235
01:05:10,246 --> 01:05:14,346
location, give me a list
of placements in any errors

1236
01:05:14,796 --> 01:05:16,266
and I can look at
those placements,

1237
01:05:17,026 --> 01:05:26,026
actually do a center map on this
location not just refreshes my

1238
01:05:26,026 --> 01:05:26,726
display for me.

1239
01:05:26,856 --> 01:05:27,986
So, the dot has been moving.

1240
01:05:28,266 --> 01:05:30,526
This is what actually makes
the map move underneath the dot

1241
01:05:30,976 --> 01:05:32,976
and that's just a method
I have right below here.

1242
01:05:33,526 --> 01:05:39,886
But the actual geocode--
reverse geocoding is--

1243
01:05:40,506 --> 01:05:43,216
my zip code is going to be
look at the first place mark

1244
01:05:44,036 --> 01:05:45,606
and just tell me what
the postal code was.

1245
01:05:46,876 --> 01:05:49,846
So, this place mark array
that its handed back is a list

1246
01:05:49,846 --> 01:05:55,006
of things that map to that
latitude and longitude.

1247
01:05:55,106 --> 01:05:56,626
I'm just using the first one.

1248
01:05:57,196 --> 01:05:59,456
You can get other things
other than zip code.

1249
01:05:59,456 --> 01:06:00,926
There is things like
street address,

1250
01:06:00,966 --> 01:06:03,936
approximate street address,
at least city, state,

1251
01:06:04,236 --> 01:06:05,826
things like that,
all the information,

1252
01:06:05,826 --> 01:06:07,686
it knows about that
latitude and longitude.

1253
01:06:08,276 --> 01:06:14,426
I just needed the zip code
and if it happened to get one,

1254
01:06:14,816 --> 01:06:18,006
if my function was successful,
I'm going to update this--

1255
01:06:18,626 --> 01:06:20,086
what we member was a singleton,

1256
01:06:20,086 --> 01:06:23,966
a shared locations zip
code to the current value.

1257
01:06:24,436 --> 01:06:27,066
So, now, that's globally
available across my application.

1258
01:06:27,926 --> 01:06:30,276
And I'm going to tell
it to update the display

1259
01:06:30,886 --> 01:06:34,166
which if you remember pretty
much just updates my title bar

1260
01:06:34,166 --> 01:06:35,326
to have the zip code in it now.

1261
01:06:35,326 --> 01:06:35,486
All right.

1262
01:06:35,766 --> 01:06:38,546
And we're back.

1263
01:06:39,866 --> 01:06:44,776
So, the question, we'll just
ask is-- next question--

1264
01:06:45,126 --> 01:06:47,886
oh, the code is available
up on GitHub as I mentioned

1265
01:06:47,886 --> 01:06:48,936
at the start of the slides.

1266
01:06:49,816 --> 01:06:52,326
If you download the code
now and try to run it,

1267
01:06:52,416 --> 01:06:54,756
there are two things that
are moved from the code.

1268
01:06:54,896 --> 01:06:59,696
One is the images that I'm
using for the weather icons,

1269
01:07:00,106 --> 01:07:02,256
those are from Weather
Underground.

1270
01:07:02,256 --> 01:07:05,496
You can get them by searching
for Weather Ground API icon sets

1271
01:07:06,216 --> 01:07:08,346
or it should automatically
fell over

1272
01:07:08,346 --> 01:07:10,736
and pull them off the
internet as needed.

1273
01:07:12,136 --> 01:07:14,986
The other thing that's missing
is a weather underground API key

1274
01:07:15,216 --> 01:07:17,726
which is freely available
from their API site as well.

1275
01:07:18,286 --> 01:07:20,976
Go in, create an account,
they will give you a code

1276
01:07:20,976 --> 01:07:23,836
that you can plug in
and it is at the top

1277
01:07:23,836 --> 01:07:31,416
of location.m. No,
at the top of--

1278
01:07:32,516 --> 01:07:36,556
[ Pause ]

1279
01:07:37,056 --> 01:07:37,896
It's probably weather.

1280
01:07:41,716 --> 01:07:46,166
At the top of weather.m, you can
provide your own API key here.

1281
01:07:46,166 --> 01:07:51,506
So, uncomment this
and fill in the blank.

1282
01:07:53,516 --> 01:07:56,906
The reason that I don't need to
do that is I actually cheated.

1283
01:07:57,206 --> 01:07:59,646
Oh, I didn't cheat--
I did the way--

1284
01:07:59,756 --> 01:08:05,436
things the way I would
expect developers

1285
01:08:05,436 --> 01:08:08,146
to actually do them
for the longer term.

1286
01:08:09,276 --> 01:08:13,646
In your project build settings,
we saw all these stuff.

1287
01:08:14,346 --> 01:08:15,916
You probably haven't
looked through it.

1288
01:08:15,916 --> 01:08:18,376
You probably never
needed to look through it

1289
01:08:18,376 --> 01:08:19,796
and you may never need
to look through it again.

1290
01:08:20,346 --> 01:08:29,746
But, I've set up preprocessing
directives for the bug.

1291
01:08:29,956 --> 01:08:31,836
Normally, it just says
the bug equals one.

1292
01:08:32,696 --> 01:08:33,786
If you look beyond here,

1293
01:08:33,926 --> 01:08:37,306
I've actually added a
weather underground API key

1294
01:08:37,306 --> 01:08:39,576
and it's valued directly
in here, so,

1295
01:08:39,626 --> 01:08:42,866
it's configured external
to my code.

1296
01:08:44,176 --> 01:08:46,176
In theory, you could then--

1297
01:08:46,176 --> 01:08:48,046
if you're building this from
the command line you can plug

1298
01:08:48,046 --> 01:08:50,236
that code in on the fly rather

1299
01:08:50,236 --> 01:08:52,556
than having it permanently
embedded in your project.

1300
01:08:52,556 --> 01:08:55,256
So, it's just a nice
way to do things

1301
01:08:55,256 --> 01:08:59,546
when you are committing
things publicly in one place--

1302
01:08:59,756 --> 01:09:01,806
the one place but have
private secrets you need

1303
01:09:01,806 --> 01:09:03,246
to keep somewhere else.

1304
01:09:05,176 --> 01:09:07,046
Probably not a big
deal for this course

1305
01:09:07,086 --> 01:09:11,136
but in the professional
coding world,

1306
01:09:11,206 --> 01:09:12,676
things like that
actually become important.

1307
01:09:12,966 --> 01:09:13,146
All right.

1308
01:09:14,236 --> 01:09:19,166
We were looking at--
where are we again?

1309
01:09:19,276 --> 01:09:22,986
What were we looking at?

1310
01:09:26,096 --> 01:09:27,406
Core Location.

1311
01:09:28,516 --> 01:09:33,216
[ Pause ]

1312
01:09:33,716 --> 01:09:37,556
I don't think there's
anything else--

1313
01:09:38,026 --> 01:09:40,206
were there other
questions on what I did

1314
01:09:40,206 --> 01:09:41,986
with the reverse geocoding?

1315
01:09:42,356 --> 01:09:42,626
All right.

1316
01:09:43,956 --> 01:09:45,286
I'm going to move on.

1317
01:09:45,286 --> 01:09:46,746
I want to get to office errors.

1318
01:09:47,516 --> 01:09:51,556
[ Pause ]

1319
01:09:52,056 --> 01:09:53,146
All right.

1320
01:09:53,326 --> 01:09:54,646
Two more topics and we're done.

1321
01:09:55,366 --> 01:09:58,296
First one is storyboard
constraints.

1322
01:09:58,756 --> 01:10:03,506
So, I mentioned that when
you rotate the device,

1323
01:10:04,396 --> 01:10:06,096
you don't necessarily
want things to be laid

1324
01:10:06,096 --> 01:10:07,886
out in the exact same
way that they were.

1325
01:10:10,706 --> 01:10:14,346
So, here, this one is
rather straight forward,

1326
01:10:14,346 --> 01:10:15,506
everything is full screen.

1327
01:10:16,436 --> 01:10:19,016
When I rotate the device,
everything is still full screen.

1328
01:10:21,836 --> 01:10:24,546
Likewise, news has built

1329
01:10:24,546 --> 01:10:27,246
in graceful handling
of what to deal.

1330
01:10:28,696 --> 01:10:30,736
Weather got interesting now.

1331
01:10:32,356 --> 01:10:37,896
By default, interface builder
doesn't know how I want

1332
01:10:37,896 --> 01:10:40,946
to rearrange stuff when I
change the orientation here.

1333
01:10:42,176 --> 01:10:44,676
If I didn't do anything, it
would try to take all the stuff,

1334
01:10:44,986 --> 01:10:47,956
squish it up and have lots
of white space on the side.

1335
01:10:48,536 --> 01:10:50,656
And I didn't think that
was particularly useful.

1336
01:10:51,246 --> 01:10:55,376
So, I came up with this which
is I think is a lot more

1337
01:10:55,376 --> 01:10:59,656
interesting, still required zero
lines of code and was all done

1338
01:10:59,656 --> 01:11:00,536
through interface builder

1339
01:11:00,866 --> 01:11:03,326
which I thought was
actually kind of neat.

1340
01:11:03,916 --> 01:11:05,996
And if you look at
it, you can sort

1341
01:11:05,996 --> 01:11:07,666
of tease part what I'm doing.

1342
01:11:08,316 --> 01:11:10,606
You can see that
the sun is still

1343
01:11:10,606 --> 01:11:13,806
in the same location
relative to here.

1344
01:11:14,236 --> 01:11:17,956
And the temperatures are still

1345
01:11:17,956 --> 01:11:20,066
in their location
relative to over here.

1346
01:11:21,426 --> 01:11:25,356
I didn't do upside
down of your phone.

1347
01:11:25,956 --> 01:11:31,966
So, this still works
and this still works.

1348
01:11:32,216 --> 01:11:34,596
And this actually is still
under the sun when I rotate.

1349
01:11:35,326 --> 01:11:38,996
But it's too far down on
the screen and gets it.

1350
01:11:39,346 --> 01:11:41,816
I was OK with that they got
the burning on one screen,

1351
01:11:41,816 --> 01:11:44,386
so that was pretty good.

1352
01:11:44,666 --> 01:11:46,546
So, how does this
actually happen?

1353
01:11:52,996 --> 01:11:56,636
All right, when you build
things in storyboards

1354
01:11:56,776 --> 01:12:01,326
and you drop things
on, remember,

1355
01:12:01,536 --> 01:12:02,876
like if I drop the button on,

1356
01:12:03,396 --> 01:12:05,636
you start to get
these little helpers.

1357
01:12:06,256 --> 01:12:10,056
There's a line here,
there's a line there.

1358
01:12:10,676 --> 01:12:17,006
If I drop something in the
lower right corner here,

1359
01:12:17,346 --> 01:12:20,416
we know that we're a certain
distance from the right

1360
01:12:20,416 --> 01:12:21,756
of the screen and
certain distance

1361
01:12:21,756 --> 01:12:22,766
from the bottom of the screen.

1362
01:12:23,556 --> 01:12:28,076
But how does interface builder
know whether this is relative

1363
01:12:28,076 --> 01:12:31,666
to the top of the screen, or
relative to where it's going

1364
01:12:31,666 --> 01:12:35,526
to show my temperature
or what's going on here?

1365
01:12:35,526 --> 01:12:37,416
How does it know what
to glue things to?

1366
01:12:38,036 --> 01:12:46,946
If you come over here
in the size inspector,

1367
01:12:50,776 --> 01:12:53,546
you'll see it's got this
idea of constraints.

1368
01:12:54,586 --> 01:12:56,386
And right now, it's
saying that this,

1369
01:12:56,426 --> 01:12:58,116
we see this little
blue strut here

1370
01:12:58,116 --> 01:12:59,376
and this little blue strut here,

1371
01:13:00,166 --> 01:13:03,406
it's saying that the trailing
space, so the space to the right

1372
01:13:03,406 --> 01:13:07,336
of the bottom is
relative to the super view

1373
01:13:07,556 --> 01:13:08,936
and it equals the default.

1374
01:13:09,526 --> 01:13:12,256
So, I want the edge
of the screen

1375
01:13:12,256 --> 01:13:14,706
and give me the default space
from the side of that screen.

1376
01:13:15,956 --> 01:13:18,826
Likewise bottom, it says it's
relative to the super view

1377
01:13:19,156 --> 01:13:20,266
and the default space there.

1378
01:13:21,946 --> 01:13:31,416
If instead, I had put this for
example here, they'll say, "OK.

1379
01:13:31,486 --> 01:13:37,036
I think what you want is
your top space compared

1380
01:13:37,036 --> 01:13:41,406
to the image view which is this
little line here, this default

1381
01:13:41,866 --> 01:13:45,786
and you're going to be
center aligned on this label.

1382
01:13:46,326 --> 01:13:48,306
I would have thought it
would have guess centered

1383
01:13:48,306 --> 01:13:52,206
on the screen but it also
happens to be centered

1384
01:13:52,206 --> 01:13:54,146
on the temperature of that time.

1385
01:13:54,146 --> 01:13:56,496
So, let's come up with that
as the possible constraints.

1386
01:13:57,376 --> 01:14:00,086
So, that is a valid possibility.

1387
01:14:00,606 --> 01:14:04,186
But what I can do is also
do other constraints.

1388
01:14:04,506 --> 01:14:08,156
So, there's this little toolbar
down here, little hard to see,

1389
01:14:08,586 --> 01:14:12,966
we've got alignment options,

1390
01:14:13,616 --> 01:14:17,056
struck options and
resizing options.

1391
01:14:17,626 --> 01:14:21,256
So, for example, if this button
should be the same distance

1392
01:14:21,256 --> 01:14:25,716
from the bottom of the screen
every time, I can have a struck

1393
01:14:25,766 --> 01:14:28,936
that is bottom spaced
to super view.

1394
01:14:31,676 --> 01:14:38,616
So, now this button has--
should have three constraints.

1395
01:14:38,616 --> 01:14:42,276
So, now it has three
constraints.

1396
01:14:43,056 --> 01:14:45,286
The purple ones are
the ones that--

1397
01:14:45,286 --> 01:14:49,136
it has come up with on its own
and it thinks have to be in.

1398
01:14:49,136 --> 01:14:52,516
There's no-- you haven't
given that any other criteria,

1399
01:14:52,976 --> 01:14:55,116
so it's doing the best I can.

1400
01:14:55,336 --> 01:14:59,486
The blue ones are ones that you
can manipulate and are the ones

1401
01:14:59,486 --> 01:15:00,946
that you have already
created yourself.

1402
01:15:02,046 --> 01:15:04,926
So, it's still keeping
track of the distance here,

1403
01:15:05,186 --> 01:15:06,316
and the distance here,

1404
01:15:07,696 --> 01:15:10,456
but if this button is really
only relative to the bottom

1405
01:15:10,456 --> 01:15:13,006
of the screen I don't need
this top constraint anymore.

1406
01:15:13,616 --> 01:15:15,716
And because it's blue
I can actually go ahead

1407
01:15:16,196 --> 01:15:18,096
and delete that.

1408
01:15:18,676 --> 01:15:22,436
And now, all it knows is that
the button is centered compared

1409
01:15:22,436 --> 01:15:24,806
to this label in this
distance from the button

1410
01:15:24,806 --> 01:15:25,976
of the screen all the time.

1411
01:15:26,516 --> 01:15:30,076
[ Pause ]

1412
01:15:30,576 --> 01:15:34,176
So, if we look at something
like my temperature,

1413
01:15:35,116 --> 01:15:37,616
you'll see I've got a fixed
width and a fixed height,

1414
01:15:37,956 --> 01:15:39,826
so that gives it part
of the constraints.

1415
01:15:40,636 --> 01:15:46,246
And I've specifically said
that the right edge should line

1416
01:15:46,246 --> 01:15:47,806
up with the right edge of this,

1417
01:15:48,796 --> 01:15:55,246
and the bottom spacing should
be relative to as this as well.

1418
01:15:55,246 --> 01:15:58,076
So, this location, the
Fahrenheit is based

1419
01:15:58,076 --> 01:15:58,976
on the location of the Celsius.

1420
01:15:59,111 --> 01:16:01,111
[ Pause ]

1421
01:16:01,206 --> 01:16:01,976
The Celsius--

1422
01:16:02,516 --> 01:16:04,806
[ Pause ]

1423
01:16:05,306 --> 01:16:07,236
-- is actually a
certain distance

1424
01:16:07,236 --> 01:16:08,436
from the bottom of the screen.

1425
01:16:09,196 --> 01:16:12,396
And I think there might be one
other constraint on that one.

1426
01:16:12,586 --> 01:16:15,426
Yeah. And it also
knows its distance

1427
01:16:15,426 --> 01:16:16,446
from the side of the screen.

1428
01:16:17,716 --> 01:16:22,236
So, iOS can figure out
how far up to put this,

1429
01:16:22,376 --> 01:16:24,906
how far over to put this,
and then once it knows

1430
01:16:24,906 --> 01:16:26,306
where this is it
can figure out where

1431
01:16:26,306 --> 01:16:27,866
to put the temperature
relative to that,

1432
01:16:28,266 --> 01:16:29,996
so they end up stuck
on top of each other.

1433
01:16:30,606 --> 01:16:33,396
And it can sort of extrapolate
this idea and see that, oh,

1434
01:16:33,396 --> 01:16:36,586
this UI image view was going to
pinned to the left in the top.

1435
01:16:37,306 --> 01:16:42,246
And we can see that that has
a fixed width, a fixed height,

1436
01:16:43,216 --> 01:16:46,226
formal spacing here,
formal spacing there.

1437
01:16:46,476 --> 01:16:47,966
I'll let you play with
that more but does

1438
01:16:47,966 --> 01:16:49,306
that basic idea make sense

1439
01:16:49,306 --> 01:16:52,046
of how you glue things
relative to other things?

1440
01:16:53,036 --> 01:16:56,616
Cool. So, the last
thing I want to talk

1441
01:16:56,616 --> 01:16:59,836
about is the one I find most
interesting but it's the end

1442
01:16:59,836 --> 01:17:02,706
of my talk and it's probably the
most boring to everyone else.

1443
01:17:03,016 --> 01:17:04,106
[ Inaudible Remark ]

1444
01:17:04,106 --> 01:17:05,526
Oh yeah, question.

1445
01:17:06,516 --> 01:17:11,556
[ Inaudible Remark ]

1446
01:17:12,056 --> 01:17:14,536
So, this-- so the
question is if you switch

1447
01:17:14,536 --> 01:17:17,376
to landscape view do you have
to respecify the constraints?

1448
01:17:17,696 --> 01:17:17,836
>> Yeah.

1449
01:17:18,836 --> 01:17:20,726
>> The-- and the answer is no.

1450
01:17:21,016 --> 01:17:24,146
The constraints are always
the constraints and based

1451
01:17:24,146 --> 01:17:27,476
on whatever geometry of
screen it gets it will build

1452
01:17:27,796 --> 01:17:29,386
as best it can with that layout.

1453
01:17:30,246 --> 01:17:32,246
[ Inaudible Remark]

1454
01:17:32,476 --> 01:17:35,026
I don't think I can switch
it in interface builder.

1455
01:17:35,376 --> 01:17:38,836
I've only been able to switch
it, if you got a thought on how

1456
01:17:38,836 --> 01:17:40,686
to do that I'd be
happy to try it but.

1457
01:17:41,166 --> 01:17:44,066
>> So, how do it know what it
looks like when I [inaudible]?

1458
01:17:44,596 --> 01:17:46,126
>> So, the only way I
found to know what it looks

1459
01:17:46,126 --> 01:17:48,706
like when you switch it is to
run your app and switch it.

1460
01:17:49,026 --> 01:17:50,156
There's got to be a better way.

1461
01:17:50,746 --> 01:17:52,806
I saw some articles
on stock overflow

1462
01:17:52,806 --> 01:17:56,396
that were basically titled how
do I re-orientate my storyboard

1463
01:17:56,396 --> 01:17:57,396
in interface builder?

1464
01:17:57,656 --> 01:18:00,496
I wasn't finding a good
way to do it, but I'm happy

1465
01:18:00,496 --> 01:18:04,276
to look into it further.

1466
01:18:04,356 --> 01:18:06,766
Any other questions
on constraints?

1467
01:18:07,486 --> 01:18:10,096
>> But when you switch why
the logo just disappear?

1468
01:18:10,586 --> 01:18:11,926
>> So, the question is

1469
01:18:11,926 --> 01:18:13,976
when I switch why does
the logo disappear?

1470
01:18:14,546 --> 01:18:17,656
The reason is I've made the
image view a fixed height

1471
01:18:17,896 --> 01:18:20,196
and I made the logo appear
under the image view.

1472
01:18:21,126 --> 01:18:23,626
And the amount of
space that this takes

1473
01:18:23,626 --> 01:18:25,516
up is too much for the screen.

1474
01:18:25,516 --> 01:18:29,736
So, the screen bottom bar
here is just overlapping

1475
01:18:30,356 --> 01:18:33,316
and this is pushed off
bigger than the screen fits.

1476
01:18:34,046 --> 01:18:36,996
As an extrapolation if I took
the same geometry and dropped it

1477
01:18:36,996 --> 01:18:38,806
on like an iPad that
would probably end

1478
01:18:38,806 --> 01:18:40,636
up with something crammed up
over here and something way

1479
01:18:40,636 --> 01:18:43,926
down here, it would be
kind of a diagonal display.

1480
01:18:44,286 --> 01:18:48,436
So, the last thing I want
to show you is unit test.

1481
01:18:48,436 --> 01:18:51,576
And very few people get
excited about testing

1482
01:18:51,576 --> 01:18:53,486
but I think it's one
of the most powerful

1483
01:18:53,486 --> 01:18:54,646
and interesting things
we can do.

1484
01:18:54,916 --> 01:18:57,896
And they don't look
that difference.

1485
01:18:58,266 --> 01:19:01,106
So, this basically
looks like header files,

1486
01:19:01,106 --> 01:19:02,296
we've seen everywhere
else, right?

1487
01:19:02,296 --> 01:19:04,366
I've got my mobile local test.

1488
01:19:04,366 --> 01:19:07,916
They happen to be of this class
type which is a send test case,

1489
01:19:08,986 --> 01:19:11,776
but that could have in
other cases been as simple

1490
01:19:11,776 --> 01:19:14,436
as UIViewController or
something like that.

1491
01:19:14,436 --> 01:19:16,266
We've seen this basic
structure before.

1492
01:19:17,836 --> 01:19:21,386
The method file is going
to look a little different

1493
01:19:21,386 --> 01:19:23,266
but not much different.

1494
01:19:24,236 --> 01:19:26,146
I've moved by interface
here again,

1495
01:19:26,416 --> 01:19:27,856
and I've got a property
for weather.

1496
01:19:27,856 --> 01:19:30,256
So, I'm going to instantiate
a weather object to some point

1497
01:19:30,866 --> 01:19:36,646
and I've got three methods, set
up, tear down, and my example.

1498
01:19:39,016 --> 01:19:42,306
So, set up is sort of
like how we've been using

1499
01:19:42,306 --> 01:19:42,576
[inaudible] load.

1500
01:19:42,576 --> 01:19:44,686
It's the first thing that's
going to happen, and it's going

1501
01:19:44,686 --> 01:19:46,966
to create whatever
variables I need for my tests,

1502
01:19:47,576 --> 01:19:49,606
so to do whatever
the super class says,

1503
01:19:49,606 --> 01:19:51,976
and let me get in here.

1504
01:19:52,526 --> 01:19:55,436
And in this case all it's going

1505
01:19:55,436 --> 01:19:57,546
to do is allocate a
new weather object.

1506
01:19:59,216 --> 01:20:02,066
Tear down would be if I
needed to tear anything

1507
01:20:02,066 --> 01:20:03,336
down in this case I don't,

1508
01:20:03,816 --> 01:20:07,276
but let's say you were using
some sort of local storage

1509
01:20:07,276 --> 01:20:09,326
in someway where you
created some test records

1510
01:20:09,666 --> 01:20:11,836
at the end you want to
delete those test records.

1511
01:20:12,426 --> 01:20:13,926
You could use the
tear down methods

1512
01:20:13,926 --> 01:20:17,486
to undo whatever
you've done there.

1513
01:20:17,796 --> 01:20:21,596
And then the mid of it
is this test example.

1514
01:20:22,156 --> 01:20:26,746
So, I'm going to create
some helper stuff here,

1515
01:20:26,746 --> 01:20:28,586
but I'll create an
NSDateFormatter

1516
01:20:29,106 --> 01:20:31,676
that basically makes
a date out of an hour.

1517
01:20:31,996 --> 01:20:36,316
And what I'm going to be
testing here is this concept

1518
01:20:36,316 --> 01:20:37,146
of is night [phonetic].

1519
01:20:37,436 --> 01:20:41,646
So, we haven't necessarily seen
it yet, but at nighttime instead

1520
01:20:41,646 --> 01:20:44,196
of a sunny sun up on the display

1521
01:20:44,196 --> 01:20:46,456
and clear weather you'll
actually get a moon.

1522
01:20:46,746 --> 01:20:49,896
And the way I did that
is it says from 7 p.m.

1523
01:20:49,896 --> 01:20:53,926
to 7 a.m. that's considered
nighttime and from 7 a.m.

1524
01:20:53,926 --> 01:20:56,126
to 7 p.m. is then
daytime and I can switch

1525
01:20:56,126 --> 01:20:58,736
between my icons that way.

1526
01:20:58,926 --> 01:21:00,796
Well, how do I know that
actually working other

1527
01:21:00,796 --> 01:21:03,746
than trying to set all times
of day which is not practical,

1528
01:21:03,746 --> 01:21:05,316
I don't have 24 hours
to do my testing.

1529
01:21:06,636 --> 01:21:11,626
What I can do is I'm creating a
quick array just 'cause I wanted

1530
01:21:11,626 --> 01:21:16,606
to try a number of things at
once of 19, so at 7 o'clock,

1531
01:21:16,606 --> 01:21:19,466
8 o'clock, 6 a.m,
these are all things

1532
01:21:19,466 --> 01:21:22,666
that should be nighttime
according to my app.

1533
01:21:23,166 --> 01:21:25,936
And there are all things
that touch near the boundary.

1534
01:21:25,986 --> 01:21:28,936
I know 7 is the magic number,
but I want to make sure

1535
01:21:28,936 --> 01:21:32,886
that 6 a.m. is nighttime
and 7 a.m. is daytime,

1536
01:21:32,886 --> 01:21:39,076
and 8 a.m. is daytime, likewise
6 p.m. is daytime as soon

1537
01:21:39,076 --> 01:21:40,826
as it hits 7 p.m. that
is definitely nighttime,

1538
01:21:40,826 --> 01:21:42,566
and then of course 8 p.m.
is nighttime as well.

1539
01:21:43,506 --> 01:21:45,926
So, I set up some test
conditions for night.

1540
01:21:46,016 --> 01:21:50,846
So, I'm just creating as
NSDate based on that hour.

1541
01:21:51,866 --> 01:21:53,456
And then, this is
the actual magic.

1542
01:21:54,226 --> 01:21:56,516
I'm asserting that
this will be true.

1543
01:21:57,426 --> 01:22:00,886
If weather is night is called
with any of these times,

1544
01:22:02,166 --> 01:22:03,826
that should be true, right?

1545
01:22:03,826 --> 01:22:06,066
This is what nighttime is
defined in my application.

1546
01:22:07,436 --> 01:22:11,396
And just for my own description
it is night when hour is blank.

1547
01:22:11,396 --> 01:22:14,456
So, if the test fails I know
what test was being run is

1548
01:22:14,456 --> 01:22:16,226
night, when hours whatever.

1549
01:22:17,296 --> 01:22:25,416
Likewise, I can repeat that same
bit of code for 7 a.m., 8 a.m.,

1550
01:22:25,416 --> 01:22:28,846
6 p.m. and these are days,
so I'm going to assert

1551
01:22:29,586 --> 01:22:32,266
that is night going
to be false this time.

1552
01:22:32,416 --> 01:22:34,666
And there number of different
assertions, you can check

1553
01:22:34,666 --> 01:22:37,166
for null, you can check if
things that are exceptions.

1554
01:22:38,226 --> 01:22:39,776
True and false is
a nice easy one.

1555
01:22:42,016 --> 01:22:43,306
Theoretically, I could comeback

1556
01:22:43,306 --> 01:22:46,116
and say what happens
if we pass in null.

1557
01:22:46,706 --> 01:22:47,616
Oh, you have a question?

1558
01:22:47,716 --> 01:22:50,336
>> Yeah, is the reasons that's
been showing a sun so far

1559
01:22:50,476 --> 01:22:52,776
because it is like in
a different location?

1560
01:22:53,366 --> 01:22:55,216
>> Yes, the reason
this been showing a sun

1561
01:22:55,216 --> 01:22:59,226
so far is the zip codes
happen to be either Western--

1562
01:23:00,866 --> 01:23:02,046
Pacific or Mountain Time.

1563
01:23:02,046 --> 01:23:02,856
I don't know which but yeah,

1564
01:23:03,186 --> 01:23:06,746
we haven't quite hit 7 p.m.
according to the app yet.

1565
01:23:08,436 --> 01:23:11,386
So, I got my test, theoretically
I could say, you know,

1566
01:23:11,386 --> 01:23:13,156
what is the case for null,

1567
01:23:13,306 --> 01:23:17,076
like I actually don't know
what their function should do

1568
01:23:17,076 --> 01:23:17,586
in that case.

1569
01:23:17,586 --> 01:23:18,686
Maybe you should
throw an exception

1570
01:23:18,686 --> 01:23:20,726
because that doesn't
make any sense.

1571
01:23:21,416 --> 01:23:23,786
It can only return
a Boolean value.

1572
01:23:23,786 --> 01:23:28,106
So, if I give a time
of null is that true?

1573
01:23:28,316 --> 01:23:30,236
Four is night, is it
false first night?

1574
01:23:30,236 --> 01:23:31,026
I don't know.

1575
01:23:31,026 --> 01:23:33,506
But I could write the next test

1576
01:23:34,456 --> 01:23:38,606
that tells it what it thinks the
situation should be and then see

1577
01:23:38,756 --> 01:23:40,126
if it's doing what
I think it does.

1578
01:23:41,136 --> 01:23:45,186
And using this test is
actually really easy.

1579
01:23:45,366 --> 01:23:48,216
So, we've been using
the run button.

1580
01:23:49,576 --> 01:23:52,476
There is a tiny little arrow
next to the run button.

1581
01:23:52,946 --> 01:23:55,236
So, if you hold down run it's
actually a drop down menu,

1582
01:23:55,236 --> 01:23:59,646
and it's a simple as just
using test at this point.

1583
01:23:59,646 --> 01:24:00,466
And I would build my app.

1584
01:24:01,436 --> 01:24:03,516
It will tell me I still
have my assimilator open

1585
01:24:03,516 --> 01:24:04,526
and it wants to use it.

1586
01:24:05,516 --> 01:24:07,796
[ Pause ]

1587
01:24:08,296 --> 01:24:12,636
So let me put that, it
still knows I'm testing.

1588
01:24:12,776 --> 01:24:13,696
I run my test again.

1589
01:24:14,181 --> 01:24:16,181
[ Pause ]

1590
01:24:16,346 --> 01:24:17,896
It will pop-up assimilator.

1591
01:24:19,366 --> 01:24:23,146
And apparently nothing
happen, but that is not true.

1592
01:24:23,266 --> 01:24:26,416
It said finish testing,
no issues.

1593
01:24:27,116 --> 01:24:31,206
So, in this case life was good.

1594
01:24:31,546 --> 01:24:35,726
If I change my test and
I said rather than 7

1595
01:24:35,726 --> 01:24:42,166
and 8 p.m. being nighttime,
if I said that was also false,

1596
01:24:43,426 --> 01:24:45,326
my function is going
to return true.

1597
01:24:45,456 --> 01:24:46,686
I'm expecting false.

1598
01:24:47,516 --> 01:24:50,266
[ Pause ]

1599
01:24:50,766 --> 01:24:53,376
And for those three
conditions it's going to say no.

1600
01:24:53,376 --> 01:24:58,276
These are the failures that
you saw when you run your test.

1601
01:24:58,396 --> 01:25:02,906
So, I can go in and
see whether is night,

1602
01:25:02,906 --> 01:25:06,926
night should be false is
night was one hour is six.

1603
01:25:07,836 --> 01:25:11,676
So, I can quickly
see these things

1604
01:25:12,746 --> 01:25:15,646
and know how my functions
are testing

1605
01:25:15,646 --> 01:25:17,106
without having to
run the whole app.

1606
01:25:17,106 --> 01:25:19,736
I can do all sorts
of automated stuff.

1607
01:25:20,126 --> 01:25:24,956
So, you know, if I refactor my--
is night method to do something

1608
01:25:24,956 --> 01:25:26,896
in slightly different
way I can see

1609
01:25:26,896 --> 01:25:28,916
if it's still working the
same way as it work before.

1610
01:25:29,846 --> 01:25:32,716
One of the great approaches
to development is the idea

1611
01:25:32,716 --> 01:25:34,036
of test driven development.

1612
01:25:34,446 --> 01:25:37,976
We actually write all your test
first before you write any code,

1613
01:25:38,706 --> 01:25:40,906
so you know what-- how
things are supposed to work

1614
01:25:41,196 --> 01:25:42,866
and then you make
code to make it work.

1615
01:25:43,756 --> 01:25:47,406
Sometimes it's called red, green
testing where everything starts

1616
01:25:47,406 --> 01:25:49,386
out red, because you run
the test and there's no code

1617
01:25:49,386 --> 01:25:52,656
and it's broken, and you
continually work towards getting

1618
01:25:52,656 --> 01:25:55,056
green and as tester green
you get to the point

1619
01:25:55,056 --> 01:25:57,086
where everything
is green and then

1620
01:25:57,256 --> 01:26:01,516
in theory your code does exactly
what you thought it was going

1621
01:26:02,056 --> 01:26:03,036
to do.

1622
01:26:03,276 --> 01:26:05,656
So, does the basic idea
of testing makes sense

1623
01:26:05,776 --> 01:26:07,926
on how you could actually
implement some test?

1624
01:26:08,281 --> 01:26:10,281
[ Pause ]

1625
01:26:10,546 --> 01:26:10,966
All right.

1626
01:26:10,966 --> 01:26:12,456
So, that was everything
I have tonight.

1627
01:26:12,456 --> 01:26:13,626
I'm sorry we've gone so long.

1628
01:26:13,626 --> 01:26:14,486
It's 8 o'clock now.

1629
01:26:15,026 --> 01:26:18,646
But we'll wrap things up and
shift over to office hours

1630
01:26:18,646 --> 01:26:19,976
and we'll get you some
help with your projects.

1631
01:26:20,606 --> 01:26:21,266
Thank you so much.

1632
01:26:21,266 --> 01:26:21,976
I really appreciate it.

1633
01:26:22,516 --> 01:26:26,516
[ Applause ]

1634
01:26:27,016 --> 01:26:31,736
[ Silence ]

