1. 程式人生 > >2014 s408 swift playgrounds

2014 s408 swift playgrounds

Hi.Welcome toSwift Playgrounds. I'm Rick Ballard and withme today is my colleague Connor Wakamo. We're both Engineers in the Xcode Team and we've been working hard to bring Playgrounds to life.We introduced Playgrounds to the world Monday morning and you saw a little bit more about them Monday afternoon and yesterday. Well, today we're going to go into a lot more depth.

We're going to start out todaywith some conceptual background,what Playgrounds actually areand what you can use them for.

And then we'll show you examplesof how to use Playgrounds for learning, exploration,and visualizationof the results of your code.

We'll show you how you canuse your own custom resources with your Playgrounds,and how to use Playgroundsfor algorithm developmentand developmentof other separablepieces of code.

We'll introduce theXCPlayground frameworkwhich includes somereally powerful utilitiesthat you can use toenhance your Playgrounds.

And we'll show you how you candevelop your own Custom Quick Looks, so that you can visualizeyour own classes the same wayyou visualize the classesthat come with the frameworks.

Next, we'll showyou a great demoof how awesome Playgrounds arefor developing custom viewsand in any other kindof custom drawingand we'll show you how you canuse your own asynchronous codewith Playgrounds.

Finally, we'll finish uptoday with a little bitabout the limitations thatPlaygrounds have today.

So what exactly are Playgrounds?Playgrounds are a new type ofdocument introduced in Xcode6 and they're actually a file wrapper containing a few useful things.

First of all is your Swift code.

The code that would be run and the result are,and generate results to display automatically every time youedit your Playground file.

Swift Playgrounds also can contain a folderof embedded resources which are made available to your codeor your Playground can reference resources elsewhere on your system you want to make available.

Finally, your Playgroundcan contain a timeline fullof timeline items that provide useful visualizationof your results beyond what you see in the sidebar.

When you first opena Playground,we show the Playground Editorwith your Swift code on the leftand the results sidebar onthe right showing the resultof every expressionin your code.

Every time you edit your source,we rerun your Playground sourcefrom the top to the bottomand present the new resultsfrom that run in the sidebar.

This is the basic editor mode.

But if you go into the assistanteditor mode we'll show the Timeline Assistant bydefault which allows youto visualize yourresults in more detail.

For example, you candisplay the value historyfrom a line in your code.

In this case, sinceit's a numeric value,we'll draw a graph ofthat value over timesince it was iteratedmultiple times in a loop.

If you're looking for consoleoutput like that from Print Man,you'll also find that inthe Timeline Assistant.

There are a coupleother useful things you,I want to call out here.

In the lower right handcorner, there's a time-stepper.

And this controls how long yourPlayground will continue to runafter the top of asource is finishedif you're using live viewsor indefinite execution.

And I'll explain what both ofthose are a little later on.

There's also a slider whichallows you to go back in time and view results in thetimeline from a specific pointin your Playground execution.

So here, you can see we'reviewing a numeric resultfrom partway through thePlayground execution.

But you'll find this isvery useful with live viewsas it allows you to scrubback through the recordingof that view and see exactlywhat your animation was doingat a specific point in time.

So that's what Playgrounds are.

Let's talk a little bit aboutwhat you can use them for.

We think your first great useof Playgrounds isgoing to be learning.

We've introduced a brand newlanguage for you to learn and we think the best way toget started is just to openup a Playground anddive in and play around.

Our documentation also includesa special interactive Playgroundcalled the Swift Tour.

This allows you tosee documentationand Playground Editor sideby side in the same editor.

So you can read about howto do something and try itout right there withoutleaving the editor.

Finally, we think Playgroundsare a fantastic way for people to learn how to programin the first place.

Beginners don't have to learnhow to configure a project and target and buildand run and debug.

They can just type codeinto a Playground Editorand immediately see the results.

So if you know anyone whowants to learn how to program, we encourage you to suggesttrying it in a Playground.

We think Playgroundsare also going to bein indispensabletool in your toolboxfor everyday code development.

If you're developingan algorithmor any other separablechunk of code,you should considerstarting it on a Playground,working on it there untilyou have it how you want it,and then dragging thatcode into your projectfor use in your application.

Any sort of drawing codeyou want to do is also great in a Playground because youcan immediately see the visualresult of what yourcode is doing.

And every time youchange your code,you can immediately see howthat affects the visual result.

Finally, processing code likevalue transformers or a sequenceof image filters aregreat in Playgroundsbecause you can visualizethe result at every stepof the transformation process.

And when you changesomething, you can see howthat change ripplesthrough all your results.

We think you'll findthat Playgrounds are fertileground for experimentation.

And in particular,any time you're tryingto learn some newAPI, you should try itout on a Playground because youcan immediately see how it worksand what results it gives you.

You don't need a project, youdon't need to build and run.

You just open up even astandalone Playground document, type in your code,and see what happens.

I'm sure all of youhave many a time goneto create a new project fromthe application template,and gone to findapplicationDidFinishLaunching,just to put a line ofcode and to try some API.

Oh, and then you probablyhave to NSLog it tooso you can see what happened.

You don't have todo that anymore.

Now you can just openup a Playground and tryout the API you want to try.

In fact, we'd recommend youconsider keeping a Playground in your doc at alltimes for quick access.

So anytime you wantto try something it's rightthere at your fingertips.

So with all that said, let'sdive in and take a lookin an actual Playground.

To do that, I'm going to invitemy colleague Connor up on stage.

>> Thank you, Rick.

Hello everyone.

My name is Connor.

I'm an Engineer onthe Xcode Team.

And today I'll be talking toyou about how you can work with Playgrounds as wellas some of the thingswhich we think Playgroundswill be really great for.

Now, Rick has alreadycovered manyof the basic conceptsbehind Playgrounds.

And so I think really the bestway to show you how to work with Playgroundsis actually justby jumping straight into a demo.

