1
00:00:00,506 --> 00:00:07,306
[Silence]

2
00:00:07,806 --> 00:00:08,366
>> Chris Gerber: Welcome.

3
00:00:08,736 --> 00:00:12,196
My name is Chris Gerber
and this is CS 76.

4
00:00:12,656 --> 00:00:14,076
Tonight we'll be doing Lab 2.

5
00:00:14,076 --> 00:00:17,786
We're going to start off with a
walkthrough of the next project

6
00:00:17,866 --> 00:00:19,076
which is Evil Hangman.

7
00:00:24,936 --> 00:00:29,126
So we'll start out with an
overview of the project.

8
00:00:29,406 --> 00:00:31,316
We're going to talk about
the equivalence classes

9
00:00:31,316 --> 00:00:33,966
which are sort of key to how
Evil Hangman is going to work.

10
00:00:35,016 --> 00:00:37,266
We'll talk about setting up
the project, how we're going

11
00:00:37,266 --> 00:00:40,796
to get input in the application,
how we can use property lists

12
00:00:40,796 --> 00:00:44,456
within the project and finish
up with just a little bit

13
00:00:44,456 --> 00:00:46,536
about how you can store
setting in your application.

14
00:00:47,106 --> 00:00:50,466
So first of all, Evil Hangman.

15
00:00:50,766 --> 00:00:55,886
The goal of the game is to
try to make the player lose

16
00:00:55,946 --> 00:00:56,876
and the way we're going to do

17
00:00:56,876 --> 00:00:59,236
that is we're just
going to cheat.

18
00:00:59,446 --> 00:01:03,616
How we're going to cheat is
after each guess we're going

19
00:01:03,616 --> 00:01:06,886
to select the longest
possible list of words

20
00:01:07,936 --> 00:01:11,246
that is still available
after that guess.

21
00:01:11,856 --> 00:01:13,856
This will make more
sense as we get into it.

22
00:01:14,246 --> 00:01:16,716
So let's say we start
with a very short list.

23
00:01:16,716 --> 00:01:18,206
We've got these seven items.

24
00:01:18,606 --> 00:01:24,306
I've got cat, cot, cow,
dog, dot, tag and tot.

25
00:01:24,306 --> 00:01:26,126
So I have a minimum
number of letters.

26
00:01:26,126 --> 00:01:29,166
We've only got maybe a half
dozen letters here to work with.

27
00:01:29,606 --> 00:01:31,106
What are we going to do?

28
00:01:31,216 --> 00:01:33,646
So the player is going to
come up and guess a letter.

29
00:01:34,386 --> 00:01:38,366
So let's say they've guessed
the letter T. For each

30
00:01:38,366 --> 00:01:42,266
of the words we can then
map what that guess would do

31
00:01:42,536 --> 00:01:46,046
to what the board would
look like at that time.

32
00:01:46,216 --> 00:01:50,466
So if the word was cat and they
guessed T they would have gotten

33
00:01:50,466 --> 00:01:51,996
the T in the third location

34
00:01:52,056 --> 00:01:53,446
and the first two
would still be blank.

35
00:01:54,226 --> 00:01:56,756
If the word was actually cow

36
00:01:56,756 --> 00:01:58,406
and they had guessed T they
wouldn't have any letters

37
00:01:58,406 --> 00:01:58,996
matching yet.

38
00:01:59,676 --> 00:02:02,196
If the word was actually
tot they would get T-T.

39
00:02:02,516 --> 00:02:07,126
So you get this idea of if
you'd played hangman before

40
00:02:07,126 --> 00:02:10,796
as you guess letters you fill in
the blanks, so the possibilities

41
00:02:10,796 --> 00:02:14,646
after all this are we
could end up with -- T.

42
00:02:15,326 --> 00:02:17,496
We could end up with -- - .

43
00:02:17,776 --> 00:02:22,316
We could end up with T-- or
we could end up with T-T.

44
00:02:23,136 --> 00:02:26,056
So there's really only four
possible outcomes at this point

45
00:02:26,056 --> 00:02:30,556
in the game no matter what
the words were to start with.

46
00:02:30,716 --> 00:02:34,286
Moving from there we now have
these four different classes

47
00:02:34,286 --> 00:02:35,716
and we can look at them.

48
00:02:36,696 --> 00:02:41,526
The words cat, cot and dot
have all mapped to -- T.

49
00:02:42,096 --> 00:02:44,916
So there are three cases that
we can get to in that case.

50
00:02:45,316 --> 00:02:49,236
If it was cow or dog it
would have matched to -- - .

51
00:02:49,386 --> 00:02:51,416
So there are only two
possibilities in that case.

52
00:02:52,006 --> 00:02:53,806
So obviously what we want to do

53
00:02:53,806 --> 00:02:56,936
at this point is pick what
gives us the most opportunities.

54
00:02:56,936 --> 00:03:00,946
So if we look at this choice
we've got three possible words

55
00:03:00,946 --> 00:03:04,736
still in the list so even though
here we might not be showing

56
00:03:05,466 --> 00:03:10,766
that any letter has matched
it's not as strategic a location

57
00:03:10,766 --> 00:03:14,166
for us to end up so what we'd
rather do is show the user --

58
00:03:14,166 --> 00:03:17,936
T and still have three
possible outcomes to work with.

59
00:03:18,636 --> 00:03:21,326
Does this basic idea
sort of make sense?

60
00:03:25,236 --> 00:03:26,656
So then we can continue.

61
00:03:27,406 --> 00:03:31,196
We've got this new list and the
person guesses the letter C.

62
00:03:32,456 --> 00:03:37,206
We've got these three conditions
they map out to C-T or -- T.

63
00:03:37,856 --> 00:03:38,876
Repeat the process.

64
00:03:39,316 --> 00:03:43,076
We see that there are
now two cases for C-T

65
00:03:43,316 --> 00:03:45,456
and that is still our
best case situation,

66
00:03:46,546 --> 00:03:49,156
so we'll pick that
and continue on.

67
00:03:49,736 --> 00:03:53,796
If they guess A we get
to a special case now.

68
00:03:54,696 --> 00:03:58,126
Each one is going to map to one
condition but we definitely want

69
00:03:58,126 --> 00:04:03,206
to pick the best equivalence
class for us which is cot

70
00:04:03,406 --> 00:04:05,576
because the user has not won.

71
00:04:06,316 --> 00:04:08,696
So we are going to
hit situations

72
00:04:08,696 --> 00:04:12,556
where potentially the number of
words in each list is the same.

73
00:04:12,776 --> 00:04:17,256
If there's no clear outcome we
should just do something sort

74
00:04:17,256 --> 00:04:17,796
of random.

75
00:04:18,036 --> 00:04:20,086
If there is a clear
outcome we should try

76
00:04:20,086 --> 00:04:21,106
to make the player lose.

77
00:04:21,626 --> 00:04:23,356
This is still following?

78
00:04:23,356 --> 00:04:23,816
It's still good?

79
00:04:28,356 --> 00:04:30,776
All right, so how do
we actually do this?

80
00:04:31,046 --> 00:04:32,666
I mean, the idea makes sense.

81
00:04:32,666 --> 00:04:34,536
You can get a little sense
of how you would play this

82
00:04:34,536 --> 00:04:36,566
with your friends if you
were working on paper.

83
00:04:37,036 --> 00:04:42,476
If we go out to Wikipedia we'll
see this, equivalence classes.

84
00:04:43,036 --> 00:04:46,086
"The equivalence class of an
element A is denoted, bracket A,

85
00:04:46,086 --> 00:04:48,646
may be defined as
the set of elements

86
00:04:48,646 --> 00:04:50,206
that are related
to, A by tilde."

87
00:04:50,766 --> 00:04:52,716
This does not tell
me a whole lot.

88
00:04:54,006 --> 00:04:58,046
What this basically translates
to is you should define a set

89
00:04:58,046 --> 00:05:01,236
of words sharing a given
letter at a given location

90
00:05:01,686 --> 00:05:02,896
and the other thing that comes

91
00:05:02,896 --> 00:05:04,876
out of it actually
is order matters.

92
00:05:05,246 --> 00:05:10,396
So -- T is treated
differently than T-- .

93
00:05:12,456 --> 00:05:14,676
So what would this
look like in code?

94
00:05:15,156 --> 00:05:17,406
It would have been great

95
00:05:17,406 --> 00:05:20,846
but X code has no idea what
NS equivalence class is.

96
00:05:21,156 --> 00:05:25,996
We just can't get it for free in
this case, so we have to think

97
00:05:25,996 --> 00:05:29,516
about how we would
actually implement this.

98
00:05:29,726 --> 00:05:30,936
So we've got a few options.

99
00:05:30,936 --> 00:05:34,706
We've heard about some of
these classes and type, classes

100
00:05:34,706 --> 00:05:38,706
and class, so we have things
like NS mutable dictionaries,

101
00:05:38,926 --> 00:05:42,316
NS mutable arrays, there's
also something called an NS

102
00:05:42,316 --> 00:05:43,156
mutable set.

103
00:05:43,606 --> 00:05:48,196
As you remember the
dictionaries map keys to values.

104
00:05:48,696 --> 00:05:52,536
An array is just a list of items
but they're in a specific order.

