WWDC2018 Session 203

Transcript

[ Music ]
>> Hi everyone!
Good morning!
[ Applause ]
Thanks, everyone, for being here
today.
My name's Jesse Pease.
And I'm an engineer on the
Health Engineering Team.
And today, I'm going to show you
how to make your very first app.
So today we're going to step out
of our comfort zones.
We're going to explore, and
we're going to start building
our dream app.
You know that one that you've
had in the back of your mind
while you're waiting in line for
your coffee in the morning?
Or that one that you drew out on
your napkin on the flight out
here to WWDC?
Or that one that you tell your
friends about and make them
promise not to tell anyone else?
That one. That's the idea we're
going to start working on today.
As Joseph Chilton Pearce said,
"To live a creative life we must
lose the fear of being wrong."
And when we start building new
ideas, we're bound to run into
bumps in the road.
But our goal today is to show
you all the building blocks you
need to make your dream app a
reality.
We're going to start off today
by organizing our ideas.
Then we're going to learn how to
navigate Xcode.
And then build a simple game
using Swift.
Now familiarity with a
programming language will help
you today.
But if you're new to Swift or
looking for a helpful resource,
I recommend downloading the App
Development with Swift book from
the Apple bookstore.
Or checking out the Swift
Playgrounds app for iPad.
Later [inaudible] is going to
show you how to add multiple
views within your app and then
persist in display data for your
users over time.
So Tono [phonetic] and I were
recently at a unicorn petting
zoo.
Yes, we actually have these in
California.
And we were after having this
experience countless times of
waiting in line.
We decided that we needed to
make something to keep ourselves
occupied while we wait.
So we decided to make a game.
Something quick and fun to keep
us occupied for a short amount
of time.
And I said, "Well, of course if
we make a game, it has to have
unicorns."
But then we needed something
that people would want to avoid.
Maybe poop.
And so we decided to make a
whack-a-mole-type game with
unicorn and poop.
And then incorporate scores and
eventually a leaderboard to keep
track of our scores over time.
Because we have a little bit of
a competitive nature.
So let's take a look at what
this game play looks like.
Upon pressing start game, a
random emoji's going to appear
somewhere randomly on the
screen.
Either a unicorn or a poop.
At that point, the user has one
second to click that button.
Now, if they hit the unicorn,
then they get one point.
Then if they accidentally tap
the poop, then the game is over.
But in addition to this, if they
miss the unicorn, the
not-so-lonely unicorn, and so
they automatically lose the
game.
So the goal is hit all the
unicorns.
Don't hit the poops.
Let's take a look at this.
Get it! Nice!
Get that unicorn.
Oh! There we go, one more.
Oh! Oh, shoot.
Moving too quickly and
accidentally hit a poop.
Let's jump right in.
So for those of you who aren't
familiar, Xcode is a tool we use
on macOS to help build iOS,
macOS, watchOS, and tvOS apps.
You can download it from the App
Store if you don't have it
already.
So when we open up Xcode, we
first want to select create a
new Xcode project.
After this, we see all the
different type of app templates
that we can create.
In our case, we're going to
select single view app.
But notice here that you could
also select a page based app, a
sticker pack app, or even a
game.
But our game is very simple, so
we will just stick with single
view app.
And then hit next.
From here we type in our app
name, which in our case is
Disappearing Unicorns.
And our ex-- , our team name is
Example Team.
And hit next.
After we choose a place to save
our app, we're dropped into the
project settings.
Now we won't be making any
changes here today, so we'll go
ahead and look at the other
important files in our Project
Navigator on the left-hand side.
The first one is the
AppDelegate.
An AppDelegate is created for
each app, and it helps us manage
the lifecycle of our app over
time.
There's certain methods that can
be called when we're going into
the background or coming into
the foreground.
But we won't be making any
changes with our AppDelegate
today either.
Next I'm going to select the
main storyboard file.
The storyboard is where we
create the UI or the user
interface for our app.
And where we can add all of the
UI elements like buttons,
labels, or images.
But it's not just where we
create that one single view.
It's also where we lay out all
of the logical flow for our app
over time.
The story.
Next we'll select the view
controller.
The view controller helps us
control out view, and this is
where we'll write the logical
code for our app.
Well let's talk about how we
create our views within our
storyboard.
Let's navigate back over to the
main dot-storyboard file.
And at this point, make sure not
to select the
launchscreen.storyboard.
The launchscreen storyboard is
what we use to create the view
for when our app is being
launched or loaded onto the
screen the first time.
You'll notice in the upper
right-hand corner of our
storyboard here that there's an
object library button.
This is a button with a circle
and a little square inside.
This is where we can take things
like buttons or labels or images
and drag them onto our
storyboard.
On the left-hand side, you'll
see the outline view for our
app.
And if you click the little
disclosure triangle, you'll see
all the different things that
are currently on our storyboard.
Now you're thinking to yourself,
"There's nothing on this
storyboard.
Why is this helpful?"
Well, in the future, you may
have lots of elements on your
storyboard.
And eventually you may not be
able to find something because
it could be under something
else.
Or maybe you've accidentally
created duplicates.
So this is a great place to go
if you're looking for all of the
elements that you've put on your
storyboard.
Alright. Let's go ahead and jump
into our demo and start making
our app.
So here I'm going to go over to
my computer where I already have
Xcode launched.
Okay. And I have my Disappearing
Unicorns file.
Here I'm navigating to the main
storyboard.
And let's go ahead and start off
by adding all of those UI
elements that we need to create
our game.
So I'm going to go up to the
object library.
And I can scroll through here
and see all of the different
things that I can put on there.
We have labels, buttons, text
fields, activity indicators,
even images.
But let's start off with that
start-game button.
So here I'll search for button.
And click and drag the button to
the center of my storyboard.
Here I'll double click to change
the text to start game,
exclamation point.
But this is a little bit small.
So in order to make this larger,
I can go to the upper right-hand
corner of Xcode and open up the
Inspector pane.
And then select this little
slider button which is the
Attributes Inspector.
This is where we change
attributes of the items on our
storyboard.
In this case, I'm going to make
my font much bigger.
From size 15 to size 50.
And hit done.
Now to quickly create copies of
items on our storyboard, I can
hold down the option key and
click and drag on my storyboard
to quickly create another copy
of this button.
And so in this case, I'm going
to change start game to the
emoji for a unicorn.
And to pull up the emoji
keyboard, I can hit the
control-command-space key and
select unicorn.
Great! Let's go ahead and make a
quick copy of this as well for
our poop.
Control-command-space and poop.
Awesome. And one more button for
our leaderboard button.
So click, option, drag.
Double click leaderboard.
Uh-oh. Not all caps.
And change our font here from
size 50 to size something much
smaller.
Maybe 25. Awesome.
Now we need one more element on
our storyboard which is a label
for our points.
So go back to my object library
and search for label.
And then click and drag this
onto the screen.
Here I'm going to change this
text to be zero.
And then change the font to
something much larger like size
90.
Awesome! There we go.
Now we have all of the UI
elements that we need to create
our game.
Let's go ahead and start
connecting our UI to our code.
Now to have both the storyboard
and the view controller code up
at the same time, I can open up
this Assistant Editor.
It's the button with two
overlapping circles.
Awesome. Now there's a bunch of
different types of connections
that we can make between the
objects on our storyboard and
our code.
Now the first type is called an
outlet, and an outlet lets us
refer to our user interface
within our code.
Let's start out by creating an
outlet for this start game
button.
To create an outlet, I select
the start-game button on the
storyboard, hold down the
control key, and click and drag
over to my storyboard.
Sorry, over to my view
controller code, and let go.
At this point, I change my
connection from-- type-- oh,
it's already outlet.
Perfect. And I'm going to name
this start game button and hit
connect.
Awesome. Now we have a
connection between our code and
our storyboard.
And we can double check that
this connection was made
correctly, by seeing this little
gray circle to left of
start-game button.
If we hover over it, it
highlights the item on our
storyboard that is connected to
this code.
Now, in the interest of time,
I've already written the code
for our other outlets.
But you'll notice that to the
left of them, they have open
circles.
This means that they haven't
been connected to our storyboard
yet.
To make the connections, we just
click inside the circle to the
left of good button in this
case.
And drag over to our unicorn
button which is the button we
want to be associated with this
line of code.
And let go.
We'll do the same thing for bad
button, leaderboard button, and
points label.
Awesome. Now all of these
connections have been made.
Now another type of connection
we can make is called an action.
And an action is a piece of code
that's linked to an event that
can occur within our app.
In this case, I want an action
method for whenever my
start-game button is pressed.
So to create this connection, I
could hold down the control key
once again with the start-game
button and click and drag over
to my view controller code.
And let go.
This time I will change my
connection to type action and
name this start pressed.
And I want my event to be a
touchup inside event, and hit
connect.
Awesome. You'll notice that
there's this closed circle once
again.
And when I hover over it, the
start-game button is
highlighted.
Now I've already written two
other action methods for both
our good pressed and our bad
button pressed.
But I actually want to make a
different type of connection
this time.
I want to create an event or an
action event for when I press
down on my button.
Because I want my user to get
the point immediately when they
touch the button.
Not when they've touched down
and then back up.
I want to select the object that
I want to be associated with
this action.
In this case, my good button or
my unicorn.
Then go back to my Inspector
pane and click on this little
button with the circle with a
little arrow inside.
This is called our Connections
Inspector.
From here you'll see all the
different types of sent events
that I can create a connection
for.
In this case, I want to create a
connection for the touch-down
event.
I'll click inside this open
circle, and drag over to the
action method that I want to be
associated with this event.
And let go.
I'll do the same thing with my
bad button.
Touch-down, click, and drag over
to bad pressed and let go.
Okay, great.
Just two more things that we
want to do before we can build
and run our app for the very
first time.
The next thing we want to do is
we want to do a little bit of
set-up for our app.
And we can do this in a method
called viewDidLoad.
And a viewDidLoad is created for
a view controller at the very
beginning automatically.
And in here, what I want to do
is a bit of setup.
In this case, I want to hide
some things.
The first thing I want to hide
is that points label.
I don't want that on the screen
the very beginning of our game.
So I'll just type points label
dot-- hmm.
How about hide?
Oh look? Looks like there's a
property called isHidden.
And if I hit enter, it'll
autocomplete into Xcode for me.
To see what isHidden does, I can
hold down the option key on my
keyboard, hover over isHidden
and click.
When I do this, I can read a bit
more about what isHidden is, and
what I can do with it.
In this case, I see that it's
both a getter and a setter.
Which means that I can set
isHidden equal to true, and it
should hide my points label at
the very beginning of my game.
Now I also need some variables
to keep track of my gameplay
over time.
And I've already written these,
so I'll quickly add them using a
shortcut.
One of them needs to be, it's
already initialized, but I
actually need to populate it
with some data.
And that's this game buttons
list.
Now you're thinking to yourself,
"Jessie, if we only have a
unicorn and a poop, why would we
need to create a whole array of
buttons?"
Well, in our case we want to
make our code more extensible
which means make it easier to
build on over time.
Because in the future, we may
have more than just the unicorn
and the poop.
We may have a thumbs-up emoji.
We may have a frowny-face emoji.
So in this case, we want to say
that game buttons equals list of
good button and bad button.
Okay. I've also written some
helper methods that will help us
with our gameplay.
I'm going to add those now.
One of them is this method
called set up fresh game state.
You'll notice that it makes sure
that the start game and
leaderboard button are unhidden.
They're onscreen.
It hides my gameplay buttons,
and it sets up some initial
values for my points.
So here in my viewDidLoad, I
also want to call up set up
fresh game state.
You'll notice here as I'm
typing, Xcode is autocompleting
all of the things that I could
possibly put as some code.
In this case, if I hit enter
with set up fresh game state
already highlighted, it'll
automatically populate it for
me.
Okay. One last thing we want to
do, and then we can build and
run our app.
Just for sanity, in my start
pressed method, action method,
I'm going to put a print
statement here.
And say start game button was
pressed.
And I expect that every time I
press that start-game button,
this line of code will be logged
to my console.
I can show my debug area by
opening up this middle button
here with the line on the bottom
of the square.
I'm going to hide my Inspector
pane.
I don't need that anymore.
Okay. It's finally time.
We can build and run our app.
Now in the upper left-hand
corner, you'll notice that my
app name, Disappearing Unicorns,
with a little arrow to an iPhone
10.
If I click on iPhone 10, I can
see all the different simulators
that I can run my app on.
Now a simulator is a simulation
of a device on my Mac.
And in this case, I want to
select iPhone 10.
Now if I had plugged my phone
into my computer, I could also
build and run my app on my own
device which is pretty cool.
So with iPhone 10 selected, I
can click this play button here.
This will build and run my app
in my simulator.
Here we go.
Oh, nice! Okay, so when I press
this start-game button, I should
see that the start-game button
was pressed is logged in my
console down here.
Awesome! We've just created a
UI, and we've connected it to
our code.
Let's jump back over and start
talking about the game logic for
our app.
Okay, so in the very beginning
of our game, we know we have
that start screen, and it has
two buttons on it.
It has that start-game button
and that leaderboard button.
But we're just talking about the
gameplay right now.
So we're going to wait for the
start-game button pressed.
And once that button is pressed,
we drop into playing mode.
And at the beginning of playing
mode, we get a random emoji in a
random location on the screen.
Either a unicorn or a poop.
At that point, we set a timer
for one second to allow our user
to have time to interact with
our button.
Now at the end of that one
second, if the user did not
press a unicorn, then the
unicorn was lonely, and they
lose.
And if they successfully avoided
tapping a poop, then they get
another round of the game.
Now we also want to say what
happens if they actually do
press one of the buttons during
the game.
Well if they press the unicorn
button, we give them another
round of the game and give them
a point.
Otherwise, if they accidentally
select the poop, then game over.
Okay. Let's talk about what this
code looks like.
We'll start off with the start
screen.
Now we're going to break up our
code into logical blocks.
And in our case, we're going to
use methods to do this.
So that it's not just one long
file full of lots of code.
And it's easier for us to look
at very specific parts.
The first method we're going to
write is called start new game
which we're going to call from
start pressed.
This is going to do some setup
for the beginning of a game
route.
The first thing that happens in
start new game is that we need
to hide that start-game button
and hide that leaderboard
button.
Then we need to update our
points label and set it to zero.
And we can even do some cool
things here like dynamically
change the color of our points
label throughout our code.
And here I'm going to set that
text color to magenta during
active gameplay.
Finally at the end of setting up
my start new game, I'm going to
call the first round of my game.
Okay? Let's look at that.
In our one-game round, we first
update our points label, make
sure that it's up to date.
Then we display a random button.
Either that unicorn or that poop
in a random location on our
screen.
I've written this helper method
display random button that
chooses a random x and y
coordinate to place our button.
Then we set a timer for one
second.
Now, if this timer goes off
after one second, then the code
inside the block of the timer
will get called.
And in that case, we want to
check if the current button
that's on screen is a unicorn,
then the game is over.
Because the user left a lonely
unicorn again.
Otherwise, if they successfully
avoided the poop and that's
still onscreen, they get another
round of our game.
Now let's talk about what
happens if they did press one of
our buttons.
Well if they pressed the good
button, we want to give them
another point.
We actually want to cancel our
timer.
And we're going to do this by
invalidating it so that it
doesn't go off, and then we'll
call another round of our game.
And if they press the bad
button, well let's hide that
button and get it out of the way
so that they can't interact with
it again.
We'll cancel the timer again by
calling invalidate on it.
And then call game over which is
a helpful method that I've
written to help end the game.
Okay, let's add this game logic
into our game.
Going to go back over to our
Xcode project.
And in this case, I don't need
my storyboard up anymore.
I'm just going to be making
changes to my view controller.
So I can select here the
standard editor, and then select
my view controller from my
Project Navigator.
Now, we've already written our
code in our slides.
So I'm going to just quickly add
it into our view controller
using some shortcuts.
So here we have start new game
where we hide our start game and
our leaderboard button.
Set up some initial stuff with
our game points, and then call
one round of our game.
Then we need our one-game round.
And here we update our points
label, display random button,
and call our timer.
And finally we need to put the
code and for the logic in our
both our start pressed.
And our good pressed.
And finally our bad pressed.
Okay. We have all the code we
need.
Let's see how it goes.
Here I'm going to click this
play button again to build and
run our app in the simulator.
Okay, I'm nervous.
Let's go.
Oh! Got one!
Where's another?
There's a lot of poops.
There we go.
Okay, I could seriously play
this all day, but I probably
should let [inaudible name] show
you how to incorporate a
leaderboard.
Whew! So I'm going to try and
lose on purpose here.
Oh, there we go.
Okay. Wow, yeah.
That's great.
[ Applause ]
That was incredible!
We just made a game in less than
30 minutes.
Just think about what you could
do if you had more time.
So we first started out by
learning to navigate Xcode.
Then we created a simple UI
using our storyboard and
connected that UI to our code.
And finally we wrote game logic
using Swift.
All in less than 30 minutes.
Now if we had more time, let's
think about some things that we
could do to take this further.
Well we just used simple UI
elements like buttons and
labels.
But you could use a framework
like SpriteKit to create more
imaginative buttons that have
elements like gravity or physics
associated with them.
We could also add MusicKit
integration and have Apple music
songs playing in the background
during active gameplay.
Or we could read from sensors
and change the speed of our game
based on the user's movement.
Here are three talks from
previous WWDCs that I highly
recommend you check out.
Introduction to SpriteKit from
2013.
Introducing MusicKit from last
year.
And Creating Immersive Apps with
Core Motion from last year as
well.
Thank you so much.
I'm going to welcome [inaudible
name] on the stage to show you
how to add additional screens to
your app.
[ Applause ]
>> Good morning, everyone.
I hope you've enjoyed building
the game with poops and
unicorns.
My name is [inaudible name] and
I'm here to help you add some
awesome features to your apps.
Along the way we'll learn about
APIs and frameworks that are
commonly used across iOS.
First, let's take a look at the
features we want to add to our
game.
We would like to introduce a
leaderboard where we can see
names and the points for each
person who's played our game.
When we tap on a name, we want
to see more information about
that person.
As we build our app today, we'll
focus on three main areas.
One is the data.
Where should we store
information about our users?
How do we retrieve this data?
Second is the user interface.
What does the leaderboard look
like?
What use should it have?
And finally, we'll talk about
the logic that's used for
managing [inaudible] for passing
data, and for doing other tasks
within our apps.
If we break down our app into
these three categories, then we
would actually end up following
a really popular architectural
pattern known as the
model-view-controller.
The model-view-controller
represents the data in the
model.
The UI is represented as the
view.
And the controller is the logic
that communicates with both the
model and the view.
This pattern helps us group
together similar tasks.
And it makes it easy for us to
make changes to one part of our
app without impacting the
others.
In iOS, the controller can be
represented as a subclass of the
UI-view-controller class.
The view can be a subclass of
the UI view class.
And the model can be a subclass
of NSobject.
When we build our app today, we
will take a closer look at the
different parts of the
model-view-controller.
Let's now jump into a demo and
build a model to store our data.
Here's the Disappearing Unicorns
project that we made with
Jessie.
Let me right click on the
Disappearing Unicorns folder and
say new file.
Select [inaudible] class which
is what most iOS classes are.
I'll click next, and I'll pull
my [inaudible] class data.
This will be a subclass of
NSobject which is a good parent
class for my data.
Let's hit next and create.
In this class, we want to store
information about the player.
So let me use a shortcut to add
some code I wrote before.
We have variables to store the
name, points, rank, and image
for each person.
In addition to this, I've added
some initializers to set up this
data.
But we don't need to worry about
those.
Let's go ahead and add one more
class by right-clicking on the
folder again and going to add
files.
This is the game data class that
I've written already.
Let's take a look at the methods
that have been implemented in
this class.
First, we have the save points
for name method.
This is used to save the total
game score for any given person.
Next we have the player data for
rank method which will give us
all the information about a
given player at a certain rank.
And finally, we have a property
to figure out the total number
of people who played our game.
We will not look at the
implementation details for these
methods today.
What's important is to
understand that we created a
separate set of files to hold
our data.
When you build your own apps, I
would encourage you to think
about your data as a separate
entity and keep it independent
of the user interface.
Just like how we've done here.
When it comes to actually saving
and retrieving the data on the
back end, we have a few
different options.
One is to use core data.
Core data is great for managing
objects on the disc.
It provides you with solutions
to validate, query, filter, and
organize your objects.
If however your data is on a web
server somewhere, then you could
use NSURLSessions to download
and upload the data.
Another great option is to use
CloudKit for storing data on the
cloud.
You could even use a third-party
cloud provider to manage your
cloud data.
Now that we've set up our data,
let's move onto the next section
where we build our user
interface.
Here's what we want our
leaderboard to look like.
I'll break this down into the
different viewers on the screen.
On the top we have a navigation
bar.
Below that is a table view which
has rows which are known as
table view cells.
Within each cell, we have an
image view on the left, and some
labels on the right to display
text.
Besides the leaderboard, we also
need to set up the details page.
This one's pretty
straightforward.
It has an image view and some
labels.
So now that we know what views
our UI is made up of, let's go
back into another demo and
actually set up this user
interface.
I'll select the main storyboard
which we built with Jesse.
Here we have a
single-view-controller which was
used to manage the entire screen
of content for the game.
Now we want to add more screens
for displaying our leaderboard
in the details view.
To do this, we can add another
view controller from the object
library.
I'll search for view controller.
Notice that there are a few
different options for view
controllers.
Since I want my leaderboard to
look more like a table, I'll
select the table-view-controller
and bring it into my storyboard.
The table-view-controller
automatically has a table view.
Let's select the table view and
look at the Attributes Inspector
on the right.
The content type here is set to
dynamic prototypes.
I'll change this to static
cells.
Static cells are great for
displaying static data.
And these can be easily set up
in the storyboard.
Now let's select a single cell
and change its style from the
Attributes Inspector to
subtitle.
This gives me a title and a
subtitle where I can display the
name and the points on my
leaderboard.
I also want to add an image to
the left of the row.
To do this, I can simply type in
the name of an image in the
Attributes Inspector's image
field here.
I have imported an image in my
project just as a sample.
Let me add that.
Okay. So now my cell is all set
up and we have a good outline
for our leaderboard.
Let's go ahead and add the
details UI.
I'll go back into the object
library, and this time we'll
take a blank view controller and
bring it into the storyboard.
Inside this view controller, we
will add an image view.
Let me set the image from the
Attributes Inspector.
Wait a minute.
This is a little scaled.
Let me change the content mode
from scale to aspect fit.
Much better.
Now I'll go back to the object
library and add some labels.
These are going to be used for
storing the name.
I'll make a copy.
Next one is for the rank, and
finally another label.
Going to make a copy.
Another label for the points.
Okay. Now that both our view
controllers are set up, there's
one other thing to do.
We need to tell our app to
actually display this
leaderboard or the details view
after we do a certain action in
the app.
Since we want the leaderboard to
be displayed after we tap the
leaderboard button.
I'll create a connection between
the leaderboard button and this
table-view-controller.
Let's hold down the control key
on the keyboard, and drag the
mouse from the leaderboard
button to the
table-view-controller.
When I release, I see a menu
with a few different options.
These are the different ways in
which we can present the second
view controller on top of the
first one.
For now, I'll select the show
option which is a commonly used
segue for such apps.
Notice that a connection got
created between the two view
controllers.
This is known as a segue.
Now, I want to display the
details-view-controller when I
tap on the cell in the
leaderboard.
So let's again hold down the
control key and drag our mouse
to the details-view-controller.
Select show one more time.
Now we are ready to run our app
for the very first time.
Let's look at the simulator.
If I tap the leaderboard, I see
a good mock-up for my
leaderboard.
I can tap on the cell and we
have our details view with more
information.
This is looking good.
But how do I go back to my
leaderboard or the game?
Let's go ahead and fix that.
To do this, I'll select the main
view controller which had the
game.
And then go to the editor menu
in Xcode, select, embed in,
navigation controller.
This adds a navigation
controller to our app.
The navigation controller is a
special type of view controller
that is used for managing the
back and forth transitions
between our view controllers.
This also adds a navigation bar
at the top of our view
controllers.
So from the Attributes
Inspector, if I set a title to--
for my leaderboard, it will now
show up in the navigation bar.
Now that we've added all the
viewers that we needed to add
for our UI.
Let me finish this up with
adding an app icon to this app.
Let's go into our project
navigator.
Select the blue folder that says
assets.
And go to the app icon image
set.
Now I have some icons that my
designer created.
I'll select these and drop them
into Xcode.
There's a specific way in which
you need to create these icons.
And we have guidelines on
developer.apple.com.
This time when we run our app,
I'll close this-- we will see an
icon on the home screen.
Isn't it cute?
[ Applause ]
Thank you.
Let's go back into the app.
And tap on the leaderboard.
This time we're able to go back
and forth between all our views.
This is great!
Let's now-
[ Applause ]
I'm glad you like that.
Let's now rotate our phone and
see what happens.
Oh no. My labels are all
clipped, and my image is too far
to the left.
In order to make my layout look
right-- let's put that back.
I'll use a technique known as
Auto Layout.
Auto Layout is a set of rules
that we define to tell our app
how we want our views to be
placed.
So each rule in Auto Layout is
known as a constraint.
Now we'll add some constraints
to this image view in our
details-view-controller.
Look at the buttons at the
bottom right of the storyboard.
We'll click on the align button,
the one with two horizontal bars
and say horizontally in
container.
Add one constraint.
This tells our app that we want
our image view to always be in
the horizontal center.
I'll also click on the button to
the next of this align button
called add new constraints.
The top-most text box here
represents the distance between
my image view and its closest
neighbor on the top.
So if I set this value, it will
make sure that my image is at
least, that my image is like ten
points away from the nearest
neighbor on the top.
Which could be the edge of the
screen too.
Let's also set the width and the
height.
Now our image view is all set to
use Auto Layout.
I'll quickly add similar
constraints to all the labels.
We can do this in one go by
selecting them altogether.
This time, if we run our app and
rotate it, we should be able to
see our view laid out properly.
There's an even easier way to
validate our layout.
We can go to the Device
Configuration pane at the bottom
left of the storyboard.
And change the orientation here
to landscape.
Now I can see my view in the
landscape orientation.
And my image is looking, my
image is in the center, and my
labels are all seen on the same
page.
You could even change the device
from the Device Configuration
pane to see how this would look
on an iPad or a smaller phone.
With that, a UI is all set up.
Let's quickly recap what we
learned in this session,
section.
We started with a
single-view-controller which had
the-- which managed the entire
screen for our game.
We learned that we can create
multiple view controllers to
display multiple screens of
content.
If we do create multiple screens
of content, then we need to tell
iOS how to go from one view
controller to another.
We do this by adding connections
that are known as segues.
We created a
table-view-controller which is
great for displaying lists of
data.
We also added it inside a
navigation controller.
The navigation controller helped
us go back and forth between the
table view and the details page.
This pattern of using a table
view along with the navigation
controller is commonly seen
across iOS apps.
Here are just some examples.
To learn more about view
controllers, check out the
documentation on
developer.apple.com.
We also learned about Auto
Layout which is a great
technique for building good user
interfaces for different screen
sizes and different
orientations.
I would recommend checking out
these WWDC sessions to learn
more about Auto Layout.
Finally, we can hook up our data
model with our UI and write in
the logic to bring everything
together.
Let's take a look at another
demo.
We need to save the score at the
end of each game.
To do this, I will select the
view controller that we wrote
with Jessie.
In the game over method, I will
call a method on my data model
that we wrote before to save the
points.
The-- this save points method
takes two parameters.
One is the total points which
we've already saved in the game
points variable.
The second parameter is the name
of the user who's playing the
game.
So to recap, I've just added
this little bit of code in our
view controller that we created
before.
The save points method on our
game data model takes two
parameters.
The first is the game points
which we had already stored in a
variable.
The second parameter is the name
of the user who's playing the
game.
In a real-world app, you would
probably want to create a
profile screen or a settings
screen where the user can enter
their own name.
But for the purposes of this
demo, I'll just hardcode this to
my own name.
Now that we've saved the score,
we need to write some code to
actually display the right
scores and the names on the
leaderboard.
So let's go ahead and create
another class by right-clicking
on the unicorn's folder and
going to new file.
A [inaudible] class again.
This will be a subclass of the
UI table-view-controller.
Remember when we created the
leaderboard on our storyboard?
It was a table-view-controller,
so I use a table-view-controller
class again to put in some code
for that leaderboard.
Let's call it the
leaderboard-view-controller.
Hit next. And create.
This already has some code that
has been generated for us by
Xcode.
These are methods that
developers find useful when
building their own
table-view-controllers.
We will implement two of these
methods.
First is a table view number of
rows in sections.
This method is asking us for the
total number of rows that we
want to display in our table
view.
In our case, the total number of
rows will be the same as the
total number of players that
have played the game.
And we can get this information
again from our data model.
So the number of players
variable will give us the total
number of rows.
The second method that we need
to implement is the cell
[inaudible] at index path
method.
This method is called every time
a cell needs to be displayed on
our leaderboard.
The index path argument tells us
the row number for the cell that
will be displayed.
And in here, we're expected to
configure the cell just like the
comment says.
So let me pull in some code to
set up this cell.
We are using our game data class
again.
And the index paths row will
tell us the rank of the player.
Since we want to display the
players in ascending order.
Once we have the player rank, we
can send it to the player data
method on our game data class
and get more information about
that player.
Using this information, we can
set up our cell.
The text label is the title.
The detail text label is the
subtitle.
And the image view is the image
that will have the photo.
Now instead of creating this
game data instance twice, I'm
just going to put it at the top
of the class so it can be
reused.
Let me also delete the number of
sections method that was added
for us by default, because we
don't need this today.
Now that we have written the
code for the leaderboard, let's
open the main storyboard and the
Assistant Editor on the right.
I'll rotate the specs so we can
see it properly.
We need to tell Xcode that the
code for our leaderboard here is
written in the class that we
just created.
To do this, I'll select the view
controller for the leaderboard.
Go to the Identity Inspector,
and change the class name to
leaderboard-view-controller.
After this, I'll select the
table view in the storyboard.
Go to the attributes Inspector
and change the content type to
dynamic prototypes.
This means that the cells are
now being created dynamically in
the code that we wrote.
We will also select a single
cell.
And in the identifier section in
the Attributes Inspector, I'll
copy over the reuse identifier
from the cell [inaudible] index
path method in my class.
By doing this, I'm saying that
I'm willing to reuse the cells
in my table view.
This will help improve the
performance of my table view.
Finally, we've written the code
for this leaderboard class.
We still need to write code for
our details-view-controller.
Luckily, I've already added some
code that we'll import into our
project.
This is the
details-view-controller class.
Let's jump to it from our jump
bar.
Here we have some IBOutlets for
the different views in our
details-view-controller.
Remember when we wrote the game,
we connected these IBOutlets to
the views on the storyboard.
But we're not able to do that
right now.
This is because we haven't told
Xcode that the code for this
view controller is right here.
Let's do that again by going to
the Identity Inspector and
changing the class name to
details-view-controller.
Now we can connect the IBOutlets
easily.
By doing this, we can set the
views from our code like I've
done in the view load method
here.
Let me hide the main storyboard
for a moment.
We also have a player info
variable here.
And we are using that player
information to set up our views.
You might be wondering that we
didn't really send this player
information anywhere.
So how do we get all this data?
We actually need to ask our
leaderboard about the person
whose name was tapped.
So we'll go back in the
leaderboard scoreboard and
figure out which person we need
to display more information
about.
I'll jump to the
leaderboard-view-controller.
At the bottom of this class, we
have a method that was written
for us by Xcode called the
prepare-for-segue method.
This gets called while we're
transitioning between one view
controller and another.
It will be called for us as soon
as we tap on a cell in our
table-view-controller.
So in here, I will get more
information about the player
based on the rank again.
And I can figure out the rank
because there is a property on
the table view called index path
for selected row.
This tells me the row number for
the cell that was selected.
We also get a segue parameter in
this method.
Remember how segues connect two
view controllers?
So the segue's destination
property will tell me which view
controller we're navigating
towards.
Once we have an instance of the
details-view-controller which is
the one we're going towards,
then we can set the player info
with the details we have.
Finally, we are ready to run our
app one last time and see how
everything comes together.
So now we'll play the game.
And we go to the leaderboard,
and we can see all the
information coming in from our
data model.
[ Applause ]
I made only one point, so I'm at
the end.
Let me see what my rank is.
Rank eleven, not too bad.
At least my app is all set up.
Now that we've built our app,
let's take a look at some next
steps.
Before you release your apps,
it's important to test them.
The exit test framework can be
used to write unit tests.
You should also check out the
App Store review guidelines.
These are meant for creating a
good experience for users and
developers alike.
At some point, you'd need to
enroll in the Apple Developer
Program.
This will help you create the
certificates and profiles that
you need to distribute your
apps.
Finally, submit your apps for
review.
Once they're approved, go tell
your friends and family and the
whole world.
That you've built an app.
To learn more about these next
steps, check out the resources
section for this session on your
WWDC Apps.
To summarize, I would encourage
you to explore Xcode.
It has many tools and templates
that make iOS development really
easy.
You can easily set up the user
interface using the storyboard.
Try some views and see what your
app might look like.
Think about what data you might
need, and how you would store
it.
It's important to create good
user experiences for all
devices.
This might mean optimizing
performance for older devices or
taking care of different screen
sizes.
Follow the guidelines and best
practices to make a good app.
If you've done all this, then
you're officially an iOS app
developer.
Congratulations!
And have a great WWDC.
[ Applause ]