Learn more about Swift Playgrounds, the new iPad app that teaches coding using the powerful Swift programming language. Explore the featured content, complete with puzzles that help you master each coding concept. Learn more about the coding features of Swift Playgrounds and see how the editing experience was re-imagined for touch. Learn to use the included templates to build playgrounds and look at the available features in the new playground book format.
[ Music ]
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
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.
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.
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
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,
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 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.
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
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
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.
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.
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.
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.
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
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
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,
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
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.
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
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.
So let's get started.
Now we have here the document browser.
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
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?"
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.
"Are you crying?"
Tap Run My Code.
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.
UInt, which is Swift's type for unsigned integer.
"UInterested in my clever jokes?"
That sounds like some of you agree with Em
on this assessment here.
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.
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
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,
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,
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
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 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.
Those of you who've authored Playgrounds before will
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.
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
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
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 --
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
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.
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
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
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,
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
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
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.
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
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.
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.
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.
Thank you Jonathan.
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
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.
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,
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.
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 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 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.
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.
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,
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.
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.
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.
Stop. That was really fun.
Now I'm going to bring Matt back up to wrap things up.
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
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.
We've got more information available
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.
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.