WWDC2016 Session 408

Transcript

[ Music ]
>> Good morning.
[ Applause ]
Good morning.
[ Applause ]
Thank you so much everybody.
My name is Matt Patenaude.
I'm a software engineer
on the Playgrounds Team.
And welcome to Session 408,
Introducing Swift Playgrounds.
I am absolutely thrilled to be
a part of the team that gets
to show this to you today,
and boy have we got
a lot to show you.
So with that in mind, we
are going to dive right in.
So you've had 48 hours
to play with this by now,
so I'm sure a lot of you
have already seen this.
But if some of you
have somehow managed
to resist the temptation,
Swift Playgrounds is a really
exciting new app for iPad
Swift Playgrounds is a really
exciting new app for iPad
that allows you to program
in Swift and brings the power
of Swift literally to
the tips of your fingers.
If you aren't that
experienced with programming,
we've got you covered.
We've built a great
learn to code playground
that you can download
right from within the app,
and we've designed it to
be engaging and exciting,
regardless of what level
you're starting at.
And if nothing else, you can
probably get some pretty good
dance moves out of it.
If you are a little
bit more experienced,
we've also given you some
great starting points,
like this shapes template,
which will let you experiment
with things like color and touch
in ways that are unique to iPad
that you couldn't
do anywhere else.
And if you're already used to
building playgrounds in Xcode,
you can take any of
your iOS playgrounds,
and once you update them for
Swift 3, they'll run great
on Swift Playgrounds
and iPad as well.
We think it's a really
exciting product,
and we know you're going
to do some really
amazing things with it.
And as such, we got
a lot to show you.
And as such, we got
a lot to show you.
So we're going to break our talk
into three different
segments today.
First, I'm going to ask my
colleague Max to join me
on stage, and he's going to
show you how to use the app,
including all of the great
touch affordances and gestures
that really make this a
unique experience for iPad.
After that, Jonathan's going
to come up, and he's going
to show you how to build
really engaging content
for Swift Playgrounds, using
all of the new features
of our new document format.
And finally, Izzy's going
to come up, and he's going
to show you some of
the really cool things
that you can do once you've had
a little bit of time to play
around with this thing.
So without further ado, Max.
[ Applause ]
>> Thanks Matt.
Thanks Matt.
So we're going to start off by
having a look at a screenshot
of Swift Playgrounds,
so we can see what all
of the different parts
of the UI are made of.
So up at the left, the
left side of the screen,
we've got the source editor.
On the right, we've
got the live view.
Now the source editor is
made up of a whole bunch
Now the source editor is
made up of a whole bunch
of different sections.
So one type of section
is the Playground markup,
and you'll see that we've
got rich markup in here.
This can be interspersed
inside of the single page,
and this is the rich text
to help you learn
something about the document.
Underneath, we've got an
example of some source code.
So here, this is where you'll
do all your programming.
Along the bottom of the screen,
we have the shortcuts bar.
In the center of that,
we show code completion,
and this depending on
the code's position.
On the left, we have the
Undo and Redo buttons,
and on the right we have the
two -- a couple of shortcuts.
One is to delete something.
The next is to insert
a new line.
And the third is to
bring up the keyboard.
These buttons will help
you if you want to program
without needing the keyboard.
Along the right side,
you have the live view.
This is where you can see
your code being executed
in real time, and underneath
that, the Run My Code button,
in real time, and underneath
that, the Run My Code button,
which will compile
and execute your code.
Along the top left, we have
the Document button to go back
to your documents, the button to
bring up the table of contents
that shows you all of
the different chapters
and pages inside
of your document.
We have the two buttons for page
navigation, and on the right
of that, the Tools menu, and the
Library menu and the Tools menu.
But let's have a look
at them in detail.
Inside of the Library menu,
we've got a couple of snippets.
Next to that, we have
all the image literals
that could be inside of your
playground or your document.
And thirdly, we have file
literals, which is all the files
that you can drag out of the
library into your document.
And in the Tools menu, this
is where you can find help
about the app, a
glossary of terms provided
with the document, two
buttons to share something
about your document,
such as Record a Movie,
which takes movie of what you're
doing, and the Take Picture,
which takes movie of what you're
doing, and the Take Picture,
which will save a
picture of the live view.
And finally, the Reset Page
button will reset the page
to the original state.
So here we are in the document
browser, and as you can see,
got a whole bunch of documents.
I'm going to open up the
Shapes Playground template
that I've got here.
So I've only got one
line of code here,
Let rectangle equals value.
I want to draw some
rectangles in the live view,
because I think that'll be fun.
So I'm going to tap on Value,
and you'll see that we bring
up code completion
along the bottom.
Got a whole bunch of
different options here.
So I'm going to find a rectangle
in code completion by tapping
and dragging to the left to
go through code completion.
So there's a rectangle.
Tap on that.
It gets inserted
into the document.
Now notice, there's
an orange circle
in the left side of the screen.
So that's a live issue
about this line of code.
We're going to tap on that.
It tells me there's
something wrong with this.
I needed to add parens
after rectangle.
I needed to add parens
after rectangle.
So here we provide fix-its.
You can tap on the first one,
and then that will get
inserted into the document.
The orange circle goes away.
Now tap on my code, and we
can see I drew a rectangle.
It's a square, but.
Now notice when we move down,
we've now got Rectangle
in code completion.
So I'm going to tap on
that, and tap on the dot,
and now it's going to list
all the different properties
and functions that I
can use on Rectangle.
Let's make this a
bit easier to see
by changing the border's
color and the width.
So let's start out by
tapping Border Color.
We get an equal operator.
Tap on that.
And we get a placeholder
that's of a type of color.
Now notice the second item
in code completion
here is a gray square.
That means that we can insert
a color literally in line.
So I'm going to tap on that, and
we get a white color literal.
Tapping on that brings
up a quick editor
to change the value.
There's a whole bunch
of quick editors inside
of Swift Playgrounds, and
this is just the color one.
So I'm going to change
it from white to black,
and let's tap Run My Code.
And now it's going
to a black border.
It's not very visible,
so I'm going
to increase the border
width as well.
Tap on Rectangle.
Tap on dot.
Tap on Border Width equals, and
now we've got a number literal,
which also brings
up a quick editor,
so we can punch in a number.
Going to punch in four.
Oops. And tap Run.
And now it's a bit more seeable.
Now I'm going to -- I want
to make a playground here
that will draw a square
everywhere I drag my finger
in the live view.
So I'm going to do a bit
more programming here,
and I want to hide
the live view,
just to give me some
more space to work.
So I'm going to tap and hold
on the center of the screen,
and it's going to split
the screen into two.
Now drag to the right to
dismiss the live view.
Let's tap at the
source of the code.
Now Swift Playgrounds also has a
great keyboard for when you want
Now Swift Playgrounds also has a
great keyboard for when you want
to do programming with
the onscreen keyboard.
So I'll tap the Keyboard
Up button to bring that up.
Notice the keys have
alternatives on top of them,
but more on that later.
Let's start by using the canvas
object that I know is inside
of the shapes playground to
interact with the live view.
So I'll type C-a-n.
Gives us a canvas object.
Type Shared to get
the shared canvas.
And now I'll type Drag.
Notice that Swift Playgrounds
fuzzily matches the untouched
drag handler from
just typing Drag.
So I'll tap on that, and we get
this placeholder for a function.
If I type Return, it'll
expand the placeholder
so we can do some coding.
Now I want it to create a
rectangle every time I drag
my finger.
So all I have to do is what I
was doing before, every time.
So let's tap on the closing
brace here, and tap on Hold,
and drag it down to encompass
the code we were doing before.
One more thing I
have to do though.
One more thing I
have to do though.
I have to change the center
of the rectangle to
be wherever I tap.
So let's add that
line of code now
by setting the rectangle's
center position to be equal
to the canvas shared
current touch points,
which I know is in array.
If I tap and hold on the H,
and drag it to the right,
it gives me an array's
subscript.
Now I can tap and hold on the
P to get the zero element.
Now let's dismiss that,
and bring in the live view,
and tap Run My Code,
and we can draw.
Yeah.
[ Applause ]
Now I'll tap and hold on
the center of this screen.
Drag it to the left.
Dismiss the code.
Now I can draw everywhere.
Now, I like my little
bit of art here,
so I'm going to send it to Matt.
So I'm going to tap
on the Tools menu.
You just take a picture to
save a copy of the live view.
You just take a picture to
save a copy of the live view.
Now, a lot was going on here,
and there's a lot
behind the scenes
to make a playground
work this way.
So I'm going to bring
up Jonathan,
who's going to show us
exactly what is inside of each
of the playgrounds in
order to make them work.
So, Jonathan.
[ Applause ]
>> Thank you Matt and Max.
So Swift Playgrounds on iPad
lets you use the same Swift 3
Playground documents that
you created on your Mac,
and you can make
them on the iPad too.
You can use AirDrop,
iCloud Drive,
or other document providers
to transfer and work on them
in either environment.
And don't forget to have fun.
But in addition
to the traditional
Playground document format,
Swift Playgrounds for iPad
introduces a new document format
that takes advantage
of the new environment.
Playground Books provide
some more building blocks
Playground Books provide
some more building blocks
to construct an interactive
story in the course of something
that you want other
people to explore.
You want to show them something.
So in these next moments, I'd
like to show you an overview
of what's new, and then
demonstrate how you can put
these new things to good use.
So first off, Playground Books
are made up of pages grouped
into chapters, and a table
of contents is generated
from this for easy navigation.
Playground Books provide a new
type of page called a cutscene,
and this can be useful
if you want
to stage a full-screen
illustration in the course
of a story that you're
trying to tell.
You can see how our content
team has put this to good use,
trying to demonstrate
big ideas in a fun way.
And as you introduce concepts,
you can use the glossary feature
to link terms with their
definitions at the tap
of a finger, and all these terms
and definitions are gathered
up to provide a reference
in one place.
A Playground page full of Swift
code can be a bit daunting
A Playground page full of Swift
code can be a bit daunting
to just jump into.
Sometimes you don't
want to distract
from the finer point
you're trying to present.
So Playground Books
give you the ability
to focus the learner
using editable regions.
You annotate your Swift
code with special comments.
They become blanks that
the learner then fills in.
This lets you reduce
distraction,
especially at an early
stage when you're trying
to demonstrate a
complex concept.
And Playground Books
lets you mark code
that you don't want
to show up at all.
Hidden code blocks give you
the flexibility to run, set up,
and tear down code around some
kind of workspace in the middle.
It's a great way to hide
the details at first,
and then you can pull
back the curtain,
and expose this setup magic
when you're ready to do so.
Playground Books lets you
configure the shortcuts
that show up it the
completion bar here.
You can specify or exclude
identifiers, modules, keywords,
etcetera, customizing what
shows up above the comments.
And with the new
document format,
And with the new
document format,
you can configure the live
view to be always on as soon
as the page is loaded.
It runs Swift code in a separate
process, completely independent
of the code that is typed
and run in the editor.
This editor code on the left and
the live view code on the right,
they talk to each other with
a special XPC mechanism.
We're actually going to see how
that works, and you can watch
through my demonstration and so
that you can take
advantage of this.
It's a great way to do
interactive visualizations,
building up with each successive
run of the code in the editor.
And if you've chosen to
progressively explore an idea
and guide through the
steps to build something,
you can analyze what was
typed, and then provide hints
that the learner can bring up
by tapping the Hint button.
And if they succeed in their
task, you can let them know
with a success message.
And Playground Books will
remember your assessment
of each page, and the learner
can see what they've completed
in the table of contents.
Use these Hint and
Assessment mechanisms as a part
Use these Hint and
Assessment mechanisms as a part
of your own motivational design.
You have access to a
simple key/value store
that is kept with the document.
This lets you track preferences
or even more advanced forms
of progress as the learner moves
through the book page to page.
And Playground Books
are resettable.
Every change made is kept
in a separate place away
from the main document content.
And if the learner so chooses,
they can reset the page back
to the state it was when
they first opened it.
The entire document
can be reset too.
Every page will be pristine.
The key/value store
will be cleared out.
Assessments reset.
And they're ready
to start again.
And last, but certainly not
least, on developer.apple.com,
you can see the documentation
of the format.
We want to make sure that
you know how it works
so that you can work on your
own custom content production
workflows to make
the magic happen.
Start with the examples
and the references.
Dig into all that, and even
take apart the Playground Books
Dig into all that, and even
take apart the Playground Books
produced by our content
team to learn more.
There you go.
So now I'd like to
introduce a Playground Book
that I have created to show
you what you would experience
from an author's perspective.
So my audience for this
book that I made just
for you is someone
who's used Swift before
and even used Playgrounds
as they were on the Mac,
but now they're new to the
Playground Book format,
and they'd like to know
more about how it works.
My goal with this
Playground Book is
to build a living reference
demonstrating how the new
always-on live view works
and how you can talk to it.
So let's get started.
What better way to
demonstrate the new features
of Playground Books than
with a Playground Book
that demonstrates the new
features of Playground Books?
We're very self-referential
around here.
All right.
So let's get started.
Now we have here the
document browser.
I'm going to bring up my
Playground Book called "Talking
I'm going to bring up my
Playground Book called "Talking
to the Live View"
by tapping on it.
And you can see immediately
the live view starts running.
Notice that the code
on the editor has not even been
compiled, and it's not running
at all, yet we have
a separate process
with the code I've written
for the always-on live view
getting us this beautiful little
face here.
I'd like you to meet Em.
My helper here is a
Swift program that loves
to recognize knock, knock jokes.
So we can see here on
this introduction page,
our goal is to just play around.
I don't want to burden the
learner with all the details
of how we're actually
going to send messages
over to the live view.
I just want you to
experience it for fun
with this fun little
story attached to it.
What we're going to
do is we're going
to send messages using this
Say function down below.
These strings will be passed
over to the other side,
and they'll advance the
conversation state machine
that is running for Em
that will keep going
as the jokes continue.
So we'll start here.
We have a string already filled
out for us called
"knock, knock."
I'll just tap Run My Code, and
Em responds, "Who's there?"
I'll just tap Run My Code, and
Em responds, "Who's there?"
The code on the left
was compiled, executed.
The special magic happened
with the Say function,
and the string was
passed to the other side.
And we'll brush away the
magic dust here in a moment.
So let's continue.
I'm going to say, "Boo."
And I'm using the
external keyboard to type,
because I don't want
to cover up the screen
with the on-screen keyboard.
I will send this string
over by tapping Run My Code.
"Boo! Who?"
"Are you crying?"
Tap Run My Code.
[ Laughter ]
And Em has correctly
identified this knock,
knock joke as a classic.
Let's try one more to see
how this continues to work.
I need to restart Em's
conversation state machine.
So I'm going to start by
saying, "Knock, knock."
I'll tap Run My Code to compile
and run this, send the string
over the wire to the other side.
"Who's there?"
UInt, which is Swift's
type for unsigned integer.
"UInt who?"
"UInterested in my
clever jokes?"
[ Laughter ]
That sounds like some
of you agree with Em
on this assessment here.
That's unfortunate.
But what we have here is a way
to experiment with the idea.
And when you're ready, you
can go to the very next page,
where the magic dust
is brushed away,
and you can see exactly how
the Say function is written.
This is all it takes
to send a string
over to the live view process,
and well unpack this a bit more
in a few minutes here.
But here, what we have
is a Playground Book
that progressively explores
the always-on live view API
from the author's perspective.
You can continue on to further
pages, where you learn how
to send more complex
commands over to Em.
You can configure it
to recognize new setup
and punch line joke patterns.
You can even save these joke
patterns to the key value store
to load them when you
want to have fun later,
after the next time you
open the Playground Book.
after the next time you
open the Playground Book.
So this Playground Book
is available for download
with our session materials.
I encourage you to check
it out after the session.
But right now, we're going
to kind of unpack this,
and see how this thing works
from an author's perspective.
So Playground Books are a
special document format geared
towards teaching these
concepts on a touch environment
that we have on the iPad.
They're a folder with the
extension .playgroundbook
that is treated as a document
package by the operating system.
You edit these on your Mac with
whatever you would like to use.
You can use Xcode, your
favorite text editor.
Use your version control system,
build your own custom
content management workflow
if you need to, to be able
to produce content
in Playground Books.
And we're going to walk
through how this package is
assembled together.
The package contains
the files and folders,
and Swift code assets
configuration
that make everything work.
And here's an overview
of these pieces.
We're going to refer back to
this as we go, so we can kind
of see how everything
gets assembled together.
At the very root of
this document package,
you have a folder
called contents,
and as you would guess, this is
where you put your
authored content.
Moving inside, you will
recognize these two folders
if you've authored
playgrounds before.
Sources is where you put the
global Swift files that you want
to have compiled and made
available to every page
in your Playground Book.
You don't even have to import
anything to make this work.
Anything that's declared as
public will be ready to go
as soon as you open the page.
And then Resources holds the
assets used by your pages.
Place your images, your
sound files, any other assets
that you need to
load by file name,
and they'd be pulled
out of this folder.
Note that these two folders
right now are in the root
of this document
package, so everything
in them is made available to
every page in the entire book.
If you choose to, you can
scope things to just chapters
by putting a Sources and
Resources folder in there,
by putting a Sources and
Resources folder in there,
or even individual pages.
You don't have to
share all of this stuff
across every other page.
It's up to you.
Customization there,
for your uses.
The next folder we're visiting
here is named Chapters,
and as you would expect,
it contains chapters,
which are themselves folders
containing one or more pages,
and each page is a folder
that contains the content
that you interact with when
the Playground Book is used
in the app.
This first file we're going
to see here is called
Manifest.plist.
It's a special configuration
file that sets
up how the page will work.
If you open this file, it
will look something like this.
We'll go through
it, don't worry.
Now, manifest files are property
lists, dictionaries of keys
and values that Swift Playground
uses to determine how this page
with a document is
supposed to behave.
These manifest files
are used at the chapter
and the document level as
well to configure behavior,
like the order of things
in the table of contents.
We're just going to focus
on the page manifest today,
We're just going to focus
on the page manifest today,
because it has the most
impact with what you just saw
in the demonstration,
and we'll see how each
of these configuration
mechanisms alter what happens
on the page.
The first key in the property
list is name, as you can tell.
It sets the name at the top of
the document, and it's also used
in the table of contents.
The next key, LiveViewMode,
controls how the live view works
when the page is first opened.
Usually, the live view is
hidden until it's either invoked
in code or the learner
brings it back on screen.
In this case, I want it to show
up as soon as the page opens.
So by setting the string
value of this key to visible
by default, I get
the behavior I want.
PosterReference is a key that
a string value used to look
up a file name in the
Resources directory.
That file becomes a
poster that covers
up the live view area before
the live view process has had a
chance to run right
after the page opens.
And as you can see here, as soon
as the live view process begins
And as you can see here, as soon
as the live view process begins
to run, the poster
image is faded away,
and we can see the live
view content underneath.
The LiveViewEdgetoEdge
key has a Boolean value
that determines whether
or not the content area
of the live view extends
to the entire boundaries
of the viewport, and also
underneath the Run My Code
button, as you see here.
I wanted to that in my
case, so I set it to Yes.
If you set LiveViewEdgetoEdge
to No,
and you gave the live
view a background color,
this is what you'd see.
Note how it's inset
all the way around.
It's not covered up by
the Run My Code button.
It's up to you which
mode you want,
depending on the
content that you have.
For instance, if you
needed to have a view
that had full control
of the touch area,
then setting LiveViewEdgetoEdge
to No would give
you what you want.
Playground logging mode controls
the inline results that you see
on the right side of every line
in the editor that
returns a value.
in the editor that
returns a value.
In my case, my live view does
all the results reporting
that I need.
So I decided to set the
PlaygroundLoggingMode
to the string value Off,
which turns off the
inline results completely.
Now we've reached
the interactive bits
of the Playground
document format.
This is where all
the fun happens.
Let's take a look at this first
one called Contents.swift.
Now, all of you have interacted
with Contents.swift before.
Whether it's full screen
or on the left-hand side
of the live view, as seen here,
whatever is in the editor
comes from Contents.swift.
And when you tap the Run
button, everything in this file
and everything it
references is executed.
In my introduction page,
Contents.swift looks
something like this.
At the top is Playground
Markup prose written
to help describe
what you can do.
Your objectives, goals,
instructions that are read
by the person going
through the page
to understand how they're
supposed to interact.
to understand how they're
supposed to interact.
Those of you who've authored
Playgrounds before will
recognize this.
It's the standard
Playground Markup comments.
And here, I have a few lines
of code that are used to set
up the page so that the real
action can happen down below,
but I don't want this
part to be visible,
at least not on this page.
So I use these special magic
comments to mark the start
and end of a hidden code block.
Everything between these
two lines is tucked away.
It's executed along
with everything else,
but it is not visible
when you open this page
in Swift Playgrounds on iPad.
And the real work of the
Playground page is kicked off
with this statement, a
call to the Say function
that was written above
in the hidden code.
Now I wanted to ensure that
as the learner was sitting
down with this page
and filling things
into this function parameter
that they wouldn't accidentally
cause a compiler error.
So I'm using editable code
regions to be able to set
up with these special magic
comments the beginning
and ending of an
editable code block,
and they can only
type in this spot.
and they can only
type in this spot.
You can have as many of these
as you want on the page.
And the first time
you introduce one,
only these areas can be
typed in, and it works great
for what I need, and the
learner can type away,
and they're just
affecting the string.
And experienced Playground
authors will notice this
placeholder syntax.
These angle brackets and
pound signs cause a bubble
to show up in the editor.
The learner can tap on the
bubble, and then as soon
as they start typing,
it replaces the contents
with whatever they wanted.
This is a great way to give
a clue of what is supposed
to go in a certain spot.
So that's a good summary of what
goes on inside Contents.swift,
a quick summary on
the left-hand side.
But now we're going
to turn our attention
over to the right-hand
side and what goes
on in the always-on live view.
This introduction page has
a file named LiveView.swift.
This is what it looks like.
First we import
PlaygroundSupport.
Now, those of you who've
authored Playgrounds before are
familiar with XE Playground, the
framework that gives you access
familiar with XE Playground, the
framework that gives you access
to the page environment.
That's been renamed.
It's been new and improved.
It's called Playground Support,
and this is what you
use going forward.
So we ask, for the
current Playground page,
and then we set the live
view property on that page
to be a fresh instance of this
thing called FaceViewController.
Where did this
FaceViewController come from?
Well, it's part of
the Swift code stored
in the Sources directory at
the root of the document.
This is the library of code
that I built up to be able
to share across all the pages.
Anything I put in here,
I can reference as long
as it's marked as public.
Now, you could, if you want to,
write all of your live view code
inside the LiveView.swift file.
There's nothing stopping
you from doing that.
But then you have
to copy that file
to any other Playground
Book page that needs
to share the same
live view behavior.
Every page in my Playground
Book document does,
so I'm just using these
three lines as, like,
setup that make the
Playground --
setup that make the
Playground --
make the always-on
live view run.
They're all sharing
the FaceViewController,
and I just have to
copy this file
across to any other page
that needs to use it.
Those of you who've authored
Playgrounds before may feel
like you're looking at something
familiar with this code.
Isn't this how you would
set up the live view
if you were doing it from
within Contents.swift?
Yes, it is, and you can
still do it this way.
If you choose to, it runs
inside the main process,
where all the code in the
editor is run as well.
That is really useful,
since you have full access
to the live view object.
You can take page.liveview,
cast it to FaceViewController,
and manipulate it
like anything else.
Call methods on it,
change properties.
It's right there
inside your process.
But that means that the live
view is only active as long
as the code in the
editor is running.
It will not start until the
learner taps Run My Code.
It will stop as soon as
the learner taps Stop
or starts typing
into the editor.
And it can't run if there's
a compiler error in the code
And it can't run if there's
a compiler error in the code
that is currently being
typed into the editor.
So that is where the
always-on live view
and LiveView.swift comes in.
If this file -- if a file with
the name LiveView.swift is
in your Playground Book page,
you automatically have
an always-on live view.
This file is executed as
soon as the page is opened,
and that makes it run
in a separate process,
which is awesome, because that
means it's running all the time.
Even if the code in the editor
isn't running or can't compile.
The trade-off is that you
can't just cast the live view
to an instance of
FaceViewController and talk
to it like you were
doing before.
You have to use some sort
of cross process mechanism
to send messages back and
forth, and we're going
to look into that next here.
Say we have this code
in the main process
from Contents.swift,
the main process
of the code running
in the editor.
We want to send the
string "knock,
knock" to the other side.
So first thing we do is
import PlaygroundSupport.
So first thing we do is
import PlaygroundSupport.
We get access to
the current page.
And when we ask for the
live view of the page,
we don't cast it to
FaceViewController.
We cast it to this
special class called
PlaygroundRemoteLiveViewProxy.
The instance of this class
is what does the work
to hand things across the wire
between the two processes.
And if this conditional
cast succeeds,
then that is your queue
inside the code that would run
in the main process that you
have an always-on live view
for this page.
Use this as that signal.
So assuming this all
worked, we've casted it.
We actually have a live view
running, and we have the proxy.
We craft a message.
The message-sending mechanism
uses PlaygroundValue,
an enum that we'll kind of talk
about a bit more in a moment.
But as you can probably guess
by looking at this line,
we're casting a string case with
the associated string literal
"knock, knock," and then
we take that message,
and hand it over to the proxy,
calling the send
method passing it in.
So the Contents.swift code
hands that string value
over to the live view proxy, and
then the live view proxy passes
that over to something
listening on the other side.
We need to wire up
the FaceViewController
so we can receive this message.
Somewhere in our
library of code,
we've extended the
FaceViewController,
and we've said that
it will conform
to the
PlaygroundLiveViewMessageHandler
protocol.
That means we must
implement the received method
that takes a PlaygroundValue.
This will be called, because
this FaceViewController is the
live view, because
we assigned this
to the page.liveview property.
That's what the live view
proxy knows as the queue
that this thing needs
to receive the message.
Inside this message, we
take the message parameter,
and check to see
what enum case it is,
extracting any associated
values.
I only care about strings right
now, so we'll just use the
if case let syntax, and then
once we do that, if true,
if case let syntax, and then
once we do that, if true,
the value of this enum is
bound to the identifier text.
And now, inside the if
clause, we have a string.
Do something with it.
And in this case, we pass it off
to this function
processConversationLine
that then advances Em's
conversation state machine.
So what if we want to
send data the other way,
from the live view?
Say we set up something
where you tap on the face,
and we get the string
"hello" sent back?
How do we do that?
Well first, in the live view
process, you need a mechanism
that actually triggers the
sending, and I've chosen
to have a tap gesture
recognizer set up on the face
that will call us back
on this tapped method.
Once you tap on the face,
we craft the PlaygroundValue
message we want to send a string
with the associated literal
"hello," and then we call send
on self, passing this
message to the other side.
Now, where did the
send method come from?
Well, by declaring
that we conform
Well, by declaring
that we conform
to this
PlaygroundLiveViewMessageHandler
protocol, it was
bolted on to our class
as a convenience, automatically.
Send is defined in
the protocol extension
with a default implementation,
and because this class is
the live view, calling send
like this will just pass it
right to the live view proxy,
and it will make its way over
to the other side, like so.
You tap on the face.
"Hello" is crafted, sent
to the live view proxy,
and now then live view
proxy has to deliver
that to something
listening on the other side.
Let's see how we could
wire that up next.
There's a bit of set up we
have to do, because by default,
code that you write
in Contents.swift will
stop executing as soon
as it reaches the
last statement.
That's not what we
want in this case.
We're waiting for some sort of
asynchronous message to come
at some later point in time,
so we need to first grab
the Playground page,
and then tell it that
we don't want it to stop
by setting the
needsIndefiniteExecution
property to true.
We asked for the live view
proxy, just like we did before,
and now we need to have
something that acts
as the delegate of that proxy
that can receive the message.
I'm just going to make
something up here.
A class right in line.
Notice that it conforms
to the PlaygroundRemote
LiveViewProxyDelegate protocol,
which means I have to implement
the remoteLiveViewProxy
received method.
And that's it.
This will be called
by the live view proxy
with the Playground value that
we can take apart using the
if case let statement,
and inside we do
something with the text.
That defines the delegate.
Now we have to wire it up.
So we'll instantiate
it, and then assign it
to the proxy's delegate
parameter, or delegate property,
and that completes the circle.
So now we have the
FaceViewController.
You tap on the face.
"Hello" is wrapped up
as a PlaygroundValue,
passed into the live view
proxy, where it passes it off
to the delegate, that
class that we just created,
and it receives the message, and
then you make the magic happen.
and it receives the message, and
then you make the magic happen.
I want to quickly point out this
PlaygroundValue enum gives us a
lot of options to statically
declare primitive values
that we want to be able
to send back and forth
between these two processes.
You can use these enum cases
directly, like we've seen
in the last few slides.
Or you can define
conversion operations
into Playground values from
your own data structures.
As an added bonus, the key
value store uses Playground
values too.
So the work done to get
your data into and out
of this model can be used both
for cross process communication
and for saving statement.
So remember, Contents.swift
is in a process running
on the left-hand side.
It's what we call
the main process.
And if you have a
LiveView.swift file
in your Playground Book page,
it will be executed and run
in the separate always-on
live view
in the process you
see here on the right.
in the process you
see here on the right.
It's a different mechanism that
we had before, so please dig
into our reference
examples and documentation
to see how this thing works
so you can take advantage
of the new goodies.
Before we reach the
end of our discussion
about authoring Playground
Books, I want to point
out one last detail
that you will notice
as an author of content.
When you play with your
great idea on your iPad,
and then you sync it back to
your Mac and take a look at it,
you'll notice at the top
level a new folder will show
up at the sibling
level with Contents.
This is where all
the changes typed
into the editor are stored.
So don't be shocked when you
go and play with your content
on your iPad, typing furiously
and changing a bunch of things
in the editor, and you think
it goes into Contents.swift,
but when you bring it back
to look at it on your Mac,
the Contents.swift
file looks just
like you authored it before.
Where's all the changes
you made?
That's by design.
The authored content
is never changed
by Swift Playgrounds
on the iPad.
by Swift Playgrounds
on the iPad.
Swift Playgrounds stores a
dif of the learner's changes
in this Edits folder, and
we reapply it when we can,
and this keeps the
content pristine,
and it's how the Playground
Books are resettable.
So that is a very
brief overview,
a subset of the underlying
bits that make
up the new Playground
Book format.
As mentioned, please go
to developer.apple.com,
grab the reference
documentation,
the examples we have, take apart
the Playground Books produced
by our content team.
It's all there, and we want
to make sure you have
the resources you need
to make awesome stuff.
Now I've led you through
a part of the experience
that an author has when they're
crafting these Playground Books.
But as you'd expect, this app
is just plain fun to doodle
with on your own as
some sort of scratchpad.
It's great stuff.
And next, I'd like to invite
my colleague Izzy to show some
of the things that
he has been exploring
with Swift Playgrounds.
Izzy.
[ Applause ]
Thank you Jonathan.
That was awesome.
Now, we're going to jump
straight into our demo.
So like all of you, I've
just been so excited by all
of the features and
all of the APIs
that have been announced
since Monday.
And in particular,
one area of coding
that I was really interested
in, as long as I can remember,
is procedural content
generation.
The idea that a computer can
generate something that is
like a real world is
just fascinating to me.
So when I saw that GameKit
added API specifically for this,
I wanted to jump right in and
get my hands dirty, so I did.
I wasn't quite sure what
I needed, but I looked
at the new APIs, and I saw
that they added this function
called GKPerlinNoiseSource,
and we have help in the app
that shows us all of
the documentation.
So if I tap Help here,
we can see that
GKPerlinNoiseSource has features
we can see that
GKPerlinNoiseSource has features
that make it good for
generating natural phenomenon,
such as clouds and terrains.
That sounds like
exactly what I wanted.
So I took this, and I just
wrote a couple lines of code,
and I turned it into an image.
So I wanted to look at my image.
So if we run our playground --
for those of you who are used
to Playgrounds on the
desktop, you'll notice
on the right-hand side,
we have a result sidebar.
For those of you who
haven't seen this before,
as your playground executes,
each lines generates a result.
And we can tap on this,
and it'll show a little
popover with our content.
Now this a little bit small, so
I wrote a few more lines just
to zoom in a little bit and
keep it pixely, because I want
to think about the pixels.
We're going to talk
about that in a minute.
So now, I have a much bigger
image, and we can add this
in line with the Add
Viewer button, and it stays
with our code as we scroll.
So now that this is
large, we want to reason
about our image a little bit.
So we generated our noise,
and we want to generate
some 3D terrain with this.
and we want to generate
some 3D terrain with this.
So what we're going to do is
we're going to go pixel by pixel
through this image, and
when the image is dark,
we want it to be a very
low area in our 3D terrain.
And when the image is bright,
we want that to be a very
high image in our terrain.
So you can see in the
upper right-hand corner,
it's a very sort of dark area,
and that's going to be low.
And in the bottom left
corner, it's bright,
so it's going to be high.
So I wrote a just little
small extension on UI image.
It takes an 8-bit grayscale
image, and it just iterates
through the rows and the
columns, and it calls a block
for every position with the
8-bit value at that position,
which we're going to
convert into our height.
Now, because we have a very
small image, it's just 10 by 10,
255 for the full range of 8-bit
images sounds a little bit high.
So I wrote a small bucket
function right here,
and just to prove to myself
that worked, I iterated all
of the possible values of
my bucket, of my integer,
of the possible values of
my bucket, of my integer,
and you can see with our
popover here that it clamps
to a nice stair step function.
So we just get a range from
0 to 4, instead of 0 to 255.
And then we can go over
our image with our block,
and then we end up with a graph
that looks kind of like this.
And this is interesting.
It's kind of cool looking, but
it's not really 3D terrain.
Like, you can see each point
in our image now has an
associated height value,
but it's not exactly
what I wanted to.
And normally, I would
be pretty stuck here.
I don't have the deep knowledge
of 3D APIs to really generate
from scratch the
terrain that I wanted,
and I don't have the 3D skills
as an artist to do this by hand,
but I happen to know
that the Learn
to Code playground has a
Build Your World page in it
that I can use to progress
my experiment here.
So I'm going to move over into
the Learn to Code playground,
and we're going to already
be on the page that I want.
and we're going to already
be on the page that I want.
So this is the Create
Your World page,
and if I just run
this really quickly,
you can see that we're just
floating in the clouds here.
So I'm going to paste the
code that I wrote before,
and I want to type for a
minute, so I'm just going
to hide the live view.
And here, where we have our --
where we just echoing
our value before,
we want to turn this
into a 3D world.
So what we want to do is our
Create Your World page provides
us with a world.
So in our world, we want
to place blocks at the x
and y value that we're at.
And we're not taking
into account value,
so we need to make a height,
and we want to call our
bucket function on our value,
and then for our height, we
want to place our blocks.
and then for our height, we
want to place our blocks.
And I just love this
animation, so I'm going
to do it one more time.
Then if we run this
oh. We forgot to add
our parens, like Max.
So if we run this, you can see
that we're putting
blocks in our world.
And I can see pretty quickly
that this isn't quite
what I expected.
There's these weird
blanks spots in my world,
and I don't want that.
I'm not generating a fantasy
world of flying islands.
I want to generate something
that looks like Earth.
So let's stop that
really quickly.
So these blank spots didn't
really make sense to me
at first, but after a
little bit of thinking,
it's clear that when our height
is 0, because your range is
from 0 to 4 and not 1 to 5,
we're just not putting
a block in.
So our 0 spot seemed like a
good place to put some water.
So our 0 spot seemed like a
good place to put some water.
So if our height is less
than 1 in our world,
we want to place water.
And now, if I tap If with our
structured editing helpers,
we can add an L statement,
and just do what we
were doing before.
And this, I want to speed
it up just a little bit.
So my world also
has a command speed,
and I just want to
crank that up.
Let's
Oh, perfect.
All right, so let's run
this and see what happens.
So now you can see
our world has water.
So this is pretty cool.
[ Applause ]
We went from just sketching with
an API and a blank playground,
and then when we
hit a roadblock,
we moved over into the
Learn to Code playground.
So the Learn to Code
playground, while it's a very,
very valuable tool for learners,
it's also a powerful platform
for seasoned developers
who want to explore APIs
and develop ideas against.
So that was pretty cool.
Now you have the spectrum of
iOS APIs available to you,
and that includes things
like Core Bluetooth.
So I'm going to switch over to
this other iPad really quickly.
And here, I have a playground
that uses core Bluetooth
to talk to a peripheral.
I have a Sphero SPRK Plus here,
and what we can do is I'm going
to place this on the ground,
because we need a
little bit of space.
But what we can do,
when I run my code,
But what we can do,
when I run my code,
the Sphero will light
up and start driving.
And it's just moving
in a square right now,
but I'm using Core Bluetooth
to control a third-party robot
from my iPad, and
that's just so fun.
[ Applause ]
I want this to just be just
slightly more engaging,
so I'm going to hide
this for a moment.
And what I'm going to
do is add some colors.
So one of our other
structured editing helpers,
we can just drag our array
out, and add some items.
[ Applause ]
And I'm going to make
these all colors.
You know, these colors right
here seem really familiar,
but I can't quite
place my finger on it.
So in a rest function,
we're just going
to iterate three of these.
And then instead of
setting our color to white,
we're going to set to color.
Let's bring our little
helper back in.
Let's run this.
Now we're changing colors
as we're driving our Sphero.
Now we're changing colors
as we're driving our Sphero.
[ Applause ]
Stop. That was really fun.
Now I'm going to bring Matt
back up to wrap things up.
[ Applause ]
>> Thank you so much Izzy.
That is really cool.
So we've seen a lot today.
We started out with Max, who
showed you how to use all
of the great touch controls that
we have in Swift Playgrounds
to interact with
Swift code in ways
that we've never been
able to do before.
Jonathan showed you how to
build engaging content using all
of the great new features
in Playground Books,
that way you progressively
explore ideas
and disclose content
as you go along.
And Izzy showed you that you're
not limited to the things
that come in Learn to Code,
that you can experiment
that come in Learn to Code,
that you can experiment
with the iOS SDK and
interact with things
in the physical world or even
build a world of your own.
We think that you're going to
be able to do a lot of really,
really cool things with Swift
Playgrounds, and we can't wait
to see what you do with it.
Thank you.
[ Applause ]
We've got more information
available
on developer.apple.com.
We're session 408.
There are, of course,
some related sessions you might
be interested in checking out.
Thank you so much everybody,
and enjoy the rest of WWDC.