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 visualization  of the results of your code.

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

We'll introduce theXCPlayground framework  which includes somereally powerful utilities that 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 way  you visualize the classesthat come with the frameworks.

Next, we'll showyou a great demo  of how awesome Playgrounds arefor developing custom views and in any other kindof custom drawing and we'll show you how you canuse your own asynchronous code with Playgrounds.

Finally, we'll finish uptoday with a little bit  about 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 you edit your Playground file.

Swift Playgrounds also can contain a folder  of embedded resources which are made available to your code or your Playground can reference resources elsewhere on your system you want to make available.

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

When you first opena Playground,  we show the Playground Editorwith your Swift code on the left and the results sidebar onthe right showing the result of every expressionin your code.

Every time you edit your source,we rerun your Playground source from the top to the bottomand present the new results from 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 you  to visualize yourresults in more detail.

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

In this case, sinceit's a numeric value,  we'll draw a graph ofthat value over time since 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 run after the top of asource is finished if 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 point  in your Playground execution.

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

But you'll find this isvery useful with live views  as it allows you to scrubback through the recording of that view and see exactlywhat your animation was doing at 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 use  of 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 open  up a Playground anddive in and play around.

Our documentation also includesa special interactive Playground called the Swift Tour.

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

So you can read about howto do something and try it  out 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 Editor  and 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 be  in indispensabletool in your toolbox for everyday code development.

If you're developingan algorithm  or 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 project for use in your application.

Any sort of drawing codeyou want to do is also great  in a Playground because youcan immediately see the visual  result 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 sequence of image filters aregreat in Playgrounds because you can visualizethe result at every step of the transformation process.

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

We think you'll find  that Playgrounds are fertileground for experimentation.

And in particular,any time you're trying  to learn some newAPI, you should try it out on a Playground because youcan immediately see how it works and 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 gone  to 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 too  so you can see what happened.

You don't have todo that anymore.

Now you can just openup a Playground and try  out 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 want  to try something it's rightthere at your fingertips.

So with all that said, let'sdive in and take a look  in 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 things  which we think Playgroundswill be really great for.

Now, Rick has alreadycovered many  of the basic conceptsbehind Playgrounds.

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

So, let's go ahead and do that.

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

Now you'll notice herethat on the Welcome window  for Xcode we've added thisbrand new "Get started with a Playground" button.

It's that way we want tomake it really easy for you  to 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 putting  on 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 string  and we're assigningthe value, "Hello, Playground" to that string.

You'll notice that in the resultsidebar we're seeing the result of 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 code  and we're getting anindicator in the result sidebar that we've executedthat code 10 times.

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

We'll let it runand we'll see there  that we immediatelyget an indication that this code hasexecuted 100 times.

Now, knowing that isvery useful information  but 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 code  with 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 well as a place for you tostore results which you like 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 showing  in the result sidebar a colorswatch indicating what the color is as well as indicatorsof all of the components which make up that color.

So I can, you know,take this color  and 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 have  and we'll create a dictionary.

So we'll sayNSForegroundColorAttributeName  and 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,systemFontOfSize  and then let's go to somethingfairly big, so I'll just put in 42, see what that looks like.

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

You're seeing that we're showingthe plain text representation of this, as well asan icon indicating that 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 itself  and we support that as well.

So I can just hover overthe result and in addition  to 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 Look of that value to show youthe full representation of it as it was created inthe Playground source.

So, OK, that's colorsand strings.

Let's try something with images.

Let's actually start  up 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 do with like NSImageNameUseror accounts or something in that line.

So I'm just going to createan array with imageNames  that 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 images  and 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 times  for the trailing closure itself.

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

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

You just go ahead and putthe thing that you want  to 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 origin  because 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 ImageView  on 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 object  and then you put another linewhere we show it as a result.

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

So you see here thatwe're starting  out 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 there  but 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 equalsImageScaleProportionally  UpOrDown. And we'llre-execute and now you'll see that 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 going  to 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 Settings which is shown whenever you'reviewing a Playground document.