So, let's go ahead and do that.

So here I am at the demomachine and I'm just goingto go ahead and launch Xcode.

Now you'll notice herethat on the Welcome windowfor Xcode we've added thisbrand new "Get startedwith a Playground" button.

It's that way we want tomake it really easy for youto just get started with one.

So I'll just click on that.

We'll create a Playgroundand I'll just give it a name and a place to save it.

So "MyPlayground"is fine and puttingon the desktop is fine as well.

So let's say create, and then wehave here our Playground itself.

So, you notice thatwe're importing Cocoa,so we have full accessto the Cocoa APIs.

And then we are alsocreating a stringand we're assigningthe value, "Hello,Playground" to that string.

You'll notice that in the resultsidebar we're seeing the resultof that.

So in this case we're seeingthe string, "Hello, Playground".

So OK.So that's kindof the basic idea.

Let's try somethingwith numbers.

So let's say, for i in 0 to10, let's just say, i times i.

You see there thatwe execute the codeand we're getting anindicator in the result sidebarthat we've executedthat code 10 times.

So, OK, let's trybumping that up to 100.

We'll let it runand we'll see therethat we immediatelyget an indicationthat this code hasexecuted 100 times.

Now, knowing that isvery useful informationbut sometimes you actuallywant to see the value there.

And we have supportfor that as well.

So OK, I'll just hover overthis result, and you'll see that we're highlightingthe line of codewith which it is associated.

And we're also showingthis button here.

That's called theValue History button.

And if I go aheadand click on it,we'll open up the assistanteditor into the timeline mode.

This is the place where you cansee results over time as wellas a place for you tostore results which youlike to see persistently.

So in this case, we're showingthe graph for i times i.

And we've seen this, you know,this nice little curve here.

So OK, so that's kind of thebasics of using the timeline and calculating numbers.

Let's try something alittle bit more interesting.

Let's go ahead and dosomething with AppKit.

So let's first startup by creating a color.

So you let color equalsNSColor. blueColor.

You'll see there thatwe're now showingin the result sidebar a colorswatch indicating what the coloris as well as indicatorsof all of the componentswhich make up that color.

So I can, you know,take this colorand let's create anotherattributed string using it.

So let's say, let attrStrequals NSAttributedString.

And we'll pass it in the stringin an attributes dictionary.

So we'll use thestring we already haveand we'll create a dictionary.

So we'll sayNSForegroundColorAttributeNameand we'll pass itthe color we have.

And then I'll say,NSFontAttributeName,I'll just pass it a font.

So I'll say, NSFont,systemFontOfSizeand then let's go to somethingfairly big, so I'll just putin 42, see what that looks like.

So, OK.So here, you noticethat we're getting aresult for this as well.

You're seeing that we're showingthe plain text representationof this, as well asan icon indicatingthat it is an attributed string.

Now, that's great.

You know, we know thatthis code is executed.

But I really want to see whatthe actual value is there.

See how the attributedstring looks itselfand we support that as well.

So I can just hover overthe result and in additionto the Value History button,you'll see that we havea Quick Look button.

And so if I go ahead and clickon that we'll show a Quick Lookof that value to show youthe full representation of itas it was created inthe Playground source.

So, OK, that's colorsand strings.

Let's try something with images.

Let's actually startup by creating anarray of image names.

So I'll say, letimageNames equals,we'll put in an array thereand, I know it's something to dowith like NSImageNameUseror accountsor something in that line.

So I'm just going to createan array with imageNamesthat I think it couldbe, the ImageNameUser,NameUserAccounts,NSImageNameUserGroup.

It's OK.We run thecode and you notice that we now have anarray of strings.

We actually want tosee an array of imagesand that's very easy to do.

I can just say something like,let images equalsimageNames. map.

I'll pass it a trailing closureto just say, NSImage named, pass it the positionalargument $0.

And you'll notice there thatwe're now seeing that this line of code executed 4 times.

And so, basicallywe can see that,you know, OK, that makes sense.

We're executing thisline of code 3 timesfor the trailing closure itself.

Then we're executing it oncefor the assignment to images.

Actually, I only want tosee the images array itselfand we have a nice little trickfor doing that in a Playground.

You just go ahead and putthe thing that you wantto see on a line by itself.

So there you see, you know,we've put images there,we rerun the code, and we'reseeing the images array.

I can Quick Look that andI can see, "Oh, you know,here's the image thatI'm looking for. "And so, I'll just getthat image and say,let image equals images at 0.

We'll rerun it.

I'll Quick Look to make sureit's OK and in fact, yeah, that's the one thatI'm looking for.

Let's go ahead and putthis into an image view.

So I'll say, letimageView equal NSImageView.

We'll pass our self aframe, so let's say NSRect.

We'll say 0 for the originbecause we don'treally care about that.

Then we'll also say 512by 512 for the size.

Now I'm going to go aheadand put this ImageViewon its own line as well.

So I can show thisresult in the timeline.

And this is a neat littleway of building something up.

You take the, you startcreating the objectand then you put another linewhere we show it as a result.

Anyway, I can add somecode in between thereto see how it buildsup over time.

So you see here thatwe're startingout with just this emptyimageView, you know,we're not seeing anyinteresting there.

So let's go ahead add ourimage to the imageView.

So let's say, imageView. imageequals image.

And we'll re-execute andwe'll see here now that we're in fact showing the image therebut it's not fillingthe full imageView.

It's not doing what we expect.

That's because we haven't set upthe image scaling appropriately.

So we'll set that as well.

Say imageScaling equalsImageScaleProportionallyUpOrDown.And we'llre-execute and now you'll seethat we're seeing the imageat full size in the imageView.

We're seeing what we expect.

And it's OK.

That's how you can workwith system resources.

But I'm sure you have manyresources of your own that you'd like to use in Playgroundsas well.