105
00:05:53,286 --> 00:05:55,326
A set is different
than those two.

106
00:05:55,796 --> 00:05:57,966
It's more like an array in
that it's a list of items

107
00:05:58,316 --> 00:06:01,126
but the order of the
items is not preserved.

108
00:06:01,126 --> 00:06:03,296
It's just a collection of items.

109
00:06:03,296 --> 00:06:09,156
So if we think about
what we're going

110
00:06:09,156 --> 00:06:11,426
to do here we can start
mapping this out in pseudocode.

111
00:06:12,706 --> 00:06:15,296
For each word in the set we need

112
00:06:15,296 --> 00:06:17,926
to determine what the
equivalence class is

113
00:06:17,926 --> 00:06:20,756
for the word and then
we can add that word

114
00:06:20,826 --> 00:06:22,776
to that equivalence class.

115
00:06:23,356 --> 00:06:26,826
So if the word was cat we've
come up and guessed T we come

116
00:06:26,826 --> 00:06:29,596
to the equivalence class -- T.

117
00:06:30,236 --> 00:06:33,296
We can then say for the
equivalence class name --

118
00:06:33,386 --> 00:06:36,146
T I can add cat to that list.

119
00:06:36,336 --> 00:06:38,896
When we get done we're going

120
00:06:38,896 --> 00:06:41,006
to determine the largest
equivalence class.

121
00:06:41,206 --> 00:06:43,726
We can remove all the
other words because they're

122
00:06:43,726 --> 00:06:46,006
out of play at this
point and then we have

123
00:06:46,006 --> 00:06:47,166
to update the user interface

124
00:06:47,166 --> 00:06:57,456
so the player knows what's
going on in the game.

125
00:06:57,666 --> 00:06:59,756
I think I've already covered all

126
00:06:59,756 --> 00:07:02,306
that so we're going
to skip that.

127
00:07:02,496 --> 00:07:03,656
So what should we be thinking

128
00:07:03,656 --> 00:07:05,266
about as we're implementing
this?

129
00:07:06,256 --> 00:07:09,456
So time and space are things
we should always about thinking

130
00:07:09,456 --> 00:07:10,626
about when we're
writing our code.

131
00:07:11,226 --> 00:07:13,806
In this case when we think
about time we have to think

132
00:07:13,806 --> 00:07:16,006
about iterating over lists.

133
00:07:16,176 --> 00:07:17,976
That's going to be an
a very slow process.

134
00:07:19,346 --> 00:07:20,346
If we can do something

135
00:07:20,346 --> 00:07:24,166
that actually uses an index it
will help the performance a lot,

136
00:07:24,426 --> 00:07:28,346
so we should look into the fact
that we could index into arrays

137
00:07:28,346 --> 00:07:31,856
and dictionaries very quickly so
that might drive your decisions.

138
00:07:32,876 --> 00:07:34,366
Another thing to think about

139
00:07:34,366 --> 00:07:37,486
and this will make more
sense later I would consider

140
00:07:37,486 --> 00:07:41,436
that loading plists from storage
is actually a slow process.

141
00:07:41,496 --> 00:07:44,676
If we can keep stuff in
memory that is overall going

142
00:07:44,676 --> 00:07:48,176
to help performance, of course
then we have to start thinking

143
00:07:48,176 --> 00:07:50,126
about our space considerations.

144
00:07:50,646 --> 00:07:53,366
So words.plist is
a pretty big file.

145
00:07:53,366 --> 00:07:56,606
The file we're going
to give you is just shy

146
00:07:56,606 --> 00:07:58,116
of 250 thousand words.

147
00:07:58,626 --> 00:08:00,006
It's still just text.

148
00:08:00,006 --> 00:08:02,196
It's not huge but we're
dealing with a device

149
00:08:02,266 --> 00:08:04,616
that actually doesn't
have a lot of storage.

150
00:08:05,506 --> 00:08:06,756
So that's something
to think about.

151
00:08:07,006 --> 00:08:10,356
We'll want to keep our data
structures as small as possible

152
00:08:11,516 --> 00:08:14,196
and we're also going to have to
keep in mind that we don't want

153
00:08:14,196 --> 00:08:17,766
to keep things in memory longer
than needed so we'll have

154
00:08:17,766 --> 00:08:22,036
to trade that off versus
loaded from storage is slow.

155
00:08:23,356 --> 00:08:25,856
How long should we
keep things in memory?

156
00:08:25,996 --> 00:08:31,406
You'll remember that when memory
gets low IOS will actually warn

157
00:08:31,406 --> 00:08:34,856
us so perhaps we can keep
things in memory for a while,

158
00:08:34,856 --> 00:08:37,746
be optimistic but if we're told
that we have to give back memory

159
00:08:37,886 --> 00:08:40,836
that might be the time that we
actually have to make a change

160
00:08:40,836 --> 00:08:42,776
and then keep track of
what state we're in.

161
00:08:43,376 --> 00:08:46,306
So just a few things for you
to ponder as you start working

162
00:08:46,306 --> 00:08:47,296
through this exercise.

163
00:08:47,296 --> 00:08:50,196
One thing that you should keep

164
00:08:50,196 --> 00:08:52,816
in mind though is this
quote from Donald Knuth.

165
00:08:53,086 --> 00:08:55,026
If you don't know who he
is you should look him up.

166
00:08:55,026 --> 00:08:55,496
He's a good guy.

167
00:08:56,456 --> 00:08:59,626
He said, "We should forget
about small efficiencies,

168
00:08:59,796 --> 00:09:01,786
say about 97 percent
of the time:

169
00:09:02,066 --> 00:09:04,676
Premature optimization
is the root of all evil.

170
00:09:05,376 --> 00:09:07,446
Yet we should not pass
up our opportunities

171
00:09:07,446 --> 00:09:08,706
in that critical 3 percent."

172
00:09:10,116 --> 00:09:13,046
So certainly we want to
do what we can to squeeze

173
00:09:13,046 --> 00:09:14,726
out every last bit of memory

174
00:09:15,696 --> 00:09:17,456
but that should not
be your first goal.

175
00:09:17,456 --> 00:09:19,396
Your first goal should be
getting things into memory,

176
00:09:19,396 --> 00:09:20,856
getting things basically working

177
00:09:20,856 --> 00:09:23,836
and if you can start tweaking
things afterwards that's great

178
00:09:23,836 --> 00:09:24,686
or if you start seeing

179
00:09:24,686 --> 00:09:27,756
that things are particularly
slow then it's time

180
00:09:27,756 --> 00:09:28,736
to start thinking about things.

181
00:09:29,186 --> 00:09:29,916
You have question?

182
00:09:29,916 --> 00:09:31,916
>> I just want [inaudible]
for a second, particularly

183
00:09:32,226 --> 00:09:34,176
if you could go back
to that last slide.

184
00:09:34,656 --> 00:09:38,346
I'm not really sure
I understand.

185
00:09:38,346 --> 00:09:41,506
We're iterating over all of
the words in the collection

186
00:09:41,836 --> 00:09:45,106
and determining an equivalence
of each of them why is

187
00:09:45,196 --> 00:09:47,156
that process slower
than indexing arrays

188
00:09:47,316 --> 00:09:49,316
or dictionaries assuming

189
00:09:49,476 --> 00:09:53,796
that they are all consecutively
arranged [inaudible]

190
00:09:53,936 --> 00:09:55,216
>> Chris Gerber: Okay,
so the question is

191
00:09:55,286 --> 00:10:00,096
around why is iterating over
the lists going to be slower

192
00:10:00,096 --> 00:10:03,266
than indexing into the
arrays the way we're working?

193
00:10:03,816 --> 00:10:05,546
So one thing you
might want to think

194
00:10:05,546 --> 00:10:09,946
about out there is we've got 250
thousand words approximately.

195
00:10:11,136 --> 00:10:14,516
All those words are different
lengths and if you know

196
00:10:14,516 --> 00:10:16,766
that the length of the
word is for example,

197
00:10:16,766 --> 00:10:20,186
eight characters you might
only want to work with a subset

198
00:10:20,186 --> 00:10:25,066
of the list that is only eight
character words and you can have

199
00:10:25,066 --> 00:10:27,546
that indexed out to
a chunk of memories

200
00:10:27,546 --> 00:10:30,276
so you're only iterating
over that subset and then

201
00:10:30,276 --> 00:10:32,146
as equivalence classes
get thrown

202
00:10:32,146 --> 00:10:36,316
out you can shift yourself
down to a smaller list of words

203
00:10:36,316 --> 00:10:39,276
so you're not iterating
over 250 thousand every time

204
00:10:39,676 --> 00:10:44,836
or perhaps ten thousand then
five thousand then two thousand.

205
00:10:45,696 --> 00:10:47,416
That's sort of more of
where I was going there.

206
00:10:47,416 --> 00:10:48,156
Does that make is sense?

207
00:10:48,216 --> 00:10:50,536
>> Yeah, you'll be
chunking around with more

208
00:10:51,226 --> 00:10:54,056
because you would be
only picking out words--

209
00:10:54,056 --> 00:10:54,766
>> Chris Gerber: --
of certain length

210
00:10:54,766 --> 00:10:56,386
or have already been excluded.