You can select the platform  against 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 one  if you have resourcesthat you're interested in.

In this case, I'm just going tosay I have a folder of resources on 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 ahead and hide the Utilities area.

And to access the imagesthemselves, I just use,  you know, NSBundle API, youknow, the resources show up 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 notice  that 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 have  that 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 notice  that we're still seeingthe older version here with 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 saw  where it's small in the center.

Then I set the imagescaling appropriately  and 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 is  that 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 created in the Playground source.

We support many different types  for 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 view at that point in time.

We can show arraysand dictionaries  as we'll show a structuredversion of the array or dictionary, ah,like you might see in 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 URL and show it in the sidebar.

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

And finally, for types  if 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 class  that 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 line  of 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 somewhere  on my computer andI'd like to show it and use it with the Playground. " We have a Relative toPlayground path option.

And this is really great  if 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 check out your repository, then itwill automatically be able to use the Playgroundwith its resources. " Finally, we support anInside Playground option.

And this is greatif you're sharing  in 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 people  and see, when they openit, they'll be able to 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 resources  for 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 some of the use cases forwhich Playgrounds would be really great.

And the first of theseis Experimentation.

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

It's just a bunch ofXcode projects created  from the template that are,you know, maybe 1 or 2 changes to 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 find the right file in that projectto edit which may be easy or 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 have  to build your project.

You then run whatever you built.

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

And if you didn't get it rightthe first time, you'd then have to redo this, stop inthe debugger and step through 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 started  with a Playgroundand write your code.

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

So now, I think I'dlike to show you a demo  of 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 test  out 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 cells  into 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 conform  to the UITableViewDataSourceprotocol.

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

And, you know, that's expected.

We haven't actuallyimplemented any methods yet.

So, I'm actually going tojump to the declaration  of 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 cells so 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 fact  that 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 issue  in our Playground.

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

That's because we haven'tactually instantiated our  data source.

So, I'll just say something likeDataSource equals DataSource and then I can, you know,I'll just create a TableView and 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 able to 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 able  to 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 styles  for all the styles that we have.

So, I'm going to jumpback to the declaration  of 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 row that we're currently at.

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

And I'll say somethinglike let style equals  UITableViewCellStyle. 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 optional  UITableViewCell 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 back to the timeline usingthe jump bar.

And once it's re-executed,we'll notice here  that we're now seeing all thedifferent UITableViewCell styles in our tableView.

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

Let's go back to slides now.

So that showed you howgreat Playgrounds are  for 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 Playgrounds  and 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 InsertionSort and save it on the desktop.

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

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

If it's less, you'dswap the position  of 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 card in 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 data  that we're going to sort.

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

I'm going to use varbecause this needs  to 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 function  to generate a random number.

That doesn't return aSwift Int, so we're going  to 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 data  but I probably don'twant it to change on me every time I editthe Playground source because 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 function  to swap two pointsof data in our array.

There actually is abuilt-in function called swap  for 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 greater  than or less than another.

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

So this is an exchangeusing a type D.

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

So, the simplest way to exchangethese objects is to assign one to 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 array  and 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 exchanging until it reaches the correctposition in the array.

So, let's call thisfunction swapLeft.

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

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

OK.  So, let's implementthis, we're going to start with 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 index but what I reallywant is index to 1.

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

3 dots makes it afully closed range  which 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 position  in 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 way  from the 6th position tothe beginning of the array and 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 T  and 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 looks  like 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 visibility  into exactly what'sgoing on here.

So, let's look at how wemight visualize our results  in 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 print  out another graph everytime swapLeft is called, so I can see what'shappening to the graph over iterations of swapLeft.

And I could put this"for" statement in the end  of 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 utilities  for enhancing your Playgrounds.

Right now, we have API formanually capturing values  to display in timeline items,showing your views live and extending executionfor asynchronous code.

Right now, we'regoing to use the API  for 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 item you want that value to go to.

If you call this functionon different lines  but pass the same identifier, the values from thosedifferent lines will go to the same timeline item.

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