And we support that too.

So I'm just going togo ahead and I'm goingto show the final inspector.

It will slide in on theright hand of my Playground.

And you'll noticehere that we're,we have this new sectioncalled Playground Settingswhich is shown whenever you'reviewing a Playground document.

You can select the platformagainst which thePlayground should execute.

And, you know, OS X iswhat we're doing right now.

But we also support iOS.

And you can select apath for resources.

This defaults to nonebut you can select oneif you have resourcesthat you're interested in.

In this case, I'm just going tosay I have a folder of resourceson my desktop so I'mjust going to say,let's use the AbsolutePath option.

I can then go aheadand choose that.

So let's say here's my resourcesfolder, I'll choose that.

And then once I made that choiceI'm actually going to go aheadand hide the Utilities area.

And to access the imagesthemselves, I just use,you know, NSBundle API, youknow, the resources showup as resources forthe main bundle.

So I can say something like "letmyImage equals NSImage, named".

I have an image inhere that's just called"Xcode" so let's grab that.

We'll re-executeand you'll noticethat now we're gettingthe image result here.

And click, click to confirmthat it's what I think it is.

And in fact, it is, we'reseeing the Xcode icon there.

And now I'm just going to havethat imageView showthe Xcode icon instead.

So, I'll say, "imageView. imageequals myImage".

We'll re-execute and nowyou're seeing this new result, let's add it to thetimeline as well.

So you can see here thatwe have what we expected.

The Xcode icon is showingup in our imageView.

You'll probably also noticethat we're still seeingthe older version herewith the user iconin the imageView.

And that's because Playgroundsactually capture results on every single lineof execution.

So you can do thesekinds of comparisons.

So like for instance, you know,let's look at the imageView when we first create it.

And it's empty.

Then I added theuser icon to there.

And so, we see thatearlier version that we sawwhere it's small in the center.

Then I set the imagescaling appropriatelyand it's now fillingfull image view.

Finally, I updated it touse myImage and we're seeing that it's showingthe Xcode icon.

And that's great, so that youdon't have, you know, go back and see what happenedat a particular point.

We're capturing the data foryou as your Playground executes.

So I think that about coversthe basics, so let's go back to slides and talk a littlebit more about Playgrounds.

So one of the key ideasthat you saw there isthat Playgrounds willautomatically execute.

You just type in some codeand you'll see the results in a sidebar on the right.

Additionally, you saw thatwe can add a value history to the timeline.

So here we have a line ofcode which executed 100 times.

And if I hover over that result,you'll see this ValueHistory button.

If I click it, we'll switchinto the assistant editor and we'll show that asa history of that value.

Additionally, many values inthe Playground have Quick Looks.

All right.

So in this case we havean attributed string.

We don't see the fullrepresentation of the sidebar,just kind of theplain text of it.

But if I click on theQuick Look button,we'll see the attributedstring as it was createdin the Playground source.

We support many different typesfor Quick Looks inthe Playground.

We support colors, strings --both plain text and attributed.

We can show images, views,in this case we'll capturea snapshot of the viewat that point in time.

We can show arraysand dictionariesas we'll show a structuredversion of the arrayor dictionary, ah,like you might seein the variablesview on the debugger.

We can show points,rects, and sizes.

We'll kind of create a graphicalrepresentation of those.

We can show Bézier paths, soboth NSBezierPath on the Mac and UIBezierPath on iOS.

We can show URLs, for this we'lltake the plain text of the URLand show it in the sidebar.

But if you Quick Look, itwill show you a web viewwith the contents of that URL.

And finally, for typesif we don't have a nativeQuick Look representation,we can usually get astructured view of it, again,like you would see in thevariables view in the debugger.

So here I have anobject of a classthat I created inthe Playground.

And it is, it has acouple of properties,a foo property anda bar property.

And you're seeing thevalues of those at that lineof code when it executed.

In this demo, I also showedyou how you can use your own resources with Playgrounds.

And this is actuallyfairly easy.

So you just go ahead andshow the file inspector.

You select a locationfor Playground resources.

And for this we havethree options.

We've got an Absolute Pathoption which basically says, "OK, I've got this folderof resources somewhereon my computer andI'd like to show itand use it with the Playground. "We have a Relative toPlayground path option.

And this is really greatif you're checking yourPlayground into SCM.

Because you can say, "Oh, youknow, here's this Playground and here's this folder ofresources that's next to it,I can set this up and then whenyou use other people to checkout your repository, then itwill automatically be ableto use the Playgroundwith its resources. "Finally, we support anInside Playground option.

And this is greatif you're sharingin ways other than via SCM.

Because you can just say, "Iwant to store my resources in my Playground" and you canemail that out to other peopleand see, when they openit, they'll be ableto see those resourcesimmediately.

Once you have madethe selection,to access these resourcesin your Playground source,you just use things like,NSBundle. pathForResourceofType and NSImage named.

The resources just showup as the resourcesfor the main bundle duringPlayground execution.

So, now that we have thebasics out of the way,I think I'd like to starttalking to you about someof the use cases forwhich Playgrounds would bereally great.

And the first of theseis Experimentation.

I'm sure that all of youout there have a folderon your computer whichlooks something like this.

It's just a bunch ofXcode projects createdfrom the template that are,you know, maybe 1 or 2 changesto see how something worksor to test out an idea.

It's actually isn'tthat easy of a process.

You know, you have todo many different --you have to first choose theright project template then findthe right file in that projectto edit which may be easyor maybe not depending onwhich template you chose.

You'd have to do what you'retrying to do in the first place,and that's write some code.

Once you've writtensomething, you then haveto build your project.

You then run whatever you built.

And for iOS that mayinvolve deployingto a simulator or to a device.

And if you didn't get it rightthe first time, you'd then haveto redo this, stop inthe debugger and stepthrough your code to figure outwhere things are going wrong.