211
00:10:56,866 --> 00:10:58,026
Yeah. All right?

212
00:11:02,216 --> 00:11:03,636
Yeah, another question?

213
00:11:03,636 --> 00:11:05,506
>> [Inaudible question]

214
00:11:05,506 --> 00:11:14,126
>> Chris Gerber: Yeah,
so the question is

215
00:11:14,316 --> 00:11:19,116
around setting the
length of the word.

216
00:11:19,556 --> 00:11:21,526
If you look at the
specification,

217
00:11:21,526 --> 00:11:25,826
what we've specified is we'll
be using utility application

218
00:11:25,826 --> 00:11:27,996
which sort of has a front
side and a back side.

219
00:11:28,796 --> 00:11:30,786
The front side will be
the playing of the game.

220
00:11:30,926 --> 00:11:34,616
The back side will be for
configuring the game and one

221
00:11:34,616 --> 00:11:36,926
of the things you'll be
implementing is a slider

222
00:11:37,326 --> 00:11:39,996
that sets the length of the word
that the user will be playing

223
00:11:39,996 --> 00:11:42,806
with at that time and every
time they restart the game

224
00:11:42,806 --> 00:11:46,026
until they change the length
of the word it will continue

225
00:11:46,026 --> 00:11:47,016
to use that word length.

226
00:11:47,496 --> 00:11:51,026
So we'll be setting that
as part of our settings

227
00:11:51,276 --> 00:11:52,906
which might be preloaded
from disk,

228
00:11:53,596 --> 00:11:56,436
persisted for the next
time they play, etcetera.

229
00:11:56,866 --> 00:11:57,846
Things to think about there.

230
00:11:58,146 --> 00:11:59,266
Does that make sense?

231
00:12:00,176 --> 00:12:01,486
Okay and did you
have a question?

232
00:12:01,786 --> 00:12:07,756
>> Does it matter how long we
set the amount it can change to,

233
00:12:08,266 --> 00:12:09,786
five to ten letters?

234
00:12:10,076 --> 00:12:12,466
>> Chris Gerber: So the question
is does it matter how long,

235
00:12:12,886 --> 00:12:15,176
what the choices are
for length of word?

236
00:12:15,726 --> 00:12:20,596
And what we'll ask you to do
is assume that it is based

237
00:12:20,656 --> 00:12:22,176
on what you find in the file.

238
00:12:22,656 --> 00:12:25,866
So as you first load the file
you'll want to look through

239
00:12:25,866 --> 00:12:28,546
and figure out what the
shortest and longest words are

240
00:12:28,546 --> 00:12:31,176
in the file and that will
be the size of your slider.

241
00:12:31,546 --> 00:12:34,766
Another question.

242
00:12:34,766 --> 00:12:34,833
>> [Inaudible question]

243
00:12:34,833 --> 00:12:38,926
>> Chris Gerber: So the question
is as we first load a file

244
00:12:38,926 --> 00:12:46,386
into memory or as we first
look at the plist we need

245
00:12:48,696 --> 00:12:55,896
to load the entire thing into
memory and is that a concern?

246
00:12:55,896 --> 00:13:01,046
That is an unfortunate situation
that we have to deal with.

247
00:13:01,046 --> 00:13:04,786
You will have to load everything
into memory once and then

248
00:13:04,786 --> 00:13:12,886
from there you can decide how
much you are going to retain

249
00:13:13,056 --> 00:13:15,976
in memory as the
application runs.

250
00:13:15,976 --> 00:13:20,206
>> Are we going to have a
choice as to data structure

251
00:13:20,396 --> 00:13:27,226
that we are going use
to store the information

252
00:13:27,666 --> 00:13:29,496
in memory like [inaudible]

253
00:13:29,936 --> 00:13:30,836
>> Chris Gerber: The question is

254
00:13:30,836 --> 00:13:33,776
around what data structure
we're going to use to store this

255
00:13:33,776 --> 00:13:37,906
in memory and that is completely
open to your interpretation

256
00:13:37,906 --> 00:13:40,926
of the problem and how you
actually want to implement it.

257
00:13:41,086 --> 00:13:44,606
You should probably stick
with some of the common built

258
00:13:44,606 --> 00:13:47,516
in data types but it's up to you

259
00:13:47,516 --> 00:13:50,266
to determine what
you want to do.

260
00:13:50,266 --> 00:13:53,876
>> And as a side note
you don't have to load it

261
00:13:54,136 --> 00:13:54,476
in [inaudible] plists.

262
00:13:54,736 --> 00:13:57,766
You're free to pre-process
it in whichever ways you want

263
00:13:58,216 --> 00:14:02,436
but any [inaudible] of
those words support it.

264
00:14:02,636 --> 00:14:03,776
>> Chris Gerber: That
was a great point

265
00:14:03,776 --> 00:14:04,766
if the cameras didn't
pick it up.

266
00:14:05,366 --> 00:14:09,976
You don't need to load
plist in your application.

267
00:14:09,976 --> 00:14:14,906
You can pre-process the file
and do something else to deal

268
00:14:14,906 --> 00:14:17,796
with that so I think the
specification actually mentions

269
00:14:18,626 --> 00:14:20,266
parenthetically that
you could use something

270
00:14:20,266 --> 00:14:21,706
like a SQL-like database

271
00:14:22,306 --> 00:14:24,776
or you could somehow
otherwise pre-process the file

272
00:14:24,776 --> 00:14:27,276
so you're using smaller
subsets as you were.

273
00:14:30,136 --> 00:14:31,046
Another question?

274
00:14:31,046 --> 00:14:32,096
>> [Inaudible question]

275
00:14:32,096 --> 00:14:43,116
>> Chris Gerber: So the question
is around the strict definition

276
00:14:44,276 --> 00:14:55,176
of equivalence classes
being symmetric, transitive,

277
00:14:55,176 --> 00:14:57,996
I missed the other one.

278
00:14:58,156 --> 00:15:00,026
>> Reflexive?

279
00:15:00,256 --> 00:15:00,966
>> Chris Gerber: Reflexive.

280
00:15:01,136 --> 00:15:08,116
I honestly don't have a
good answer on that one.

281
00:15:08,316 --> 00:15:09,946
Anything else?

282
00:15:10,236 --> 00:15:14,956
All right, so just to summarize,
at every point you want

283
00:15:14,956 --> 00:15:17,646
to leave yourself the most
number of options that you can.

284
00:15:18,626 --> 00:15:21,196
If at all possible you
don't want the player to win

285
00:15:22,576 --> 00:15:25,506
and if you have the
opportunity you should think

286
00:15:25,506 --> 00:15:32,476
about how you might optimize our
very simple algorithm further.

287
00:15:32,646 --> 00:15:36,346
So getting down to real
details, how do we get started?

288
00:15:37,216 --> 00:15:39,426
We're going to be using
a utility application

289
00:15:39,506 --> 00:15:41,476
and that's one of the
standard templates

290
00:15:41,476 --> 00:15:42,826
that you'll see in Xcode.

291
00:15:43,236 --> 00:15:46,626
It contains two controllers,
a MainViewController

292
00:15:46,836 --> 00:15:48,306
and a FlipsideViewController.

293
00:15:48,986 --> 00:15:51,726
Typically, the Flipside
Controller is used

294
00:15:51,726 --> 00:15:54,796
for storing configurations,
storing settings.

295
00:15:55,266 --> 00:15:57,796
For those that have played
with an iPhone you can pick

296
00:15:57,796 --> 00:16:01,436
up something like the Apple
Weather App but I can also

297
00:16:02,016 --> 00:16:06,056
on the fly, too many windows.

298
00:16:06,056 --> 00:16:14,276
I know what happened.

299
00:16:15,586 --> 00:16:19,896
I have to exit my show first.

300
00:16:19,896 --> 00:16:23,116
All right, now I've got
code all over the place.

301
00:16:28,176 --> 00:16:36,506
Get that out of the way,
get this out of the way.

302
00:16:36,696 --> 00:16:49,376
All right, oh, I
don't have it there.

303
00:16:49,376 --> 00:16:54,356
After all that I can't even
show you what I was going

304
00:16:55,266 --> 00:16:56,926
to show you.

305
00:17:02,656 --> 00:17:08,816
That's what-- now
I've lost PowerPoint.

306
00:17:08,896 --> 00:17:12,616
All right, so for now I will
assume that you can picture sort

307
00:17:12,786 --> 00:17:14,766
of what the application
looks like

308
00:17:14,766 --> 00:17:20,986
and we'll move forward
from there.

309
00:17:21,076 --> 00:17:23,526
All right, with the
utility application one

310
00:17:23,526 --> 00:17:25,726
of the things we'll
have to use is this idea

311
00:17:25,726 --> 00:17:27,556
of delegates and protocols.

312
00:17:28,856 --> 00:17:32,006
So what a delegate is
it identifies an object

313
00:17:32,236 --> 00:17:35,926
that will handle an action
on your behalf rather

314
00:17:35,926 --> 00:17:37,466
than you handling the action.

315
00:17:37,706 --> 00:17:39,486
And where we're going
to see this

316
00:17:39,486 --> 00:17:46,026
in this particular case is the
FlipsideViewController requires

