[ Music ]
[ Applause ]
[ 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 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.
[ Applause ]
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 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.
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.
[ 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.
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.
[ 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 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 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?"
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.
[ 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.
UInt, which is Swift's type for unsigned integer.
"UInterested in my clever jokes?"
[ Laughter ]
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 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, 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 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.
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 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 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, 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 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.
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.
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.
[ 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 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.
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, 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.
[ 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 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.
[ 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.