We think Playgrounds canhandle this a whole lot better.

That's because there'sreally only 2 steps.

You would just, say, get startedwith a Playgroundand write your code.

Once you start writingyour code,we'll automatically execute itfor you and show you the resultsin the sidebar so you can seewhere things are going wrong.

So now, I think I'dlike to show you a demoof what this looks like.

So let's go back tothe demo machine.

So here I am.

I'm going to go ahead andjust launch Xcode again.

And this time I'm going tocreate an iOS-based Playground.

So I'll say, File, New File,and I'll say, iOS Playground.

And I want to actually testout how the UITableViewCellstyle API works.

So, I'm just going to calland create this Playground and call it TestTableViewCell.

Save it to the desktop, and OK.

So, here we haveour iOS Playground.

It's, you know, importing UIKit,but otherwise, it's the same,we're just creating a stringand assigning it to a variable.

So, if I want to use aUITableViewCell style,I need a UITableViewCell.

And the best way to showthat is with a UITableView.

In order to get those cellsinto my UITableView,I need a data source.

So, let's just go ahead andimplement a data source.

So I'll say "class DataSource".

We'll inherit fromNSObject and we'll conformto the UITableViewDataSourceprotocol.

Notice now that we're gettingan issue here and that's because the DataSource we'vecreated does not actuallyconform toUITableViewDataSource.

And, you know, that's expected.

We haven't actuallyimplemented any methods yet.

So, I'm actually going tojump to the declarationof UITableViewDataSource bycommand-option-clicking on it.

We see that we then openthe assistant editor.

And instead of showingyou UITableView. h,we're going to show you aSwift version of that header.

So, in this case, we're seeing,you know, here's our protocol.

We're seeing that we need toimplement these two methods.

And so, OK, I'm just going totake this one, this first one to tell the TableView thenumber of rows per section.

I'm going to copyand paste it in here.

And then I'm just going to startthings out, return 1 from this.

So, OK.So that'sthe number of rows.

Let's also provide the cell.

And OK, let's just go aheadand create our UITableViewCell.

Let's say let cellequals UITableViewCell.

I need to fix this typo.

Here, we'll say the style, we'lljust say the default style.

And then for thereuseIdentifier,we aren't actually goingto be reusing these cellsso we can just passnil for this parameter.

And OK, so therewe have our cell.

Let's go ahead and configure it.

So, I can say something likecell. textLabel. text equals Text.

OK.So that's the text label.

We'll see what that looks like.

UITableViewCell may alsohave a detail text label.

But that's not guaranteedto be the case.

So I'm going to explicitlyhandle the factthat it's an optional.

So, I can say something like"if let detailTextLabelequals cell. DetailTextLabel".

And so, if the code insideof this "if" executes,then we'll know that wehave a detailTextLabel.

So, I can say something like,detailTextLabel. textequals Detail Text,and we know that this is safe.

We're not going to accidentallytry to assign a property to nil.

So now that we've configuredour UITableViewCell,I can just go aheadand return that.

You can see now that weno longer have an issuein our Playground.

But we're also not gettingany results in the sidebar.

That's because we haven'tactually instantiated ourdata source.

So, I'll just say something likeDataSource equals DataSourceand then I can, you know,I'll just create a TableViewand tell it to useour DataSource.

So, let tableViewequals UITableView.

We'll pass it a frameso, CGRect.

Again, we don't careabout the origin.

I'll pass 320 for the width,and for the height we justneed enough to be ableto show all the cellswe care about.

So, I'll just saysomething like 240.

Finally, we'll passa style of Plain.

We'll then tell the tableViewto use our DataSource.

And then, we will tell thetableView to reload data.

Let that Playground execute.

And once it's finishedexecuting, we'll be ableto see the tableViewwe've created.

So, I'm going to just go aheadand add this to the timeline.

We can see here that we'vecreated our tableView, you know, we're seeing thecell that we want,with the text that we want.

So, OK.So that, you know,gets us up and running.

But actually I wantto see the stylesfor all the styles that we have.

So, I'm going to jumpback to the declarationof UITableViewCell style.

And you can see herethat there are 4 options.

So I'm going to change this1 to a 4, so if 4 rows.

Instead of alwayspassing the default style,I'm going to conditionalizeit based on the rowthat we're currently at.

So, I'll say let rowequals IndexPath. row.

And I'll say somethinglike let style equalsUITableViewCellStyle. fromRaw.

I'll pass the row.

This fromRaw will convert theUITable, the raw row integer into a UITableViewCellstyle optional.

And we confirm that by usingquick help and we can say that, "Oh, yes in fact, thisstyle is an optionalUITableViewCell style. "If we were to passthis directly here,we would get an erroras you can see here.

We need to explicitly handlethe fact that this could be nil.

You know, the UITableViewCellinitializer doesn't expect that.

So, let's go aheadand check that.

So we'll say, if we havea style, let's unwrap it,otherwise you justuse the default style.

It's OK.Now thatwe've handled that,let the Playgroundre-execute and let's jump backto the timeline usingthe jump bar.

And once it's re-executed,we'll notice herethat we're now seeing all thedifferent UITableViewCell stylesin our tableView.

And so now, I have a Playgroundwhich I can, you know, share with my co-workers orjust keep it as a referencefor myself to see whateach UITableViewCell stylelooks like.

Let's go back to slides now.

So that showed you howgreat Playgrounds arefor experimentation.

You just get startedwith an idea,write some code, andsee how it works.

And now I'd like to inviteRick back on stage to talk about another great ideawe have for Playgroundsand that's AlgorithmDevelopment.

Rick?>> Thanks, Connor.

Developing algorithms and anyother separable pieces of code in a Playground isa great way to go.

And so to show you that, I'mgoing to dive right into a demo.

So what we're going to do todayis implement insertion sort, a fairly straightforward sort.

We're going to create a brandnew Playground to do that.