317
00:17:46,026 --> 00:17:49,016
a delegate which is
the MainViewController

318
00:17:49,496 --> 00:17:54,216
and this allows the
MainViewController

319
00:17:54,696 --> 00:17:58,766
to have a piece of code that
runs that is passed to it

320
00:17:58,766 --> 00:18:00,296
from the FlipsideViewController.

321
00:18:00,796 --> 00:18:02,036
So any changes you make

322
00:18:02,036 --> 00:18:04,686
on the Flipside can
be communicated back

323
00:18:05,226 --> 00:18:06,786
to the MainViewController.

324
00:18:07,796 --> 00:18:09,606
So you've change the slider.

325
00:18:09,856 --> 00:18:12,146
It's essentially got call
back as we saw on Java script

326
00:18:12,146 --> 00:18:13,826
where it can call back
to MainViewController

327
00:18:13,826 --> 00:18:15,606
and say "Hey, this was updated."

328
00:18:17,156 --> 00:18:20,236
To use a delegate you have
to implement a protocol.

329
00:18:20,536 --> 00:18:24,276
In this case it will be a
FlipsideViewController protocol

330
00:18:24,886 --> 00:18:29,466
that it knows what to do and
the protocol essentially just

331
00:18:29,466 --> 00:18:33,336
guarantees that the methods you
specify will be implemented.

332
00:18:33,836 --> 00:18:39,366
The protocol itself will
look something like this.

333
00:18:39,366 --> 00:18:42,566
You'll have at protocol,
some name for the protocol.

334
00:18:43,226 --> 00:18:46,556
You can have a number of methods
that could either be voids,

335
00:18:46,676 --> 00:18:50,076
they could return values,
they could be passed in values

336
00:18:50,576 --> 00:18:57,016
and then at end the at
the end of the method.

337
00:18:57,096 --> 00:19:01,006
All right, so let's see if
we can actually take a look

338
00:19:01,116 --> 00:19:04,376
at the utility application.

339
00:19:07,556 --> 00:19:17,366
So I'm going to go from
Xcode, File, New Project.

340
00:19:18,456 --> 00:19:23,316
Utility application can be
found under IOS application.

341
00:19:23,786 --> 00:19:28,256
It'll ask you for
a product name.

342
00:19:28,476 --> 00:19:32,596
So I can give it a name.

343
00:19:32,846 --> 00:19:34,506
Your organization
can be anything.

344
00:19:34,506 --> 00:19:35,896
I've just been using my name.

345
00:19:36,426 --> 00:19:39,356
I believe the spec
asks you to edu.Harvard

346
00:19:39,356 --> 00:19:40,676
as your company identifier.

347
00:19:42,006 --> 00:19:44,646
We don't need to use
class prefix at this time

348
00:19:45,516 --> 00:19:49,256
and for this I'm just
going to use iPhone.

349
00:19:49,596 --> 00:19:51,766
You can also specify
iPad or Universal.

350
00:19:52,626 --> 00:19:54,656
We're not going to use
story boards at this time

351
00:19:54,656 --> 00:19:56,556
but we will talk about
them a bit later tonight.

352
00:19:57,876 --> 00:19:59,936
We don't need to use
core data at this time.

353
00:20:00,386 --> 00:20:03,316
Core data is essentially a back
in data store that you can use

354
00:20:03,316 --> 00:20:04,356
with your applications.

355
00:20:05,186 --> 00:20:06,946
We are going to use
automatic reference counting

356
00:20:07,356 --> 00:20:09,916
and for tonight I'm not going
to include any unit tests.

357
00:20:10,386 --> 00:20:11,556
I'll just assume I
know what I'm going

358
00:20:11,556 --> 00:20:13,326
and my code is going to run.

359
00:20:14,656 --> 00:20:17,236
It'll ask you for a
place to save your code

360
00:20:18,656 --> 00:20:22,106
and you can create a local
get repository or not.

361
00:20:22,106 --> 00:20:25,416
I personally like to
because I use get all day

362
00:20:25,416 --> 00:20:27,636
and am very familiar
with the source control

363
00:20:27,636 --> 00:20:29,846
but it's not strictly
necessary for what we're doing

364
00:20:30,266 --> 00:20:31,706
and you can hit create.

365
00:20:32,246 --> 00:20:36,496
So that will give us
our new application.

366
00:20:37,076 --> 00:20:39,616
As we mentioned there's
the MainViewController.

367
00:20:39,906 --> 00:20:41,396
There's the
FlipsideViewController.

368
00:20:42,176 --> 00:20:43,886
Each of those is also
going to have a NIB file

369
00:20:44,926 --> 00:20:48,576
so this should look vaguely
familiar from lecture.

370
00:20:48,576 --> 00:20:49,206
If you look

371
00:20:51,286 --> 00:20:55,256
at the MainViewController you'll
see it's not very complicated.

372
00:20:55,256 --> 00:20:56,866
There is one little
button down here.

373
00:20:57,376 --> 00:21:08,076
Let's see if I can, let
me put my simulator--

374
00:21:10,516 --> 00:21:30,476
[On Screen Activity
Being Performed]

375
00:21:30,976 --> 00:21:33,426
So I don't have the
fancy border on here

376
00:21:33,426 --> 00:21:34,846
but you can see it's
the same window.

377
00:21:35,046 --> 00:21:36,386
It's got the information button.

378
00:21:37,696 --> 00:21:39,536
As we mentioned,
all this is going

379
00:21:39,536 --> 00:21:41,526
to do is flip to the other side.

380
00:21:42,216 --> 00:21:44,166
This is where we would
see things like settings.

381
00:21:44,996 --> 00:21:45,616
We hit done.

382
00:21:45,786 --> 00:21:47,726
We flip back to the first side.

383
00:21:53,236 --> 00:21:56,456
To round that out you'll see the
FlipsideViewController has the

384
00:21:56,456 --> 00:21:59,986
done button entitled that
we saw and you can look

385
00:21:59,986 --> 00:22:02,436
through the actual
implementations.

386
00:22:02,436 --> 00:22:04,286
There's not a ton here.

387
00:22:04,876 --> 00:22:07,346
Things like view did load, view
did receive memory warning,

388
00:22:07,346 --> 00:22:09,106
we've seen before and
obviously they're blank

389
00:22:09,106 --> 00:22:13,046
so they could be
deleted at this time.

390
00:22:13,676 --> 00:22:20,236
If we actually look at
the header first we'll see

391
00:22:20,236 --> 00:22:23,106
that there is a
FlipsideViewController delegate

392
00:22:23,106 --> 00:22:26,006
as we mentioned so that
we can do something

393
00:22:26,006 --> 00:22:32,466
on behalf of the flip side.

394
00:22:32,626 --> 00:22:37,286
You'll see that's
actually implemented here.

395
00:22:37,576 --> 00:22:38,736
The method that's promised

396
00:22:38,796 --> 00:22:41,706
through that protocol is a
FlipsideViewController did

397
00:22:41,706 --> 00:22:42,626
finish method.

398
00:22:45,536 --> 00:22:47,076
Yeah, sorry.

399
00:22:57,396 --> 00:22:58,866
Which one is it?

400
00:23:05,856 --> 00:23:07,566
Control, Option, INT.

401
00:23:10,276 --> 00:23:17,356
Ah, there we go.

402
00:23:18,586 --> 00:23:27,936
Of course, my window
has gone so far over--

403
00:23:27,936 --> 00:23:35,266
now I can't-- there we go.

404
00:23:35,896 --> 00:23:45,156
So FlipsideViewController
did finish.

405
00:23:45,376 --> 00:23:57,146
It's going to take the
controller as it's argument.

406
00:23:57,146 --> 00:24:05,946
In this case all it's going
to do is do an animated close

407
00:24:06,646 --> 00:24:10,616
but this is our opportunity to
have access to the variables

408
00:24:10,616 --> 00:24:13,466
that are in scope of the
FlipsideViewController

409
00:24:14,156 --> 00:24:15,706
and do whatever we need to do.

410
00:24:16,346 --> 00:24:20,196
So if there was a slider that
had a value of ten we could take

411
00:24:20,196 --> 00:24:23,146
that ten and change
some variable

412
00:24:23,146 --> 00:24:24,526
in our local scope as well.

413
00:24:25,716 --> 00:24:37,356
Does that basic idea make sense?

414
00:24:37,356 --> 00:24:42,256
Okay and the
FlipsideViewController is very

415
00:24:42,256 --> 00:24:42,856
straight forward.

416
00:24:44,556 --> 00:24:47,526
We've got the actual protocol
here that we implemented

417
00:24:47,526 --> 00:24:50,826
which is the
FlipsideViewController

418
00:24:50,826 --> 00:24:51,436
did finish.

419
00:24:51,436 --> 00:24:53,576
This is the promise that we made

420
00:24:53,816 --> 00:24:55,586
when we said we would
implement this delegate.

421
00:25:02,056 --> 00:25:05,526
And the only actual line
of curve that we might care

422
00:25:05,526 --> 00:25:09,616
about here is that when we
click the done button the

423
00:25:09,826 --> 00:25:18,486
FlipsideViewController
says it is going to finish.

