WWDC2015 Session 405

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> SAM: Good morning.
[Applause]
So thank you all for
coming to today's session
on authoring rich Playground.
My name is Sam, and I'm an
engineer on the Xcode team.
So Playgrounds have been
out for about a year now,
and we've been absolutely
blown away
by what you guys
have done with them.
We've seen everything from
people writing their first
"Hello, world" all the way
up to people writing
entire books in Playgrounds.
The response has
just been amazing.
So today we're going to be
covering a couple of things.
We're going to be talking
about some of the new features
that were added to
Playground since last year,
and we're also going to cover
some of the existing features
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and we're also going to cover
some of the existing features
that have been updated.
And we'll also cover
some tips and tricks
that can help you author
really, really rich Playgrounds,
Playgrounds that
you want to share
with the rest of the world.
And as a bit of a
bonus, we're also going
to be solving a problem that's
common among WWDC attendees,
and that is how to
explore San Francisco.
So what is the problem?
Well, San Francisco
is a big place.
There's a whole lot to see,
but really you're not going
to find a lot of time to
do it between the sessions
and the labs and writing
your next great apps.
And you probably have a flight
to catch at the very end
of the week, so there's
an endpoint here.
And as engineers, we
want to be as efficient
as we can possibly be
when we solve problems,
which in the context of this
problem means we just don't want
to walk any further
than we have to.
So how are we going
to solve this problem?
Well, once we know the
places that we want to visit,
we're going to start
out at Moscone Center,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
we're going to start
out at Moscone Center,
traverse all the places
that we're going to see
in the quickest way possible
before we finally have to jet
out for San Francisco
International Airport.
Now to do this we're going
to be building a Playground.
So without further ado,
let's get into that.
Okay, so I've got a
Playground already kind of set
up for us here, and we'll
just take a quick moment to go
through what we've got.
So first up we've got a
struct here for place.
So places are going to be
what we want to see when we're
in San Francisco, and they're
going to have a name as a string
and a location as a
CLLocationCoordinate2D.
Next up we've got
a struct for city.
So in the context of our
problem this is going
to represent San Francisco.
And we can think of this
as a collection of places.
It's our own type to
hold these things.
So internally we've
got an array of places,
and then we've got
a function here
that we can add places
to our city.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that we can add places
to our city.
So let's go ahead and
just create our city.
We're going to call
it San Francisco.
And like I said, we need to
start our journey somewhere.
So we're going to go
ahead and create a place
for Moscone Center, which is
where we're going to start.
So let's create Moscone there.
And then finally
we're just going
to add the place to our city.
So those of you who are familiar
with Playgrounds are going
to remember that for each
line of code that executes,
we get a result in the
results sidebar over here.
So we can see that our add place
function is called, and it looks
like we are passing in
Moscone Center to that.
But if you look at it further
down where we've created
our city and our place,
all we're getting is the type.
So this is handy,
but we kind of want
to be a bit more descriptive,
especially if we're going
to be creating a
few more places.
If we see place after place
after place, we're not going
to be able to differentiate
these things.
So for our places, the most
descriptive thing is the name.
So how do we get the name to be
returned in our results sidebar?
Well for that we've
got a new protocol,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Well for that we've
got a new protocol,
and that is called
Custom String Convertible.
So what I can do is I'll extend
my struct here for place to say
that I'm going
to be implementing
Custom String Convertible.
And you can see now
I've got an area here
because they're not actually
conforming to the protocol yet.
So to actually conform to
the protocol we just need
to implement a re
[unintelligible] property
called description.
And that's going
to return a string.
And for us, we want to
return the name of our place
because that's the
most descriptive thing.
So you can see now, if
we look back down to
where we created our place,
we've got Moscone Center here
instead of just the type name.
So what does this
mean for our city?
Well probably the most
descriptive thing there is
to return the list of places
that are currently in the city
so we can see how our
journey is progressing.
So we're going to go ahead
and do the exact same thing
for city, just implement Custom
String Convertible there.
And go ahead and
return the description.
And for that we're going to
return to places.description,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And for that we're going to
return to places.description,
so the description of
our array of places.
So now you can see when we
first created San Francisco,
we don't actually
have anything in it
yet so we get an
empty array here.
But then when we add our place
to it, we get Moscone Center.
So when we create more and more
places we're going to see more
and more in our results sidebar.
So one of the cool things
about Playgrounds is
you're always able to kind
of get a deeper look and get
more information about a result
by clicking this Quick Look
here right next to the result.
So I click that for
Moscone Center.
We see a bit more
information about our place.
So we've got the name and we've
got the latitude and longitude.
This is superhandy to debug
but, I don't know, latitude
and longitude doesn't
really help me.
I'm not that great
at cartography.
I don't know how to position
these things in the world.
So I kind of want to see
something a bit more visual,
something that just kind
of screams out, yeah,
that's a place.
And to me nothing
screams "place" more
than just a big blue dot
with a name underneath,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
than just a big blue dot
with a name underneath,
something I would put on a map.
So how are we going to do that?
Well normally when
we kind of want
to do something a bit custom
and visual, we create a view.
So we're going to go ahead
and just create a UI
View subclass here.
And we've got some of
that already set up.
And let's just take a
quick moment to look
through what we've got there.
So we've got a class
here called View.
It's going to be a
UI View subclass.
And just internally we've
got another view that's going
to be our big blue dot view.
And then we've got a
name label that's going
to show the name of our place.
And then when we create
this thing, we're just going
to let it decide how
big it wants to be.
And finally in layout
subviews we're just going
to position these things
so that blue dot's on top
and the text is below.
So we'll create one of these
just to see how it looks first,
and we're going to pop
open the Quick Look.
Cool, that's starting to
be a bit more like a place,
like I can see that
appearing on a map.
But how do we actually
join these things up so
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
But how do we actually
join these things up so
when we Quick Look our place, we
actually see our view returned?
Well for that we've got
another new protocol,
and that protocol is
called Custom Playground
Quick Lookable.
So what Custom Playground
Quick Lookable does is
if you implement the required
method there, it will allow you
to return another type to
appear as the Quick Look
for your type or any other type.
So that could be something
like a Bezier path or a color.
But for our case we
want to return our view.
So what I'm going to go ahead
and do is just create an
extension for our place and say
that that's going
to be implementing Custom
Playground Quick Lookable.
And so again, we've
got an error here
because we're not actually
conforming to that yet.
So we'll just add
the conformance there
by implementing the Custom
Playground Quick Look method.
And so inside that
method we're just going
to return a Playground Quick
Look that's reflecting the view.
Now because we're an extension
on place, we have access
to the name of our place, so
we can just go ahead and throw
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to the name of our place, so
we can just go ahead and throw
that into the initializer there.
So now, when we Quick Look our
place again, we should see,
cool, we've got Moscone Center
there and everything is starting
to look a bit more like a place.
But we've kind of
ended up in a bit
of code here that's just hanging
around in the rest
of our Playground.
And we kind of want to move
this just out of the way
because no one else
really cares about this.
It's not really helping us to
show what we're trying to do.
So for this we're just
going to go ahead and,
well first we're going to
delete this place view here
because we don't need that.
And we're going to grab the
view here that we declared
and we're going to just go
ahead and put that directly
in our extension on place.
Clean up some white space here.
And so when the Playground
reexecutes you should just see,
cool, exactly what
we saw before but now
that view code is all just
embedded within our extension
so it's nice and clean.
What does this mean
for our city?
So if we're following the
kind of pattern that we want
to see what's in our city at
the moment, then we kind of want
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to see what's in our city at
the moment, then we kind of want
to see what places
are in our city.
And so this is going
to happen by default.
So if we click on the Quick
Look for Moscone Center,
we can see we've got
a place in there.
And we can see the Moscone
Center, little blue dot
in there, but as we add
more places, it's not going
to help us all that much.
It's just going to be listed up.
We kind of want to visualize
how these things are positioned
to each other based
on their location
so we can start working out,
well if we're at Moscone Center,
you know, we're probably
not going to go directly
to Golden Gate Bridge, we'll
probably go to something
like Coit Tower first.
So for that we're going to
create another extension.
This time on City.
It's going to be again, Custom
Playground Quick Lookable,
and we'll do that here.
I've got a bit of
code ready for that.
And we'll just walk
through this real quickly.
So it's an extension on City,
same way I implemented Custom
Playground Quick Lookable.
We have conformed to that
by implementing the Custom
Playground Quick Look
method here.
And then inside we're just
going to create a view,
work out where these
things would be positioned
within that view based on their
latitude and longitude pair.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
within that view based on their
latitude and longitude pair.
So now when we Quick Look
our city we should see, cool,
Moscone Center on the
eastern side there
by a little blank map, but we're
starting to build up a picture
about what we're actually going
to be seeing while we're here.
So now that we've got
this kind of in place,
we're going to add
a few more places.
But before we do
that, I kind of want
to keep this map view here
just open all the time,
or at least visual.
I'm opening and closing it a lot
when I want to check my code.
Well for that we've got this
cool little thing called an
inline result.
So right next to this Quick Look
button if I click Show Result,
that's just going to
go ahead and throw
that Quick Look directly
under the line of code
that generated it so I can
keep working on my Playground
and see it constantly running
and see what's actually
happening.
And the cool thing is it's
kind of small right now
so we can actually just
grab it and drag it
out like we would any other
window and make it as big
or as small as we want.
So cool, we can start working
on the rest of our Playground,
adding our places to that,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and we should see them
pop up in our map.
So what do we want to see?
I've heard Golden Gate Bridge
is pretty cool and famous,
so I'm going to go ahead
and check that out.
We'll add that to the
places that we want to see.
And when the Playground
reexecutes we'll see that based
on the location of our
Golden Gate Bridge,
we're going to be putting
that in the northwest,
which if my knowledge
of San Francisco geography is
correct, I think that's true.
What else do we want to see?
Sutro Tower, how about that?
That's kind of like something
out of War of the Worlds,
going to chuck that in and put
that in the places as well,
going to chuck in Sutro Tower.
And the Playground reexecute
and then we'll see
Sutro Tower down south.
So we're starting to get
a really good picture
of how our places are built
up, and as we add more and more
of these things we can see,
based on where their
location is, how we're going
to be getting between them.
I'm just going to go ahead
and switch back to slides now.
So you may have noticed that our
Playground got a little bit long
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So you may have noticed that our
Playground got a little bit long
towards the end of that.
We had some view code and some
extensions, and there's a lot
of stuff that wasn't
really helping us to kind
of describe the problem.
It was not that great.
So what we kind of want to do is
pull a lot of that code directly
out of the main body of the
Playground but still keep it
around so we can use it.
So to show you how
we're going to do that,
I'd like to invite my colleague
Connor up to the stage.
[Applause]
>> CONNOR: Thank you, Sam.
Hello everyone.
My name is Connor and I'm an
engineer on the Xcode team.
Today I'll be talking to you
about how you can make your
Playgrounds more powerful
and making them even more
focused on the problem at hand.
In order to do this, let's
dive straight into a demo
where I'll take a look at the
Playground that Sam just started
and add support for
finding the best path
through San Francisco while
making it more focused.
Let's head over to
the demo machine now.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Okay, so here we are in Xcode.
And if you noticed, we've got
basically the same Playground
that Sam was just showing you.
We start off by creating
a city for San Francisco.
We create a few places, and then
we add those places to the city,
ending up with this great inline
result showing you what we've
built up so far.
If you notice though, there
is one major difference,
and that's that the
entire Playground now fits
on one screen.
I'm still using my custom
city in place structs, though.
And even though Swift compiler's
pretty great, it isn't able
to actually create structs
out of thin air yet.
So what we're using instead
is a feature which we added
in Xcode 6.3 called
Auxiliary Sources.
The auxiliary sources are
additional Swift source files,
which are embedded
inside of your Playground,
and they're precompiled into
a separate swift module.
Because they don't
need to be interactive,
they can perform better
than the Playground itself.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
they can perform better
than the Playground itself.
Additionally, since they're
in a separate module,
you can use access control
to ensure that only the bits
of your Auxiliary Sources which
you want to be made visible
to the Playground are exposed,
so you can hide a bunch
of internal implementation
details
in the auxiliary sources.
To find them, we'll go ahead
and open up the navigator.
In your PC, we've got the
Playground at the top.
And then inside
of the Playground we've
got thr sources folder.
In the sources folder
we've just got a collection
of Swift source files.
I can open one up, and
here we've got city.swift,
and it's basically the same
struct that Sam was just working
on with a few minor
modifications.
First, I'd mark it as public
because we want the city
to be able to be used by
the main Playground itself.
I've also added support for
travel times to the city
so that we can actually keep
track of the time needed to get
between each place in the city.
If we look at place.swift, we
see the same basic stuff here.
So same struct that we
had before, just modified
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So same struct that we
had before, just modified
to become public and with
a few modifications to work
with the updated city struct.
I have a couple of other
auxiliary source files,
which I'm not going
to dive into.
One has to do with
property list serialization,
and the other one is kind
of a grab bag of utilities
that I've just pulled
together from other projects
that I've worked on,
and it will help me
out when I'm implementing
our algorithm.
Let's switch back to
the main Playground now.
And so here we see that we have,
you know, the start of a city.
We're starting to
build something up,
but I want to visit more
than just these two places,
and we also want to have all
the travel times between places.
I could add all of that in
code, but that wouldn't be great
because we'd have a
bunch of code at the top
of the Playground, which
isn't really instructive
to what we're trying to show.
So instead I'm going to take
advantage of another feature
that we have in Playgrounds
called Embedded Resources.
The embedded resources
are files which are copied
into the Playground itself
and are made available
to the Playground when it runs
as the resources
of the main bundle.
And they live in the
navigator as well,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And they live in the
navigator as well,
in this little Resources folder.
What I'm going to do is I'm
going to drag in a plist
from the Finder that defines
the city of San Francisco.
So I'll go ahead and do that.
I've got the SanFrancisco.plist.
I can drag it in here,
and it will get copied
inside the Playground file.
This means that we
don't have to worry
about any external file
references breaking
when you decide that you want
to share your Playground
with someone else.
It's all just in there so you
can send it as a discreet unit.
Let's take a look at what
this plist looks like.
And so first we've got
an array of places.
Each place is just
mapping a latitude
and a longitude to a name.
And then let's scroll
down a bit in this file.
We'll see here that we've
got an array of travel times.
And a travel time is just
mapping two places to the time
and minutes needed to
get between those places,
these times gathered using
the trans directions in iOS 9.
Now even though I'm calling
these destination and origin,
I am making this a little
bit simpler and assuming
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I am making this a little
bit simpler and assuming
that the time it takes
to get from point A
to point B is the same as
the time to get from point B
to point A, so these are
actually bidirectional
travel times.
Switch back to the
main Playground now.
And instead of having all
this code here, I'm just going
to select a bunch of it and
delete it and replace it
with a call to load my
city of San Francisco.
So start out by calling
this initializer on city,
call contents of
property list at URL.
And what it will do is that
it will just simply look
at the main bundle to get the
URL for a particular resource,
this San Francisco plist.
We know that we've just added
this into the Playground,
so I'll force unwrap
that optional
so I can pass it
to my initializer.
Additionally, this
initializer has been updated
to take advantage of Swift
2's error handling feature.
So I'll indicate to the compiler
that I know it can throw an
error with the Try keyword
and add an exclamation point
at the end because I don't want
to add a bunch of error handling
code that's not instructive
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to add a bunch of error handling
code that's not instructive
for what I'm trying to
show in this Playground.
Additionally, I know that this
plist is correct, so it's okay
for me to load it this way.
We can show this inline now.
And let's make it a
little bit bigger.
So here we've got our city now.
We've got the Moscone Center,
Coit Tower, Fisherman's Warf,
the Painted Ladies, Sutro
Tower, Golden Gate Park,
Golden Gate Bridge, and
not pictured in our map
but still there is the San
Francisco International Airport.
And you can see all
the connections leading
to the airport.
So great, we've got a city
that we can work with now.
But now that I look at it,
I think I'd like to make this
Quick Look a little bit nicer
by adding in some icons for
all the places that I'll visit.
And it just so happens that
on my desktop I've got this
Images folder.
And if I open that up you can
see, here we've got a bunch
of icons for each
of these places.
So I'll just go ahead and
take those and drag them
into the Resources
folder as well.
Just like the plist,
they'll be copied in there
and be made available
to my Playground.
I do need to update my
Quick Look to take advantage
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I do need to update my
Quick Look to take advantage
of these images, though.
So I'm going to go ahead and
open up the place.swift file
in the Assistant editor
by option clicking on it.
I will then find
this location view,
and instead of initializing
it to just the blue circle,
we're going to update this to
take advantage of the images.
So I can take all that code and
we will update our place view.
We'll start off by getting the
image associated with that,
create an image view,
and then set a couple
of properties before
returning it.
Now when I save this
file, Xcode will notice
that the auxiliary
sources have changed
and will automatically
recompile their Swift module.
Once the compile finishes, we'll
rerun the Playground itself
and so the Quick Look
will update automatically.
I didn't have to
do anything more
than just make an
edit and save to disc.
So great. That Quick
Look looks a lot better.
Let's switch back to
the standard editor
and start working
on our algorithm.
I'm also going to
hide the navigator
because I don't need it and
I'd like the extra space.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
because I don't need it and
I'd like the extra space.
So we're implementing a brute
force algorithm to find our way
through San Francisco.
And in order to get
that started,
we need to just get all the
paths through San Francisco.
So we'll start with this
and what we do is we
just call this all paths
through city method on our city
struct, telling it that we want
to start at the Moscone
Center and that we want
to end at the airport.
And if you look in the
sidebar at the right,
we see that we have 720 paths.
I'll then implement
the algorithm itself,
and here we're just starting
with a couple of variables
which will hold our results, one
being for the best travel time
and one for the best path.
We'll then iterate over all
the paths through the city,
getting the travel
time for each path.
We'll then compare that
to our best travel time,
updating our result
variables if necessary.
Finally, at the end we can
see here the best travel time
through the city so we'll
show that inline and we'll see
that it will take 235 minutes
to get between all these places
if we never stopped and
somehow managed to make all
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
if we never stopped and
somehow managed to make all
of our transit connections.
We can also add the path itself
inline, and so we can see
that we'll start off
at the Moscone Center,
which is what we expected.
We'll then head over to
Painted Ladies and Sutro Tower.
Then up to Golden Gate Park
and Golden Gate Bridge.
Then we'll head ove
to Fisherman's Warf
and Coit Tower before heading
down to the San Francisco
International Airport
to catch our flight.
So great, I've got all the
information that I need
to go see the sights
so let's switch back
to slides now to
take care of that.
So I just showed you how you
can use the auxiliary sources
and the embedded resources
features in Playgrounds
to make your Playgrounds more
powerful while keeping them
incredibly focused on the task
that you're trying
to actually achieve.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that you're trying
to actually achieve.
I think I have something
pretty interesting here,
and I'd like to share
it with people
when I get back home
from the conference.
But it's not quite polished
enough that I'd be ready
to show it to other people.
We've added a bunch of great
features in Xcode 7, though,
which makes sharing
your Playground
with the world even
better than before.
So now I'd like to invite my
colleague Matt up on stage
to show you about that.
Thank you.
[Applause]
>> MATT: Thank you
so much, Connor.
Hi everybody.
My name is Matt and I'm also
an engineer on the Xcode team.
And I think Connor and Sam
have done a wonderful job
of putting together a
really awesome Playground
that shows people how to
get around San Francisco
in the best way possible.
But it really isn't ready
to be shared with the world,
so I'm going to show you a
few tips and tricks you can do
to make your Playground
richer and more engaging
so you can put it out
there on the Internet
and people will love it.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So you can see here
we have the Playground
as Connor just finished
working with it.
And we have a very simple
algorithm that Connor wrote,
which walks through all the
possible paths in the city
of San Francisco and
compares them to one another.
And it was great for you guys
because we had Connor here
explaining every step of the way
as he was implementing it.
However, when we share
this with the world,
unfortunately not
everyone was here at WWDC.
So we'd like to add a little
bit of information, a little bit
of context, so that people
who view this Playground later
will understand exactly how we
got here.
So we introduced a new feature
in Xcode 6.3 called
Playground Markup Comments.
And that allows you to
annotate your Playground
with rich prose formatted
in beautiful displays
so that people can better
understand exactly how you got
to the Playground
that you arrived at.
So just to give us a little bit
more space I'm going to start
by putting away our Quick
Look here, and I'm going
to replace the comment at
the top of the Playground
with a little bit of information
about exploring San Francisco.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
with a little bit of information
about exploring San Francisco.
Now you can see this
looks a lot like a comment
that you would put anywhere
else in your source file,
but the biggest difference
that differentiates
a rich markup comment
from another comment
is the colon.
We've got a colon after the
first asterisk in the comment,
and we can actually do that as
well with single-line comments.
So add a colon over
here as well.
And when I go up
to the Editor menu
and choose Show Rendered Markup,
you'll see that this rerenders
and now we have these
beautiful rich blocks of text
that we can use when we want
to explain what's
happening in our Playground.
We can actually format them
a little bit more as well.
So if I switch back to the raw
markup, I can use a number sign
to indicate that we'd
like a heading to indicate
"Exploring San Francisco."
And I could use, for
example, asterisks around
"most efficient," to indicate
that we want this
to be in italics.
So if I render this again,
you'll see that now we've
got a nice, big, bold heading
that explains exactly what
we're going to be talking about.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So that's a great start.
I'd also like to
annotate a little bit more
about the other things that are
happening in this Playground.
For instance, all paths.
All paths through the
city is a little bit vague
and it's a little
bit mysterious,
so I'd like to add a
little bit of information
about how those paths
were computed.
And the algorithm itself could
probably use a little bit
of explanation as well.
So we'll document the algorithm.
And if I switch back once
more to the rendered markup,
you'll see now we're
starting to get something
that looks much more
like almost a book,
something that a user
could sit down with,
walk through, and understand.
We've even got a nice
bolded list, which we use
by inserting an asterisk
at the start of each line.
So that's pretty awesome.
But it isn't quite rich enough.
We want to take it just
a little bit further.
So to do that, we're
going to do a feature
that we introduced a long
time ago on Playgrounds
that is now even better on
Xcode 7, and that's Live Views.
So I've taking the liberty
of writing a live view.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So I've taking the liberty
of writing a live view.
I've put it into the auxiliary
sources already, and we're going
to start by showing it
alongside this Playground
to visualize exactly how
this algorithm works.
So the first step to using
Live Views is that you need
to import XCPlayground, which
is a module that has a bunch
of really awesome
functions that allow you
to do some pretty cool
stuff with Playgrounds.
Now you're also welcome to do
this in your auxiliary sources
and create, for instance,
a helper method
that shows your live view.
You don't need to do that
in the main Playground.
But I'm going to do
it right here just
so it's must clearer
how it all works.
Once we've got our city of
San Francisco we're ready
to show it, so I'm going to
instantiate a view controller
with our new city view
controller, and I'm going
to pass in the city
of San Francisco.
I'm then going to use
the XCPShowView function,
give it the name of a city,
and pass in our view
controller's view.
So if now I switch over and
show our Assistant editor
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So if now I switch over and
show our Assistant editor
after the Playground reexecutes,
we'll see a live view
that looks just like the
city of San Francisco.
And you can see that we've taken
the idea of the rich Quick Looks
that we've already added
and we've laid them
out onto something that looks
a little bit more realistic
so people won't be
quite so disoriented.
So that's the first step.
But we also want to show how
the algorithm itself works,
and to do that we're going
to add a little bit of code
that updates the live
view as we're walking
through our algorithm.
So we have a loop here that
iterates through all the paths
and all paths, and I'm going
to replace that with the method
on my view controller called
Visualize Path Iteration.
And I've written that to
use a trailing closure
so I can actually update it so
that it looks almost exactly
like the loop code
that we originally had.
And I'm also going
to add a line in here
so we can tell the view code
controller once we've found a
better path, we want to
show that better path,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
better path, we want to
show that better path,
especially on our map.
So it will execute
through once more,
and when it does you can see now
we're visualizing all the paths
as we traverse them through
the city of San Francisco.
And this is great
because now people
who are reading this program can
really see exactly how we got
to our answer of how to find
the best route through the city.
You might notice
something, though,
and that's that it's
checking a lot of paths.
It's actually checking 720
paths, as Connor pointed
out earlier, and
that's quite a few.
In fact by default, live
views run for 30 seconds,
which you can change
with this control
down in the bottom
right of the Playground.
And that isn't even enough
time to make it through all
of the paths through the
city of San Francisco.
Now we've artificially
slowed it down a little bit
so you can see the
paths as we iterate
through them on the live view.
But I think when people see
that, they're going to say,
well there must be a better way.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And in fact there is.
And we'd like to start out
by showing that to our users
from the very beginning.
So we're going to use
another algorithm.
It's a nearest neighbor
approximation algorithm,
and what that's going to
do is it's going to be
as though we were
starting at Moscone.
We looked at all the places
that we wanted to visit
and then we just picked the
closest one and we went to that.
And then from that place
we'll pick the next closest
and we'll go on from there.
And if I wanted, I could
implement that right
at the bottom of this
Playground document.
But that would start to
get a little bit confusing,
and it's not as focused.
One of the wonderful
things about Playgrounds is
that they're very, very
focused pieces of content,
so we want to be able
to preserve that.
And to do that we have
a brand new feature
in Xcode 7 called
Pages, which allows you
to have multiple
pages of content
in a single Playground document.
So to do that we're going
to open the navigator.
And in the bottom-left corner
we'll choose the Plus button
and click New Page.
And that's going to
create a brand-new page
in the same Playground.
I'm going to call this one
Nearest Neighbor, after the name
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I'm going to call this one
Nearest Neighbor, after the name
of the algorithm that
we're going to be using.
And then we're going to
rename our initial Playground
to Getting Around.
Now Pages are also
pretty cool because,
like the auxiliary sources and
resources that you can include
in a Playground at
the top level,
you can do that on
a per page basis.
You can see I can twist open any
one of these Playground pages
and we can embed
their own sources.
Any resources of the
same name, for instance,
will also override those
in the larger Playground.
So if you want to have some
different branding on each page
or a particular image that
is specific to the concept
that you're teaching
in each different page,
you can do that pretty easily.
So right now I'm going to switch
the nearest neighbor page,
switch back to the raw markup.
And I've already written up this
algorithm, so I'm just going
to go ahead and paste that in.
So what we have here
is a Playground
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So what we have here
is a Playground
with nearest neighbor
approximation, and you can see
when this one runs it
examines way fewer paths
through the city.
Now this is not an
optimal algorithm
in that it won't
necessarily find our best path
through the city.
But you can see it's already
done, which is pretty cool.
So this is a great way
of showing, alright,
there might be more than
one answer to this problem.
And if we render
this, we can also show
where we got this path from.
We actually edited this on,
we found the information
for this algorithm on Wikipedia.
Unfortunately, I
invented a little too far.
And we can embed a link
right into the Playground,
which would take us to the page
explaining exactly how this
algorithm works.
We could also link between
pages in a single Playground
and bring it back to our optimal
path that we discovered earlier.
And in fact, when we look
at the number of paths
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And in fact, when we look
at the number of paths
and the different paths that
we took through the city
and how long this
algorithm takes to execute,
we examined 720 paths on
this one and find a path
that is only 21 minutes
faster than the other page.
So that gives people a frame
of reference for saying,
maybe there are other
ways to do it.
And they can use a Playground
to experiment with that all
by themselves, which
is pretty awesome.
So that's adding
sections of markup, Pages,
and Live Views in Playgrounds.
[Applause]
So we have a lot of
really awesome new features
in Playgrounds in Xcode 7.
We showed you Custom Quick
Looks, which allow you
to take your custom data
types and make them come alive
in the same way that a lot
of the built-in types do.
We've also got inline results,
which stay with the Playground,
so you can show results right
next to the line of codes
that produced them, and then
those go with the Playground
when you share it
with other people.
We also have Auxiliary Sources
so you can take the code
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We also have Auxiliary Sources
so you can take the code
that goes with your Playground
that isn't as instructive
as the code in the main
Playground and put those aside
so that your users see only
the API and the functionality
that you want them to see.
We also have Embedded Resources
so you can bring in images
and make things feel even
more alive and more engaging.
We've got brand-new
markup comments
that are a really great
way to guide your user
through your Playground when
you can't be there with them,
enhanced Live Views which
are better than ever,
and Pages which allow you
to cover multiple topics
in a single Playground without
distracting from the focus
of each of them, which
is really, really cool.
So that is what we have
in Playgrounds in Xcode 7.
[Applause]
For more information, you
can visit the website.
We've got documentation up
there and the developer forums.
You can also talk
to Stefan Lesser,
our Developer Tools Evangelist.
We have a number of related
sessions that are going on.
We've got Swift in Practice,
which is happening
tomorrow afternoon,
and Building Better Apps
with Value Types in Swift.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and Building Better Apps
with Value Types in Swift.
Also the What's New in
Xcode and What's New
in Swift sessions will
be great all week.
Thanks so much everybody and
enjoy the rest of the WWDC.
[Applause]