So I'll just say getstarted with a Playground,and we'll call thePlayground InsertionSortand save it on the desktop.

If you're not familiarwith insertion sort,imagine that you have a hand ofcards and you want to put themin order with thelowest values in the leftand the highest valueson the right.

One way you might do thatis, start with the secondto leftmost card and compareits value to the leftmost card.

If it's less, you'dswap the positionof the two cards in your hand.

You'd then look at the thirdto leftmost card and compare it to the second to leftmost.

If it's less, you'd swap it,compare it to the leftmost card,swap it if needed, and goon doing this for every cardin your hand until everycard had reached the correct,sorted position.

When you're done, yourhand will be in order.

So, let's implementthat in a Playground.

To start with, weneed some random datathat we're going to sort.

So, I'm going to goahead and I'm goingto declare an array of data.

I'm going to use varbecause this needsto be a mutable array, so Ican add to it and sort it.

And we'll just make an emptyarray of ints to start with.

And I could say fori in 0 through 20,because maybe I want20 data points.

I can say data. appendto add a new element.

And let's use thearc4random functionto generate a random number.

That doesn't return aSwift Int, so we're goingto cast it explicitlyto a Swift Int.

And we'll modulus it by 100 toget a number between 0 and 99.

So if I look at data here,you can see I have aresult here on the right.

Here's an array of what looklike pretty random numbers.

You'll also notice if I editthe Playground source again it reruns and I get a differentarray of random numbers.

Ah, OK, so that's great.

Well, it's nice to be ableto generate random databut I probably don'twant it to changeon me every time I editthe Playground sourcebecause that might make ithard to develop my algorithm.

So, let's grab this randomdata and use it every time.

To do that, I'm going toclick over the result sidebar and use command-A to selectthis data, command-C to copy it,and then I'm just going to pastethis in here as array literal.

And now I can work off thesame random data every time.

OK.So, let's startimplementing our algorithm.

The first thing weneed is a functionto swap two pointsof data in our array.

There actually is abuilt-in function called swapfor this already.

But for the sake of argument,we'll implement it ourselves.

So, I'm going to say func.

I'll call mine exchange.

You know, we're going to makethis a generic because, well, we have an array of ints.

Our insertion sort shouldbe able to work on any type.

So, any type at least aslong as it's comparable.

One element can becompared as greaterthan or less than another.

So, we'll mostly work oncomparable types here,the exchange functioncan work on any typebecause we just areswapping types.

So this is an exchangeusing a type D.

And it's going to take anarray of T and two indexeswhich we're going toexchange in the array.

So, the simplest way to exchangethese objects is to assign oneto a temporary variable,assign the second to the first,and assign the temporaryvariable to the second.

So, we can say lettemp equals data of i.

Data of i equals data of j.

And data of j equals temp.

OK.I think we'veimplemented this correctly but let's try it and find out.

I can say exchange,pass my data arrayand we'll say exchange the 0thelement with the second element.

And then we'll take a lookat our array when we're done.

So, before, element 0 was12, and element 2 was 15,now element 0 is 15and element 2 is 12.

So, it looks likeexchange works properly.

OK.The next thing we need isa function to, given an index,look at the datapoint of that index,compare it to the data pointto its left; if it's less,exchange them and keepcomparing and exchanginguntil it reaches the correctposition in the array.

So, let's call thisfunction swapLeft.

Again, it's a genericbut this time we needto actually do a comparison.

So, we're going to say our typeD is comparable and we're goingto pass an array of T and anindex of the data point we wantto start swapping left.

OK.So, let's implementthis, we're going to startwith our index and goback to position 1,not 0 because there's nothingto the left of 0 to swap.

So, I'm going to sayfor i in, and, you know,I could do a rangefrom 1 to indexbut what I reallywant is index to 1.

So I'm going to reversethe range with reverse 1.

3 dots makes it afully closed rangewhich means it will goall the way to index.

So, since I'm reversing this, itgoes from index and ends at 1.

And for each of these datapoints, I'm just going to say if data of i is lessthan data of i minus 1,exchange data i and i minus 1.

OK.If it's not lessthan data of i minus 1, it must have reached thecorrect sort of positionin the array, sowe can stop there.

So, let's say else break.

OK.Let's try this function out.

I'm going to go ahead andsay swapLeft, pass data,and let's pass element1, 2, 3, 4, 5, 6.

Let's pass element 6 left.

Oops! And look at our data.

And you can see the 0has moved all the wayfrom the 6th position tothe beginning of the arrayand everything's beenmoved to the right.

So it looks like thisfunction is working great too.

OK.The last thing we need isto actually implement the sort,so this should be pretty simple.

We'll call our function isort,works again on typeT that is comparable.

And we can just passan array of Tand it will sortthe whole array.

To do this, I'm just going tosay for i in 1 (we're starting at 1 because there's nothingto the left of 0 to sort to)to data. count, swapLeft,data and i.

So, let's try itout, isort data.

And we'll look our dataarray when we're done.

And you can see it did a wholebunch of assignments up here.

And now here's ourfinal array and it lookslike this is in sorted order.

So, we've correctlyimplemented insertion sort.

So, this is great for a simplealgorithm like insertion sort.

That wasn't too hard.

But you know if I was doingsomething more complicated, it might be nice tohave more visibilityinto exactly what'sgoing on here.

So, let's look at how wemight visualize our resultsin more detail.

Well to start out with, let'sdraw a graph of the results of the data at the beginning.

To do that, I'm just going tosay for x in data (to iterate through every data point)and just print out x.

And so, you'll see thereare 20 data points here.

So this line executed 20 times.

And if I click on theValue History button,I get a nice graph here showingmy data at the beginning and,boy, that does look random.

OK.So, now I wantto try to printout another graph everytime swapLeft is called,so I can see what'shappening to the graphover iterations of swapLeft.