424
00:25:18,686 --> 00:25:29,296
All right, that's all I
wanted to cover there.

425
00:25:29,506 --> 00:25:31,396
All right, so how
are we actually going

426
00:25:31,396 --> 00:25:33,626
to get input in the application?

427
00:25:34,096 --> 00:25:35,976
So ideally we want to
see keyboard popped up.

428
00:25:35,976 --> 00:25:37,096
We want to hit a letter.

429
00:25:37,606 --> 00:25:40,946
It's going to process the
letter, think about it.

430
00:25:41,716 --> 00:25:45,146
The way to get input in
an IOS application is

431
00:25:45,146 --> 00:25:46,876
to use a UI text field.

432
00:25:48,066 --> 00:25:50,296
UI text field itself is great

433
00:25:50,296 --> 00:25:53,686
if you're just doing traditional
stuff but if you want

434
00:25:53,686 --> 00:25:56,636
to do more you can use
a UI text field delegate

435
00:25:56,746 --> 00:25:58,646
and that gives you
additional functionality.

436
00:25:59,866 --> 00:26:01,256
This also lets you do things

437
00:26:01,256 --> 00:26:04,346
like actually make
the text field hidden

438
00:26:05,086 --> 00:26:07,446
which is probably what we'd
like in this application.

439
00:26:07,446 --> 00:26:10,606
We want to listen
to the keyboard.

440
00:26:10,606 --> 00:26:12,196
We want to respond
to the key presses

441
00:26:12,606 --> 00:26:14,986
but we don't want
necessarily that text appearing

442
00:26:14,986 --> 00:26:16,686
on the screen in
a box somewhere.

443
00:26:16,686 --> 00:26:20,426
We want to process it in
a more intelligent manner.

444
00:26:25,436 --> 00:26:29,266
So if we use this UI text field
delegate we get some additional

445
00:26:29,866 --> 00:26:31,246
methods that we can
implement here.

446
00:26:31,916 --> 00:26:34,086
We get text field should return.

447
00:26:34,846 --> 00:26:37,376
This is what happens when
someone hits the done button

448
00:26:37,556 --> 00:26:41,346
on the keyboard and then we can
do whatever is appropriate there

449
00:26:41,346 --> 00:26:43,286
like perhaps hide the keyboard.

450
00:26:44,696 --> 00:26:47,976
We've got text field should
begin editing which is

451
00:26:47,976 --> 00:26:50,056
when the user is
about to edit text.

452
00:26:50,286 --> 00:26:53,166
We can do whatever we need to
set up our application then.

453
00:26:53,436 --> 00:26:57,136
And there's a text field should
end editing which is right

454
00:26:57,196 --> 00:26:59,176
as the field is about
to lose focus.

455
00:26:59,176 --> 00:27:05,726
So now I've got a
very quick demo

456
00:27:05,726 --> 00:27:09,036
about what we can do
with UI text field.

457
00:27:12,616 --> 00:27:21,186
That is, this is it.

458
00:27:23,516 --> 00:27:46,436
[On Screen Activity
Being Performed]

459
00:27:46,936 --> 00:27:50,456
All right, so I've made a
simple utility application here.

460
00:27:51,006 --> 00:27:56,986
I've got a text field and
a label and that's it.

461
00:27:58,016 --> 00:28:00,276
And what I'd like
to have happen is

462
00:28:00,276 --> 00:28:02,696
when the application
launches first

463
00:28:02,696 --> 00:28:04,886
of all it doesn't make
much sense for the label

464
00:28:04,886 --> 00:28:08,056
to actually say the word label
so I want to change that.

465
00:28:09,586 --> 00:28:12,756
The field for entering text
is currently visible so I want

466
00:28:12,756 --> 00:28:14,966
to hide that and
then I have to deal

467
00:28:14,966 --> 00:28:21,426
with how does this
all get wired up?

468
00:28:21,656 --> 00:28:30,876
So, let's look at
that, the header first.

469
00:28:38,436 --> 00:28:47,116
We're just off the screen.

470
00:28:52,896 --> 00:28:54,126
All right, so you'll remember

471
00:28:54,126 --> 00:28:58,646
from class we've got these two
new things called IB outlets

472
00:28:58,936 --> 00:29:00,346
and IB actions.

473
00:29:00,896 --> 00:29:11,306
IB outlets let us control
the properties for, sorry,

474
00:29:11,466 --> 00:29:13,436
let us set properties
from the UI

475
00:29:14,086 --> 00:29:16,966
and IB actions let us
allow us to respond

476
00:29:17,036 --> 00:29:21,326
to actions occurring
within the UI.

477
00:29:21,736 --> 00:29:25,976
So I've got, as you've noticed
the label and a text field.

478
00:29:26,746 --> 00:29:30,296
In my application I've set
up a label and a text field

479
00:29:30,296 --> 00:29:33,176
and referred to them as
text, label and keyboard.

480
00:29:33,686 --> 00:29:42,546
And again just, you'll remember
there's these little dots

481
00:29:42,546 --> 00:29:45,176
that appear and I've
prewired these up for us

482
00:29:45,506 --> 00:29:50,586
and we'll see that
in the UI side.

483
00:29:51,526 --> 00:29:55,346
I've also created a
new IB action here

484
00:29:55,346 --> 00:29:56,846
for handling key presses.

485
00:29:57,066 --> 00:29:58,496
So this is going the other way.

486
00:29:58,496 --> 00:30:01,576
Rather than updating the
UI I'm listening to the UI

487
00:30:01,576 --> 00:30:06,786
and responding to
what's happening.

488
00:30:06,786 --> 00:30:11,216
We then switch over to
the actual implementation.

489
00:30:12,676 --> 00:30:16,936
We can see if we can get
that a little more centered.

490
00:30:21,076 --> 00:30:23,946
I've done a few things here.

491
00:30:24,896 --> 00:30:28,966
So first when the application is
first loading you'll remember we

492
00:30:28,966 --> 00:30:32,356
see a view did load event occur.

493
00:30:32,426 --> 00:30:34,426
So I've done a few things here.

494
00:30:35,086 --> 00:30:37,796
I'm going to set the
text label text to blank.

495
00:30:38,396 --> 00:30:44,146
I can send a message to the edit
field that I've called keyboard

496
00:30:44,536 --> 00:30:47,936
and tell it to set its
hidden property to yes.

497
00:30:48,676 --> 00:30:50,816
Then the other thing
I've done you'll remember

498
00:30:50,816 --> 00:30:52,756
from class is I can
do, send the keyboard

499
00:30:52,756 --> 00:30:55,416
to become first responder
message.

500
00:30:56,056 --> 00:30:58,286
And what that message is going
to do is basically tell it

501
00:30:58,286 --> 00:30:59,766
that it is the primary control

502
00:31:00,276 --> 00:31:03,826
and when a text field is the
primary control the first thing

503
00:31:03,826 --> 00:31:05,306
that it wants to do is
display the keyboard.

504
00:31:05,386 --> 00:31:07,736
So that's going to pop
up the keyboard for me.

505
00:31:08,676 --> 00:31:11,616
The other method he I
implemented is this handle key

506
00:31:11,646 --> 00:31:18,246
press method which you saw
I created as an IB action.

507
00:31:18,246 --> 00:31:20,206
And what I'm doing here is

508
00:31:21,266 --> 00:31:26,776
when a UI text field has
received key presses it appends

509
00:31:26,956 --> 00:31:29,236
to a property called text.

510
00:31:30,226 --> 00:31:32,866
So what I'm going to do is
check the length of that text,

511
00:31:32,866 --> 00:31:35,506
see if it has become
greater than zero,

512
00:31:35,506 --> 00:31:36,976
so something has been typed in.

513
00:31:38,056 --> 00:31:41,396
If it is I'm going to
change the text of the label

514
00:31:42,146 --> 00:31:46,986
by setting the text to what
the text of the label was,

515
00:31:47,656 --> 00:31:49,936
create a new string
by appending a string

516
00:31:51,596 --> 00:31:53,606
and it scrolls off
the side here.

517
00:31:53,606 --> 00:31:54,996
Let me see if I can
see it, yeah,

518
00:31:55,636 --> 00:31:58,066
to whatever the keyboard
text is.

519
00:31:58,606 --> 00:31:59,466
So I'm taking what was

520
00:31:59,466 --> 00:32:02,126
in the field I'm appending
whatever the keyboard was

521
00:32:03,176 --> 00:32:10,166
and then I'm going to set the
value set in the edit field

522
00:32:10,636 --> 00:32:13,036
to just blank, to
zero it back out.

523
00:32:13,656 --> 00:32:17,106
So this, every time it hears
a key press it will take it,

524
00:32:17,206 --> 00:32:22,406
append it to what was
already in the field.

525
00:32:22,516 --> 00:32:24,746
>> Chris, will we have
access to these slides?

526
00:32:25,526 --> 00:32:26,546
>> Chris Gerber:
Yes, I will be--

527
00:32:26,816 --> 00:32:28,696
the question was will we
have access to these slides?

528
00:32:28,956 --> 00:32:31,436
I will be uploading these
slides and the source code

529
00:32:31,436 --> 00:32:37,076
that I'm showing tonight
to the CS 76 dot website.