That identifier is also shownas the name of the timeline item so 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 how  to Quick Look appropriately.

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

So to start out with, Ineed to import XCPlayground  to make this API availableand I'm going to go ahead and 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 that and close the function.

But instead of justprinting out x, what we want  to 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 pass  that identifier,and our value is x.

OK.  So let's try this functionout and visualize the data at the start of our sortand we'll label it Start as 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 is  after 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 graphs  labeled after theiteration that we're on.

So, now we can justscroll through here  and see what's happening to ourdata over time as swapLeft runs and 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 top  which 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 type of balanced binarytree where the value of every node isgreater than or equal to the value of its children.

Heaps are often used toimplement priority queues,  because it's very efficient to remove the highestpriority item, that's the top of the tree, and it's alsoefficient to insert new items into the correct position ofthe tree for their priority.

We're implementing our heapwith an underlying array  to 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 here  at the bottom we'vegot some random data that 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 defaulttreatment of this custom class is toshow the name of the class and show its properties.

In this case, it hasone property which is  that 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 looking  at 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 this as a tree everywheremy heap is referenced to 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 Support for 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 parameters  and returns any objectas an optional.

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

So, right now, thatvalue (the values  that we support here) arecolors, strings (both plain and 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 class that I wrote.

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

We'll implement ourdebugQuickLookObject method.

It takes any, or returnsany object as an optional  and 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, instead  of 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 verify that this is a correct heap.

So that's how you can Quick Lookyour own classes in Playgrounds and 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 Development  and 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 drawn  and as you're starting tobuild up your drawing code.

So for this I have a goal.

I want to take thisPlayground icon  and 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 when  in 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 methods which actually do thesetup of those layers.

You see that they'reunimplemented right now  and 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 instance  of my PlaygroundIconView.

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

Let's go ahead and showthat in the timeline.

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

So yes, we have anempty view here.

We actually justnow need to go ahead  and implement thesesetup functions.

So let's go ahead and do that.

So we'll start outby creating the path  for the background layer.

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

And in fact, yeah,that looks more or less  like 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 timeline  that 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 base  that we have for theplay- . . . for the seesaw.

So let's set up thelayer itself as well.

And there, we justmake that change  and immediately get the feedbackof seeing what that looks like 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 children  on each side of the seesaw, andthen we set up the bench itself and 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 animation  to 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 pi  over 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 whether  or not it should be animating.

It starts out as falsebut we have this code here  which executes wheneverthis is set to say, "Well, if the animation statehas changed and we're told to animate, then juststart animating depending on the current angleof the seesaw. " I then have this helper method for actually performingthe animation itself.

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

Set the duration to whatwas passed in which defaults  to 1-1/2 seconds, but canbe customized depending  on 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 angle  property accordingly.

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

Or basically saythat if we finished  and we're still supposedto still be animating, then just go ahead andanimate to the opposite angle of 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 help  from the XCPlayground framework.

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

So the second pieceof functionality  which the XCPlayground frameworkprovides is the ability to 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 Playground executes and thenwe'll record frames as the Playground executes so you can play them backonce execution finishes.

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

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

And it is also whatwe'd show as the title  for 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're  looking 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 ahead  and 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 XCPShowView  and 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 time  which we'll let thePlayground continue executing after 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 takes  about 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 edge  of 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 kind of 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 that  and drag it through here.

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

So this is, you know, afairly basic animation  and it's doing what weexpected but, you know, if you had somethingmore complex and you want to just kind of take a lookat just a small portion of 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 you  about how you canuse asynchronous code in 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 functionality  which the XCPlayground frameworkprovides is the ability to extend execution.

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

XCPlayground, though,provides API  for extending executionindefinitely.

That's thisXCPSetExecutionShould  ContinueIndefinitely 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 terminated  if 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 wait  for an earlier executionto finish.

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

That's because XCPShowViewimplicitly  calls XCPSetExecutionShould ContinueIndefinitely.

You should just thinkabout this as if nothing  in the Playgroundsource has told Xcode that the Playgroundused to stay alive, then the Playground will stopexecuting once we reach the end of 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 Playground  which uses asynchronous code.

We create, uh, we haveour session delegate  which 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 contents  of the Apple home page.

We then tell thedata task to resume.

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

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

And this is because nothing  in the Playground hastold the Playground that it should continueexecuting.

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

Let's go ahead and sayimport XCPlayground.

And then we can sayXCPSetExecution  ShouldContinue,XCPSetExecutionShould ContinueIndefinitely.

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 output  that we expect in the timeline.

So OK, that's how youuse asynchronous code  in Playgrounds.

Let's go back to slides now.

There are a few alternativesbut we really think  that you should typicallyuse XCPSetExecutionShould ContinueIndefinitelywhen you're trying to use asynchronouscode in Playgrounds.

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

Basically, you just need to makesure you don't reach the end of 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 results  in the Playground willgenerally dominate the runtime, not your actual code.

This means that the performancewill be dependent on the number of lines of code executed,not the actual performance of 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 bundle  where 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 things  which require user interaction.

So we have great supportfor showing live views  but 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 executing  against the simulator.

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

And finally, we do notsupport using your own app  or framework code in aPlayground unless it's something that you can just copy and pasteinto the Playground source.

Basically, you can only usethings in the standard library,  in the SDK, or that's in thePlayground source itself.

You can get around some of theselimitations by using the REPL.

The REPL is the commandline interface to Swift  and it works this way becausethe REPL can actually execute in your own process.

You just stop at a breakpoint,and then at the LLDB prompt,  you execute the REPL commandand you'll just be dropped  down right into the Swift REPL.

Playgrounds though provide aricher experience than the REPL.

And that's because we willautomatically execute your code  from a known state.

That means, you know, you make asingle edit to a line and then, you know, we justrerun it from 0.

Whereas with the REPL, ifyou wanted to make an edit  to something earlier in thesource that you had entered, you have to, you know,get the process back into the state then, youknow, reenter the REPL, retype everythingmaking that one change to see how it affects things.

Playgrounds also supports someof these higher level futures  like Quick Looks and a timelinewhich we do not support, uh,  which the REPL does not support.

If you'd like to learnmore about the REPL,  you can go to the Introductionto LLDB and the Swift REPL talk.

And we'll go into much moredetail about how the REPL works.

In summary, we think Playgroundsare a great way to play  with Swift, with Cocoaand with Cocoa Touch.

We think you can use themfor things like learning,  exploration and visualizationand frankly probably tons of things which we haven'teven thought of yet.

The XCPlaygroundframework provides APIs  for using your Playgroundsfor more advanced things.

So you can do things likemanually capture values  with the XCPCaptureValue API.

You can show live views in thetimeline by calling XCPShowView.

And then you canalso extend execution  for asynchronous operationswith the XCPSetExecutionShould ContinueIndefinitely function.

Finally, we'd really like tojust encourage you to go out  and give Playgrounds a try.

I think, you know,they're really approachable  and if you just sitdown with them for a little bit you'llfind a number of great ways to integrate them intoyour development process.

For more information, you cancontact our Developer Tools  Evangelist, Dave DeLong.

We also have someinformation about Playgrounds  in the Source EditorHelp for Xcode 6.

You can also askquestions about Playgrounds  on the Apple Developer Forums.

We have several relatedsessions about Swift this week.

So there was an Introductionto Swift session yesterday,  which you can catchon the video.

We also have an IntermediateSwift session later  this afternoon.

There's also an AdvancedSwift session tomorrow  which you'll be able to see.

We had an Integrating Swift  with Objective-C sessionearlier this morning which you can catch on video.

And we also have aSwift Interoperability  in Depth sessionlater this afternoon.

Finally, if you'd like to learnmore about the Swift REPL,  you can go to theIntroduction to LLDB  and the Swift REPL session.

Thank you all for coming  and I hope you have agreat week here at WWDC.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值