And I could put this"for" statement in the endof swapLeft again andshow the Value History.

But again, in Value HistoryTimeline item for given,a line is going to show allthe data from that line.

So, each time swapLeftis called,its data would beappended to the same graph.

That's not what I want.

I want a new graph,every time it's called.

So to do that, we're going toneed a new tool in our toolbox.

I'm going to go back toslides and show you that.

With Playgrounds, we'reshipping a new framework called XCPlayground and it containssome very useful utilitiesfor enhancing your Playgrounds.

Right now, we have API formanually capturing valuesto display in timeline items,showing your views liveand extending executionfor asynchronous code.

Right now, we'regoing to use the APIfor manually capturing values.

That API is calledXCPCaptureValue.

It's a function that takes anidentifier, which is a string, and your value, whichis of any type.

When you pass it -- your value-- it will take that value and put it in a timelineitem for you.

So, the identifier that you passit identifies what timeline itemyou want that value to go to.

If you call this functionon different linesbut pass the same identifier,the values from thosedifferent lines will goto the same timeline item.

Conversely, and what we wanthere, if you have one line that calls XCPCaptureValuebut it's called multiple timeswith different identifiersand it passes thosedifferent identifiers,that one line can generatemultiple different timelineitems (or grabs, in our case).

That identifier is also shownas the name of the timeline itemso you can easily seewhat data is what.

The value pass can beanything, because it's a generic but it helps if it's a typeof value that we know howto Quick Look appropriately.

So, let's go backand give this a shot.

So to start out with, Ineed to import XCPlaygroundto make this API availableand I'm going to go aheadand define a new function.

I'll call it visualizeand it's a generic.

And it will take an array oftype T and I'm going to use this"for" loop in it, soI'll just indent thatand close the function.

But instead of justprinting out x, what we wantto do is capture that value.

So, I'll call XCPCaptureValue.

I need an identifier, solet's add one to our function.

So, identifier is astring and we could passthat identifier,and our value is x.

OK.So let's try this functionout and visualize the dataat the start of our sortand we'll label it Startas the identifier justso we know what's what.

And here you can see it ran andhere's our data at the start.

So that's a good start.

So now, we're going to goahead and visualize our data after every iterationof swapLeft.

So, I can call visualize,I'll pass data as it isafter this iterationof swapLeft.

And for our identifier, let'slabel it after the iteration, the number of timesthat swapLeft is called,which is the index parameter.

And so, I'm goingto let this run now.

And you can see that it'sgenerated multiple graphslabeled after theiteration that we're on.

So, now we can justscroll through hereand see what's happening to ourdata over time as swapLeft runsand the sort completes.

You can see it looks like ourdata is getting sorted piece by piece.

And so, at the end, wehave a nicely-sorted array.

So there, we can easilyvisualize exactly what's going on with our algorithm.

We think you'll findthis very, very useful.

OK.Let's move onto another example.

I've got a heap PlaygroundI made here earlier.

And it's got thisHeapGrapher class at the topwhich I'll explain in a moment.

But the meat of this classis my heap class which,if you're not familiar witha heap, a heap is a typeof balanced binarytree where the valueof every node isgreater than or equalto the value of its children.

Heaps are often used toimplement priority queues,because it's very efficientto remove the highestpriority item, that's the topof the tree, and it's alsoefficient to insert new itemsinto the correct position ofthe tree for their priority.

We're implementing our heapwith an underlying arrayto represent the tree.

And in our array, the treenoted index i has children at indexes i times 2and i times 2 plus 1.

So you can see down hereat the bottom we'vegot some random datathat we seeded ourselves with.

And we've created a newheap with that data.

And we "heapified the heap,"which is to say, put that data into correctly heap-sortedorder.

On the right, inthe results sidebar,you can see our defaulttreatmentof this custom class is toshow the name of the classand show its properties.

In this case, it hasone property which isthat heap array and here itis before it's been heapified,when it's not a correct heap.

And here it is afterit's been heapified,when it's purportedlya correct heap.

But you know, it's reallyhard to tell lookingat this array whetherthat's a correct heap.

This array representsa tree and, you know,not so good at visualizing,"Hh, well, here's I,and here's i times 2,and yeah, that's less. . . "Wouldn't it be much better ifI could just visualize thisas a tree everywheremy heap is referencedto my Playground source?So let's see how to do that.

In order to visualizemy own custom class,we're going to implementCustom Quick Look Supportfor this class.

Our Custom Quick Look Supportallows you to add Quick Looks for subclasses ofNSObject only (right now).

And to do it, you implementthe debugQuickLookObject method which takes no parametersand returns any objectas an optional.

And you're going to returnthe value that you wantto represent yourobject as its Quick Look.

So, right now, thatvalue (the valuesthat we support here) arecolors, strings (both plainand attributed),images, and Bézier paths.

So, for your Custom Quick Looksyou can use any of these types.

So, let's try it out.

OK.So I mentioned before Ihad a little HeapGrapher classthat I wrote.

That's a little class that knowshow to take an array and draw itas a tree, so we'regoing to use that.

We'll implement ourdebugQuickLookObject method.

It takes any, or returnsany object as an optionaland we're just going to createone of our HeapGraphers.

And this HeapGrapher knowshow to generate an NSImage which is one of the Custom QuickLook types, supported types.

So, we're just going toreturn the image it generates with g. graphHeap andpass self. heaparray.

And now, when this runs, insteadof showing the defaultrepresentation for our class,it shows our custom QuickLook representation,which is an image.

And so when I clickthe Quick Look button,you can see here it'sdrawing my heap as a tree.

This is before it's beenheapified when you can see,for example, 78 is less than 89.

So this is not a correct heap.

But if I Quick Look itafter it's been heapified,I can now go, oh great, 91is greater than 86 and 89,86 is greater than 84 and79, and so on and so forth,and I can reallyeasily visually verifythat this is a correct heap.