530
00:32:37,076 --> 00:32:40,396
It should be up before
I go to bed

531
00:32:40,886 --> 00:32:48,726
but that could be any
time, hopefully, not five.

532
00:32:48,836 --> 00:32:55,066
All right, the other thing I
wanted to show is back in--

533
00:32:55,416 --> 00:33:02,506
in the view controller
you'll see

534
00:33:02,746 --> 00:33:07,706
that I've wired the text
label to file's owner

535
00:33:07,916 --> 00:33:10,206
and it's not obvious that
file's owner is on the screen.

536
00:33:10,206 --> 00:33:12,526
I know what the dot, dot,
dot means in this case.

537
00:33:14,446 --> 00:33:19,206
That allows the controller
to have right to that field

538
00:33:19,616 --> 00:33:24,526
and for the text field
I had to set two things.

539
00:33:24,526 --> 00:33:27,526
Can I get them both to show?

540
00:33:28,056 --> 00:33:35,346
Well, the first one
is editing changed

541
00:33:36,666 --> 00:33:38,926
so every time the contents

542
00:33:38,926 --> 00:33:42,346
of the field are
changing I am going

543
00:33:42,346 --> 00:33:47,306
to tell the file's old owner
to, it doesn't fully show

544
00:33:47,306 --> 00:33:49,586
but call my handle
key press method.

545
00:33:50,026 --> 00:33:55,376
Let's see if I can get
the other one for it.

546
00:33:55,626 --> 00:33:58,206
The other one is down here.

547
00:33:58,206 --> 00:34:04,456
Because I also need
to be able to empty

548
00:34:04,456 --> 00:34:08,336
out the field I've set
the keyboard to be wired

549
00:34:08,336 --> 00:34:10,796
up to file's owner as
well and that allows me

550
00:34:10,796 --> 00:34:12,026
to access those properties.

551
00:34:12,536 --> 00:34:21,386
So putting it all together
we can find our play button

552
00:34:28,876 --> 00:34:31,426
and the application is gone
off the bottom of the screen

553
00:34:31,426 --> 00:34:34,106
but what we care about is at the
top even though you can't see it

554
00:34:34,106 --> 00:34:36,486
and the fact that you can't see
it is a good thing, all right.

555
00:34:36,486 --> 00:34:38,356
It doesn't show us
the word label

556
00:34:38,846 --> 00:34:40,336
which is what we wanted
as a starting point.

557
00:34:40,976 --> 00:34:43,776
It doesn't show us
that edit field

558
00:34:44,806 --> 00:34:51,606
but I can't see the keyboard.

559
00:34:51,606 --> 00:34:59,056
I don't think it's
running right.

560
00:34:59,146 --> 00:34:59,926
Let's try this again.

561
00:35:05,256 --> 00:35:10,056
I have a breakpoint
in my application.

562
00:35:10,056 --> 00:35:11,406
As you may remember if you put

563
00:35:11,406 --> 00:35:13,216
in a breakpoint your
code will stop running.

564
00:35:13,526 --> 00:35:20,196
All right, so now if
we continue, all right,

565
00:35:20,196 --> 00:35:28,276
so the fields in the
text are still going.

566
00:35:28,276 --> 00:35:30,606
This time we actually
got the keyboard

567
00:35:30,606 --> 00:35:32,546
because the code is actually
running at this point

568
00:35:33,036 --> 00:35:37,206
as I type letters they do in
fact make it to the label,

569
00:35:37,466 --> 00:35:42,926
so sort of a blur,
sort of a whirlwind.

570
00:35:43,106 --> 00:35:45,886
You will have the code but
does the basic idea make sense?

571
00:35:45,886 --> 00:35:48,106
Does it all seem familiar based
on what you saw in lecture?

572
00:35:48,256 --> 00:35:48,786
All right.

573
00:35:49,796 --> 00:35:57,936
>> If you could just show
how to wire it out real fast

574
00:35:57,936 --> 00:36:00,936
with the option key held down?

575
00:36:00,966 --> 00:36:01,186
>> Chris Gerber: Yeah,

576
00:36:01,186 --> 00:36:03,916
so the question is can we
quickly redo the wiring just

577
00:36:03,916 --> 00:36:14,606
to see that happen and we
can absolutely do that.

578
00:36:14,706 --> 00:36:25,456
All right, so let's first
bring up the NIB file.

579
00:36:25,616 --> 00:36:29,486
I'm going to make this
window a little bit smaller

580
00:36:29,486 --> 00:36:31,326
so we can see it.

581
00:36:35,656 --> 00:36:36,046
There we go.

582
00:36:36,046 --> 00:36:40,696
All right, so the easiest
way to start doing this

583
00:36:40,726 --> 00:36:43,976
and for the moment we don't need
the items over here so let's get

584
00:36:43,976 --> 00:36:47,116
that out of our way, give us a
little more room to work with.

585
00:36:47,286 --> 00:36:50,736
Remember, there's the
assistant up here.

586
00:36:50,866 --> 00:36:51,976
Show the assistant editor

587
00:36:52,396 --> 00:36:56,196
which basically lets us put
any two files side by side.

588
00:36:56,896 --> 00:36:59,316
By default it will try to
pick the most appropriate file

589
00:36:59,386 --> 00:36:59,736
for you.

590
00:37:01,206 --> 00:37:03,786
So in this case it did
automatically detect that I want

591
00:37:03,786 --> 00:37:05,916
to look at my header
file which is good

592
00:37:05,916 --> 00:37:09,166
because that is what
I want it to.

593
00:37:09,326 --> 00:37:12,996
Just for your own
edification, if you click

594
00:37:13,396 --> 00:37:19,166
on the filename there it will
give you other logical choices.

595
00:37:20,266 --> 00:37:21,816
You can also go back and instead

596
00:37:21,816 --> 00:37:24,326
of automatic you can put
any other file side by side

597
00:37:24,326 --> 00:37:26,486
so you could go to manual
and I could pick any file

598
00:37:26,486 --> 00:37:28,096
to have two different
things side by side.

599
00:37:28,856 --> 00:37:30,346
But in this case
this is what we want.

600
00:37:30,386 --> 00:37:35,016
We want to see the view and we
want to see our header file.

601
00:37:35,126 --> 00:37:54,046
So I can come in here
and that's what I wanted.

602
00:37:54,836 --> 00:37:59,506
All right, so we can come
in and delete the ones

603
00:38:01,046 --> 00:38:04,316
that I had set up there.

604
00:38:05,016 --> 00:38:11,016
All right so we've got the
IB outlets for properties

605
00:38:11,076 --> 00:38:14,946
and we've got the IB
actions for methods.

606
00:38:19,156 --> 00:38:32,446
Since we want to go from our
code to the UI, I should be able

607
00:38:32,486 --> 00:38:38,296
to option click from the
text label to the text label

608
00:38:38,856 --> 00:38:43,286
and we'll see that wired up
text label to file's owner.

609
00:38:43,686 --> 00:38:49,636
I can also do option click from
UI text field to text field

610
00:38:49,736 --> 00:38:58,346
and then I can do option
click, sorry, control click

611
00:38:59,246 --> 00:39:02,236
from the text field
back to [inaudible].

612
00:39:02,906 --> 00:39:06,836
So this one is actually
different

613
00:39:06,996 --> 00:39:11,866
because I actually want to use
it editing changed so I can come

614
00:39:11,866 --> 00:39:15,046
in here and wire that
up to the method.

615
00:39:15,046 --> 00:39:18,706
I actually don't know
where the default is

616
00:39:18,706 --> 00:39:20,346
so that would actually
be interesting

617
00:39:20,756 --> 00:39:31,586
if I had instead just gone there
it would have chosen editing end

618
00:39:31,966 --> 00:39:34,526
which is in fact not what
I wanted in this case.

619
00:39:36,096 --> 00:39:37,836
So something to be
aware of if you--

620
00:39:39,476 --> 00:39:43,166
>> So right now are you
using option or control?

621
00:39:43,216 --> 00:39:51,066
>> Chris Gerber: I'm using
control at the moment.

622
00:39:51,656 --> 00:39:58,356
All right, okay, let's go
back to the slides here.

623
00:39:58,496 --> 00:40:04,156
All right, so property lists.

624
00:40:04,156 --> 00:40:06,646
Property lists are going
to be very important

625
00:40:06,646 --> 00:40:09,226
for what we're doing because
the words we give you are

626
00:40:09,226 --> 00:40:11,666
in a property list so that's a
very important starting point

627
00:40:11,666 --> 00:40:15,936
for you but basically property
lists are just key value pairs.

628
00:40:16,716 --> 00:40:18,746
You've got a way to look it up

629
00:40:18,746 --> 00:40:20,266
and what the result is
when you look it up.

630
00:40:20,686 --> 00:40:23,526
It's stored in XML which
you can just edit manually.

631
00:40:23,526 --> 00:40:26,676
It's a standard XML file or
you can use the plist editor

632
00:40:26,676 --> 00:40:29,206
which gives you a little
more of a gooey feel to it.

633
00:40:29,206 --> 00:40:30,656
It might make it
a little easier.

634
00:40:31,256 --> 00:40:34,906
Frequently, property lists
are used to store settings

635
00:40:35,036 --> 00:40:36,526
and that is probably something