So that's how you can Quick Lookyour own classes in Playgroundsand we think you'llfind that very useful.

All right.

Next, we'd like to move on toshowing you how great it is to do Custom View Developmentand other drawingdevelopment in Playground.

And to do that, I'm goingto hand it over to Connor.

>> Thank you, Rick.

Another great use case wethink Playgrounds will be used for is Custom View Development.

And that's because you canjust start writing some code and see the actual viewas it's being drawnand as you're starting tobuild up your drawing code.

So for this I have a goal.

I want to take thisPlayground iconand add some animation to it.

The icon that wehave is really great.

It conveys the playfulnessof Playgrounds.

But unlike Playgroundsthemselves, it's static.

There's nothing dynamicabout it.

And so, I'm going to tryto add animation to this.

And what better wayto do it than whenin a Playground itself?So, let's jump over to the demo.

So OK, here I'm going to goahead and open up a Playground that I've already started.

So, OK.So here we'vegot a Playground.

We've got our subclass of NSViewcalled PlaygroundIconView.

It has a few layers.

It's got these three instance,er, these three instance methodswhich actually do thesetup of those layers.

You see that they'reunimplemented right nowand we'll come backto that in a moment.

I also have an extension ofNSColor which defines a couple of colors for thePlayground icon itself.

I then have a helper functionto convert an NSBezierPath to a CGPath for usewith CAShapeLayer.

Finally, I just go aheadand create an instanceof my PlaygroundIconView.

And then, I put iton a separate lineso I can add some stuff later.

Let's go ahead and showthat in the timeline.

So, OK.So you'll see nowthat we've just gotourselves an empty view here.

So yes, we have anempty view here.

We actually justnow need to go aheadand implement thesesetup functions.

So let's go ahead and do that.

So we'll start outby creating the pathfor the background layer.

So you can see here we'recreating NSBezierPathand we can Quick Look it tomake sure it looks right.

And in fact, yeah,that looks more or lesslike the Playground icon.

So let's tell, let'ssetup our layer.

So OK, now we'resetting up the layer.

You can see here in the timelinethat we're now drawing thelayer where, you know. . .

We have the background, we'vegot the little border there, and so, OK, we've gotour background set up.

Let's also do the seesaw baseand we'll do the same thing.

We'll create a path for that.

And we'll let it executeand we'll see here,let's Quick Look, make sure. . .

Yeah, that looks more orless like the little basethat we have for theplay- . . . for the seesaw.

So let's set up thelayer itself as well.

And there, we justmake that changeand immediately get the feedbackof seeing what that lookslike when drawn in our view.

Let's also do the seesaw layer.

I've got some code hereto set that up as well.

You see here that we're just,you know, have a closure which will create thechild layer itself.

We then create a coupleof layers for the childrenon each side of the seesaw, andthen we set up the bench itselfand then add those layersto our seesaw layer.

So, OK.So now we'vegot ourselves something that looks kind of likethe Playground icon.

But like the icon itself,it's not animating.

So let's go ahead andadd support for animationto our PlaygroundIconView.

I have a snippetfor that as well.

And so, let's walkthrough what this is doing.

I define a constant for themaximum angle of the seesaw.

I've, you know, workedthrough this and I think piover 12 is about right.

I also have a property for thecurrent angle of the seesaw after any pendinganimation is finished.

And then have a propertywhich determines whetheror not it should be animating.

It starts out as falsebut we have this code herewhich executes wheneverthis is set to say, "Well,if the animation statehas changed and we're toldto animate, then juststart animating dependingon the current angleof the seesaw. "I then have this helper methodfor actually performingthe animation itself.

So we just, you know, go aheadand create a CABasicAnimation,set a couple of values,set our timing functionto match what a seesawwould actually look like.

Set the duration to whatwas passed in which defaults to 1-1/2 seconds, but canbe customized dependingon the angle of the seesaw.

We then add the animationto our seesaw layer.

We set the underlying transformproperty of that seesaw layer,so that once the animationcompletes it looks correct.

And then we update ourcurrent seesaw angleproperty accordingly.

Finally, we have, uh, weimplement the "animationDidStop, finished" delegate callback.

Or basically saythat if we finishedand we're still supposedto still be animating,then just go ahead andanimate to the opposite angleof what we currently are at.

So, OK.Let's go ahead and tellthis view to start animating.

So we'll do that and you'llnotice that after it reruns, we seeing the view updateit's look, you know,so we see that ittilted over to the side.

We're not seeing theanimation itself.

And for that, we'regoing to need some helpfrom the XCPlayground framework.

So, let's switch back the slidesto see what thatcould look like.

So the second pieceof functionalitywhich the XCPlayground frameworkprovides is the abilityto show live viewsin the timeline.

And you do that by callingthis XCPShowView function.

It takes an identifier and theview that you want to show.

After calling it, we'll show theview live while the Playgroundexecutes and thenwe'll record framesas the Playground executesso you can play them backonce execution finishes.

The identifier you pass to thisfunction must be unique insideof the Playground.

That's because thisis how we referto the live viewinternally in Xcode.

And it is also whatwe'd show as the titlefor the live viewin the timeline.

The view pass must alsonot have a superview.

This is because we will addit to our own view hierarchy and it would generally notproduce the results you'relooking for.

So with this in our toolbox,let's jump back to the demo and see how it's used.

So I'm going to goahead and just go aheadand import XCPlayground.

And then down here, insteadof just having this view item, I'm going to removethat from the timeline.

I'm going to saysomething like XCPShowViewand pass an identifier.

It can be anything aslong as it's unique.

So I'll say PlaygroundIcon View.

And then I'll pass theview that we've created.

So, we'll just letthat re-execute.

And you see therethat in the timeline,we're showing the viewlive as it's animating.

You-all also probably noticedthis little timeout field down here.

And that lets us specifythe amount of timewhich we'll let thePlayground continue executingafter we reach the end ofexecution of the top of a code.

Now, it defaults to 30 secondsbut I'm going to adjust this down since I know myanimation only takesabout a second and a half.

So I'll do 10 seconds toget a few times around.

After we edit that,we'll rerun it.

And so that's great, youknow, we see it running there.

And I'd like to show how youcan integrate XCPShowView with the XCPCaptureValueAPI we mentioned earlier.

And so, what I'm going to do,I'm going to capture the angle of the seesaw, orof the left edgeof the seesaw aswe're animating.

So here, I'm just goingto say XCPCaptureValue.

I'll pass Left SeesawPosition and I'll just pass because we know atthis point that it's,you know, it's flat on there.

Then you can take this andI'm going to put it in our "animationDidStop,finished" callback.

Now I'm going to just pass thenegative currentSeesawAngle.

That's just because that'swhat we need to do in order to get the left positionof the seesaw.

That is how the angle worksout for the transform.

So you see here thatas we're executing,we're getting the graph kindof building up over time.

And then once executionfinishes,the graph will snapback into place and kindof show you the best view ofthe data that it collected.

It's OK.You probablyalso noticed this slider became active.

And so, I can just goahead and take thatand drag it through here.

And you'll notice that we'reupdating the graph at the bottombut we're also showing youthe animation, you know,as it went through in time.

So this is, you know, afairly basic animationand it's doing what weexpected but, you know,if you had somethingmore complex and you wantto just kind of take a lookat just a small portionof your animation, youcould do that as well.

And I can also dosomething like, you know,click on one of these points.

So I can click there.

We can see it, you know, thatthe two things are in sync.

I click there.

It updates the point.

I can use the arrow keys togo through the graph's points and see that, OK,yeah, you know,we're doing whatwe expect it to do.

And so, that's how you canshow live views in the timeline with the XCPlayground framework.

Let's go back to the slides now.

Now, I'd like to talk to youabout how you canuse asynchronous codein your Playgrounds.

You got a little taste ofthis in the demo before.

But I'd like to go into alittle bit more detail now.

The third piece of functionalitywhich the XCPlayground frameworkprovides is the abilityto extend execution.

By default, execution terminatesonce all top-level code has executed.

XCPlayground, though,provides APIfor extending executionindefinitely.

That's thisXCPSetExecutionShouldContinueIndefinitely function.

You should know that this isactually not quite indefinite.

The execution time is controlledby the timeline's timeout which defaults to 30 seconds.

Additionally, executionwill be terminatedif you edit the Playgroundwhile it's running.

This is so that we can showyou up to date results rather than let, leaving you astale results while we waitfor an earlier executionto finish.

Additionally, as you sawon the last demo, you know,we didn't actuallycall this function,but we saw that executioncontinuedafter we reached theend of top-level code.

That's because XCPShowViewimplicitlycalls XCPSetExecutionShouldContinueIndefinitely.

You should just thinkabout this as if nothingin the Playgroundsource has told Xcodethat the Playgroundused to stay alive,then the Playground will stopexecuting once we reach the endof top-level code.

So now, I'd like to show youa quick demo of what it's like to use asynchronouscode in Playgrounds.

So here I am back hereand I have a Playgroundwhich uses asynchronous code.

We create, uh, we haveour session delegatewhich is anNSURLSessionDelegate.

It has a few callbacks.

And then we also just, you know,create an instanceof our delegate.

We created an NSURLSession.

And then create a data taskto download the contentsof the Apple home page.

We then tell thedata task to resume.

And you noticed that, you know,the Playground itselfhas executedbut we're not receivingany results up here.

And if I open up theassistant editor, you'll noticethat we haven't received anyconsole output even though theywere clearly logging here thatwe've received some bytes.

And this is because nothingin the Playground hastold the Playgroundthat it should continueexecuting.

So we call task. resume, weresume the task and then as soon as that finishes, we hitthe end of top-level codeand the Playgroundjust stops executing.

Let's go ahead and sayimport XCPlayground.

And then we can sayXCPSetExecutionShouldContinue,XCPSetExecutionShouldContinueIndefinitely.

This takes a Bool butthat defaults to true,so you typically don't needto pass anything there.

And I won't do that here.

You'll now notice that, youknow, we were receiving results from here and we're alsoseeing the console outputthat we expect in the timeline.

So OK, that's how youuse asynchronous codein Playgrounds.

Let's go back to slides now.

There are a few alternativesbut we really thinkthat you should typicallyuse XCPSetExecutionShouldContinueIndefinitelywhen you're tryingto use asynchronouscode in Playgrounds.

If that won't workfor you though,you can use othermethods for waitingfor asynchronousoperations to finish.

Basically, you just need to makesure you don't reach the endof top-level code beforeyour operation completes.

Before we leave today, I'd liketo talk to you a little bit about some of the limitationswe have with Playgrounds.

First off, you shouldnot use performance, uh,Playgrounds for anyperformance testing.

That's because thelogging of resultsin the Playground willgenerally dominate the runtime,not your actual code.

This means that the performancewill be dependent on the numberof lines of code executed,not the actual performanceof whatever it isyou are developing.

And that's not necessarilywhat you'd expect.

Instead we'd suggest thatyou use the XCTest framework to create performancetests in a test bundlewhere you can getmore accurate results.

We have a session later thisweek called Testing in Xcode which will go intothis in more detail.

There are few morelimitations with Playgrounds.

Playgrounds cannotbe used for thingswhich require user interaction.

So we have great supportfor showing live viewsbut you can only see them,you can't touch them.

We also do not support usingPlaygrounds for anything which require customentitlements.

For iOS Playgrounds, weonly support executingagainst the simulator.

So anything which requires adevice will not be supported with Playgrounds.

And finally, we do notsupport using your own appor framework code in aPlayground unless it's somethingthat you can just copy