636
00:40:36,526 --> 00:40:38,686
that will be useful
for you as well.

637
00:40:38,976 --> 00:40:43,736
You don't have to worry
about a lot of this

638
00:40:43,786 --> 00:40:46,366
but this is what a property
list would actually look like.

639
00:40:46,496 --> 00:40:48,946
The first few lines
here just say

640
00:40:48,946 --> 00:40:51,026
that essentially this
is a property list.

641
00:40:51,576 --> 00:40:52,776
We don't have to
worry about that.

642
00:40:52,776 --> 00:40:54,696
Where it gets more interesting
is as we get in here.

643
00:40:55,456 --> 00:40:58,486
So in this case in my property
list happen to have a dictionary

644
00:40:59,366 --> 00:41:02,296
that has a key and a string.

645
00:41:02,296 --> 00:41:06,766
So this is my key value
pair and it's standard XML

646
00:41:06,766 --> 00:41:11,756
and you can go from there.

647
00:41:11,956 --> 00:41:15,986
Interesting and useful to
note is that NS dictionary

648
00:41:15,986 --> 00:41:20,666
and NS array have methods to
init with contents of file

649
00:41:21,026 --> 00:41:24,136
to read in plist files
and they also have methods

650
00:41:24,136 --> 00:41:27,086
to write out plist files.

651
00:41:27,276 --> 00:41:31,706
Also NS bundle has a method
called path for resource of type

652
00:41:32,596 --> 00:41:35,726
which lets you get to files
in your local file system.

653
00:41:36,626 --> 00:41:38,696
So obviously we're going
to give you the plist file.

654
00:41:38,696 --> 00:41:40,566
It has to get on the device
and you have to have a way

655
00:41:40,566 --> 00:41:41,676
to find it and read it.

656
00:41:41,786 --> 00:41:43,396
So these are both going
to be very important

657
00:41:43,426 --> 00:41:45,706
for you should you be
using plists [inaudible]

658
00:41:45,816 --> 00:41:47,076
to do your work.

659
00:41:47,406 --> 00:41:55,316
We can look at that quickly as
well and we'll go back to Xcode

660
00:41:55,766 --> 00:41:58,536
and currently this is right

661
00:41:58,536 --> 00:42:01,596
in the same application I just
did not show it to you yet

662
00:42:02,166 --> 00:42:06,096
and I really haven't put much
beyond it, much into it but it's

663
00:42:06,096 --> 00:42:08,286
as good a chance for us to
see what the [inaudible] looks

664
00:42:08,286 --> 00:42:16,506
like as well since we
haven't covered much of that.

665
00:42:16,726 --> 00:42:19,866
There we go.

666
00:42:20,076 --> 00:42:22,776
So you remember when I started
I had a breakpoint in my code

667
00:42:23,046 --> 00:42:24,246
that was causing us problems?

668
00:42:24,566 --> 00:42:26,386
That was my breakpoint.

669
00:42:28,236 --> 00:42:32,456
In my view did load function
I added two commands.

670
00:42:32,906 --> 00:42:36,786
I added a new variable
file with path

671
00:42:37,166 --> 00:42:38,986
that is going to use NS bundle.

672
00:42:39,086 --> 00:42:41,326
It's going to use our main
bundle which is predefined.

673
00:42:42,376 --> 00:42:44,996
It's going to do
path for resource.

674
00:42:45,806 --> 00:42:49,406
We've got an NS string here
called words and of type

675
00:42:49,556 --> 00:42:53,156
of plist and this is
basically going to say go

676
00:42:53,156 --> 00:42:54,646
into your main bundle which is

677
00:42:54,646 --> 00:42:57,126
where your application
is storing its data.

678
00:42:58,096 --> 00:43:04,486
Look for a file called words
that is a words.plist file.

679
00:43:04,696 --> 00:43:09,046
Once we've got that path built
I'm using an NS mutable array

680
00:43:09,636 --> 00:43:10,876
to store some words.

681
00:43:11,306 --> 00:43:14,686
It's going to allocate that
array and I'm just going

682
00:43:14,686 --> 00:43:17,746
to use init with contents
of file, file of path.

683
00:43:17,936 --> 00:43:22,256
So this is essentially
going to load my file.

684
00:43:22,476 --> 00:43:28,846
Where we can see that is
when we hit run we are going

685
00:43:28,846 --> 00:43:31,426
to hit a breakpoint.

686
00:43:37,596 --> 00:43:41,466
You'll see that file with
path did in fact get set

687
00:43:42,236 --> 00:43:45,116
to this long thing
on my file system

688
00:43:45,376 --> 00:43:50,006
but then the other
thing you'll see is

689
00:43:50,006 --> 00:43:56,016
that words is now an NS mutable
array with 233 thousand objects

690
00:43:56,526 --> 00:44:03,226
and I could actually start
looking at what that looks like.

691
00:44:03,226 --> 00:44:05,646
So it went by very quickly.

692
00:44:05,646 --> 00:44:12,016
I just did a PO words
which is off the screen,

693
00:44:12,016 --> 00:44:25,396
sorry about that, and
it doesn't want to go

694
00:44:25,996 --> 00:44:30,856
and I can't go any higher.

695
00:44:31,286 --> 00:44:36,836
All right, trust that
this is PO words.

696
00:44:37,336 --> 00:44:39,446
PO is short for print object.

697
00:44:39,546 --> 00:44:43,256
At any point when you're at
a breakpoint you can use PO

698
00:44:43,256 --> 00:44:45,066
to print the contents
of an object

699
00:44:45,276 --> 00:44:46,346
in the output window here.

700
00:44:46,656 --> 00:44:50,026
You can also use just straight
P if it's not an object.

701
00:44:50,496 --> 00:44:51,236
So remember things

702
00:44:51,236 --> 00:44:57,496
like intra-traditional data
types are not objects but things

703
00:44:57,496 --> 00:45:01,946
like NS string, NS dictionary,
etcetera are so you can use

704
00:45:01,946 --> 00:45:03,776
that in your development
as well.

705
00:45:04,246 --> 00:45:10,226
And we're in the
home stretch here.

706
00:45:10,446 --> 00:45:21,076
So as you start thinking about
settings you might also want

707
00:45:21,076 --> 00:45:23,876
to look at this other
object NS user defaults

708
00:45:24,086 --> 00:45:25,476
and there are a number
of methods here

709
00:45:25,476 --> 00:45:26,566
that I think you'll find useful.

710
00:45:26,936 --> 00:45:29,726
Register defaults lets
you pre-store defaults

711
00:45:29,726 --> 00:45:33,736
for your application but then
you can use things like integer

712
00:45:33,736 --> 00:45:36,526
for key to read an
integer, set integer for key

713
00:45:36,526 --> 00:45:39,676
to set an integer
into these defaults,

714
00:45:40,176 --> 00:45:42,176
string for keys,
set object for key.

715
00:45:42,516 --> 00:45:45,576
You remember you might think
there should be set string

716
00:45:45,576 --> 00:45:47,786
for key where a string
is just an object,

717
00:45:47,786 --> 00:45:49,236
it's an NS string
so it's an object.

718
00:45:49,236 --> 00:45:54,506
And there's plenty more but
that's just one more hint

719
00:45:54,506 --> 00:45:56,346
to help you work through
your project here.

720
00:45:56,676 --> 00:45:58,986
That is the end of my slides.

721
00:45:59,446 --> 00:46:01,916
Are there any other
questions for the walk

722
00:46:02,006 --> 00:46:03,526
through of Evil Hangman?

723
00:46:04,046 --> 00:46:04,226
Yes.

724
00:46:04,226 --> 00:46:04,816
>> [Inaudible question]

725
00:46:04,816 --> 00:46:08,726
>> Chris Gerber: So yeah,
the question is around,

726
00:46:09,166 --> 00:46:17,806
the spec says we should handle
backgrounding the application

727
00:46:17,806 --> 00:46:23,686
and basically what that means is
if you are playing Evil Hangman

728
00:46:24,026 --> 00:46:29,936
and either someone hits the home
button or uses the task manager

729
00:46:29,936 --> 00:46:32,376
to switch to another app
or a phone call comes in

730
00:46:32,376 --> 00:46:34,376
or whatever happens
that interrupts the flow

731
00:46:34,376 --> 00:46:39,156
of your application what should
happen is the application will

732
00:46:39,156 --> 00:46:40,156
move to the background.

733
00:46:40,156 --> 00:46:43,766
It will be in a frozen state
but when it comes back,

734
00:46:43,766 --> 00:46:46,306
when Evil Hangman is
run next it should pick

735
00:46:46,306 --> 00:46:47,516
up where you left off.

736
00:46:48,026 --> 00:46:49,896
So if you had guessed three
letters and you were half way

737
00:46:49,896 --> 00:46:52,136
through your game it should
know you're in the middle

738
00:46:52,136 --> 00:46:55,646
of that game and try
to continue playing.

739
00:46:55,646 --> 00:46:57,306
Certainly if you
ran out of memory

740
00:46:57,306 --> 00:46:59,106
and the application
crashed or something

741
00:46:59,106 --> 00:47:00,936
like that the state
wouldn't come back

742
00:47:01,066 --> 00:47:07,246
but in any case we can reserve
state if we want it to do that.

743
00:47:07,746 --> 00:47:12,496
>> [Inaudible question]

744
00:47:12,996 --> 00:47:15,126
>> Chris Gerber: So the question
asked was whether we have

745
00:47:15,126 --> 00:47:17,876
to use NS user defaults
to save the game state

746
00:47:18,336 --> 00:47:20,346
when the application
is backgrounded?

747
00:47:20,746 --> 00:47:22,366
You do not need to do that.

748
00:47:22,366 --> 00:47:24,176
NS user defaults should be used

749
00:47:24,176 --> 00:47:27,266
for when you're first
launching the application

750
00:47:27,826 --> 00:47:31,326
or when you're starting
a new game potentially

751
00:47:31,616 --> 00:47:40,196
or when you are saving
changes to your settings.

752
00:47:40,196 --> 00:47:40,696
>> [Inaudible question]

753
00:47:40,696 --> 00:47:42,816
>> Chris Gerber: So
your question is then

754
00:47:42,906 --> 00:47:46,206
when it backgrounds the state
will be saved automatically?

755
00:47:46,866 --> 00:47:50,726
And the answer to
that would be yes.

756
00:47:50,726 --> 00:47:50,793
>> [Inaudible question]

757
00:47:50,793 --> 00:47:53,776
>> Chris Gerber: The
question is can we say

758
00:47:53,776 --> 00:47:55,346
that if you leave
the game you lose?

759
00:47:55,916 --> 00:47:58,586
That sounds very
evil but that is not

760
00:47:58,586 --> 00:48:02,216
in compliance with
our spec. Yes.

761
00:48:02,216 --> 00:48:02,736
>> [Inaudible question]

762
00:48:02,736 --> 00:48:07,216
>> Chris Gerber: So the
question is do we actually have

763
00:48:07,296 --> 00:48:09,666
to draw a hangman?

764
00:48:09,796 --> 00:48:13,126
You certainly have the option of
drawing arms and legs, etcetera

765
00:48:13,126 --> 00:48:16,346
but you can also just
for example use a count

766
00:48:16,346 --> 00:48:23,606
down that says "I have
five guesses left."

767
00:48:23,856 --> 00:48:24,366
Yes.

768
00:48:24,366 --> 00:48:25,186
>> [Inaudible question]

769
00:48:25,186 --> 00:48:34,526
>> Chris Gerber: So the question
is the application needs

770
00:48:34,526 --> 00:48:40,316
to handle low memory warnings
by reloading views as needed.

771
00:48:41,326 --> 00:48:42,696
So essentially if you were

772
00:48:42,696 --> 00:48:49,186
on the MainViewController the
FlipsideViewController can go

773
00:48:50,196 --> 00:48:50,926
out of memory.

774
00:48:50,986 --> 00:48:53,916
It can be discarded which means

775
00:48:53,916 --> 00:48:57,346
that when it initializes
you might need to reload

776
00:48:57,346 --> 00:48:59,766
from NS user defaults to see
what the settings are things

777
00:48:59,766 --> 00:49:04,726
like that or if you are
on the Flipside the state

778
00:49:04,726 --> 00:49:06,746
of your screen might
not be preserved.

779
00:49:06,746 --> 00:49:08,416
You might have to go over
to redraw the screen.

780
00:49:08,896 --> 00:49:13,546
There are the callbacks are
already there for things

781
00:49:13,546 --> 00:49:17,076
such as view-- I'd have to
look up the actual callback

782
00:49:17,076 --> 00:49:19,936
that you'll see but there are
callbacks that should show

783
00:49:19,936 --> 00:49:21,526
up in the template applications.

784
00:49:21,976 --> 00:49:22,576
They used to.

785
00:49:22,576 --> 00:49:23,536
I don't know if they still do

786
00:49:24,176 --> 00:49:26,626
that will let you
detect those states

787
00:49:26,776 --> 00:49:29,626
and determine what
you need to do.

788
00:49:29,626 --> 00:49:41,256
But we can look at that a little
more when I can look it up.

789
00:49:41,256 --> 00:49:41,323
>> [Inaudible question]

790
00:49:41,323 --> 00:49:42,946
>> Chris Gerber: Yes, did
receive memory warning.

791
00:49:45,376 --> 00:49:56,886
>> Is it a smart idea to
just use memory [inaudible]

792
00:49:57,006 --> 00:49:58,706
>> Chris Gerber: So the
question is is it all right

793
00:49:58,766 --> 00:50:01,826
to keep using memory willy-nilly
until you get a warning

794
00:50:01,826 --> 00:50:03,186
or should you be proactive?

795
00:50:03,806 --> 00:50:06,836
I would say the best practice
would be to be proactive

796
00:50:06,996 --> 00:50:11,436
and that you should certainly
not just completely abuse memory

797
00:50:11,436 --> 00:50:18,016
on the system to
make things easy.

798
00:50:18,616 --> 00:50:18,766
Yes.

799
00:50:18,766 --> 00:50:19,446
>> [Inaudible question]

800
00:50:19,446 --> 00:50:21,556
>> Chris Gerber: So the
question is will we be using

801
00:50:21,556 --> 00:50:22,436
story boards?

802
00:50:22,596 --> 00:50:27,336
And that I believe is to
the person's discretion.

803
00:50:27,386 --> 00:50:29,146
Certainly what we presented

804
00:50:29,146 --> 00:50:31,686
so far formally is
not using story boards

805
00:50:32,256 --> 00:50:35,986
but you are certainly welcome
to use them in your app.

806
00:50:36,216 --> 00:50:39,256
In this case it's pretty much
as simple as checking the box

807
00:50:39,316 --> 00:50:42,266
because if we're really just
using the two flip sides

808
00:50:42,336 --> 00:50:44,056
but if you wanted to change
your segue or something

809
00:50:44,056 --> 00:50:46,346
like that you can
do that much easier

810
00:50:46,806 --> 00:50:47,936
through the story
boards I would think.

811
00:50:48,206 --> 00:50:50,086
So yeah, it's fine to
use them or fine to not.

812
00:50:51,366 --> 00:50:55,926
>> Chris, I may say
something really stupid

813
00:50:56,006 --> 00:50:59,476
but the way I understand it is
you load the whole dictionary

814
00:50:59,706 --> 00:51:02,416
and you define the number
of letters of the words.

815
00:51:02,416 --> 00:51:04,666
Let's say three letters, okay?

816
00:51:04,866 --> 00:51:07,146
So then the guy says
okay, I have an E.

817
00:51:07,826 --> 00:51:09,546
So then you eliminate
all the words--

818
00:51:09,546 --> 00:51:14,946
first of all you eliminate
all the words don't have

819
00:51:14,946 --> 00:51:15,616
three characters.

820
00:51:16,626 --> 00:51:21,166
Then you eliminate all
the words that have an E?

821
00:51:21,166 --> 00:51:22,286
>> Chris Gerber:
Not necessarily.

822
00:51:22,286 --> 00:51:26,676
Yeah, so the question
to summarize was

823
00:51:26,676 --> 00:51:31,886
around the equivalence
classes and also word blanks.

824
00:51:32,376 --> 00:51:37,836
So for word blanks you can
most likely very simply trim

825
00:51:37,836 --> 00:51:40,526
down to just words of known
length and that's fair

826
00:51:40,946 --> 00:51:43,226
to describe the others
rather quickly.

827
00:51:43,226 --> 00:51:43,293
>> [Inaudible question]

828
00:51:43,293 --> 00:51:44,156
>> Chris Gerber: Yes.

829
00:51:44,156 --> 00:51:52,876
So the question is
will there be a slider?

830
00:51:52,956 --> 00:51:54,636
There will be a slider.

831
00:51:55,376 --> 00:51:59,136
When you set that that will
set what the state will be

832
00:51:59,196 --> 00:52:01,236
for the next time
you start the game.

833
00:52:01,716 --> 00:52:05,746
So when the start new game
button is hit you can then

834
00:52:06,196 --> 00:52:09,276
or when the application very
first launches you can load the

835
00:52:09,276 --> 00:52:12,056
dictionary and potentially
prune down to just words

836
00:52:12,056 --> 00:52:13,666
of the currently
configured blank.

837
00:52:14,926 --> 00:52:16,756
The other part to your
previous question was

838
00:52:16,756 --> 00:52:18,036
around equivalence classes.

839
00:52:18,436 --> 00:52:21,636
If the letter E was chosen you
do not automatically discard all

840
00:52:21,636 --> 00:52:23,796
the words that have
the letter E in them.

841
00:52:24,236 --> 00:52:26,926
You look for the group of words

842
00:52:27,456 --> 00:52:30,666
that has the most
available choices left.

843
00:52:31,576 --> 00:52:34,006
So if that word happens
to have an E in it

844
00:52:34,146 --> 00:52:37,876
but it gives you a much longer
list of possible choices

845
00:52:38,126 --> 00:52:39,796
that could be a better choice

846
00:52:40,456 --> 00:52:43,916
than discarding those
that don't have Es.

847
00:52:44,386 --> 00:52:45,526
All right, any other questions?

848
00:52:50,516 --> 00:53:05,700
[Silence]

