What's New in Xcode 6

Session 401 WWDC 2014

Xcode is the development environment for creating amazing apps for iOS and OS X. Start the week by watching the Xcode team demonstrate the latest features and workflows in Xcode 6. This session also provides a complete overview of the in-depth developer tools topics covered at WWDC 2014.

Good morning.

Welcome to WWDC and this is "What's New in Xcode."

You guys saw a lot of new stuff yesterday.

Today, we thought we would take a deep dive into a few specific areas of Xcode 6.

Before we do, though, let's take a look at what's happened since last time that we were here together.

I hope you guys are all using and enjoying Xcode 5.1.

Since last year, one of the biggest new things that we added was support for iOS 64-bit.

And you guys have done an amazing job of adopting 64-bit in your apps to take full advantage of our latest devices.

We've also made significant improvements to auto layout in Interface Builder and added new APIs to make your own classes work with Debugger Quick Look.

This fall we'll be releasing Xcode 6 with an even more beautiful and functional interface to go along with OS X Yosemite.

Let's take a quick look at some of the new features in Xcode 6.

First of all, we have a brand new programming language for Cocoa development called Swift.

And Swift is exciting enough on its own, but we didn't stop there.

Playgrounds provide a live and responsive environment for you to develop code.

Whether you're exploring new technologies, like Sprite Kit physics courses, or just playing around with Swift itself, you're going to love the experience of playgrounds.

Playgrounds also offer a great learning environment.

The Swift language guided tour is actually a playground where you can try things out right as you're reading and learning about Swift.

And of course Swift is fully integrated into Xcode.

Everything from code completion to connect from source in Interface Builder works beautifully with Swift.

When you're working in Swift, Xcode knows.

If you ask to see the interface for a framework class, Xcode will show it to you in Swift.

And when you ask for Quick Help, you get help in Swift.

Now, Quick Help actually has another new trick.

Oh, that's not that build.

So we have another new trick that works well with Swift's inferred types.

If you're ever curious about what type is being inferred by Swift, Quick Help can tell you.

And you can freely mix Swift into your existing Objective-C applications.

We'll be showing you how easy that is in a few minutes.

Now, let's talk about some of Xcode's design tools and the new features there.

You're probably all familiar with using storyboards to develop your iOS applications.

And in Xcode 6, you can use storyboards to develop your OS X applications as well.

In iOS, the new adaptive UI lets you have a single storyboard for your universal applications, while still retaining full control over customizing your interface for both the iPhone and the iPad.

And if you use custom fonts in your application, you can now see them right on the canvas in Interface Builder.

[ Applause ]

We have some brand new editors in Xcode 6 too, like the Sprite Kit Level Editor that lets you visually assemble scenes.

Xcode 6 has a brand new way to localize your applications.

You can export all of your localizable content into XLIFF, which is the industry-standard format that's understood by a lot of translation services.

And when you get those translations back, just import and Xcode will help you to merge that new content right into your project.

And with iOS 8's support for frameworks, you can now build IB components.

Just by adding a few attributes to your classes, you can get them to show up right in IB's canvas and configure them in the inspector.

We'll be showing you how easy it is to make your views into IB components.

Now, Xcode 6 makes debugging better than ever.

Often, when you're debugging using queues, it's not quite enough just to see the code that's running on the queue.

So in Xcode 6, we now show you how that block got onto the queue also.

When you're developing the new app extensions, debugging support is easy and automatic.

For example, if you're developing a Today View extension, just hit Run in Xcode, bring up Notification Center on the device and Xcode will automatically attach to your extension for debugging.

Xcode 6 has some brand new debug gauges to help you identify problems with disc and file I/O, disc and network I/O.

And View debugging gives you deep insight into visual problems.

We'll be showing you how easy it is to identify and fix problems with your view hierarchy and constraints using View debugging.

Xcode 6 has some all-new performance features as well that will help you to make your apps faster and leaner.

Our premier performance tool, Instruments, has a brand new interface with new workflows that make it easier than ever to analyze your app's performance.

Last year we introduced Xcode Server, and one of the biggest requests that we got was for the ability to customize what happens when you're running continuous integrations.

So in Xcode 6, we've added support for triggers that allow you to add custom behavior to your bots.

And we've added support in the XE Test Framework in Xcode and in Xcode Server for performance tests.

It's easy to make a performance test.

You just wrap your code in a measureBlock.

Performance tests let Xcode measure the speed of your code and tell you whenever it has improved or regressed.

And in order to help you to make your apps even faster, you can now profile your performance tests directly in Instruments with just a choice from this context menu.


[ Laughter ]

[ Applause ]

It's the little things, right?

Xcode also includes all-new reports that show you exactly how your performance tests are doing.

And we'll be showing you how easy it is to start writing performance tests for your projects and using them to make your apps better.

So that's just a quick tour of some of the feature areas in Xcode 6.

And now we'd like to dive in deeper and give you a detailed look at a few of these areas.

To get us started with that, let me introduce Daniel Dunbar.

[ Applause ]

Thanks, Mike.

This talk is called "What's New in Xcode," and obviously the big new thing this year is Swift.

I'm sure you're all really excited about this new language we unveiled yesterday.

And I imagine many of you are wondering, "Well, how quickly can I start using this in my own applications?"

So we'd like to kick off our demos this morning by showing you just how easy it is to integrate Swift into an existing application.

We've created this new photo scavenger game.

Let me show it to you now.

Our game is called Shutterbugs, and when I open it up, you'll see our game starts with this great looking sign-on screen, and it takes the user right into the game.

That's been working great, but our app has really been taking off recently, and users tell us they want to be able to play multiple games at one time.

So for Version 2, we'd like to introduce a new games landing screen that shows users their in progress and completed games.

And of course we'd like to do it in Swift.

Now, my designer has already updated the storyboard to include this table view controller shown here.

All we need to do to finish off this new feature is implement the code for it.

So I know I'm going to eventually want a custom cell class for my table, so I'll start with that.

Going to go to Views and select New File from the popup menu.

Of course, I want an iOS Cocoa Touch class.

And the first thing you'll notice on this screen is that there's a new language chooser at the bottom that lets you decide whether you want a Swift or an Objective-C class.

Of course I want Swift, and in this case I want a subclass of a UI table view cell.

I'll call it GamesTableView Cell.

Drop that in my project...

and Xcode takes me to the source.

These subclass templates are a great way to get started with the new language.

So for us, the main thing we'll need is a couple of properties that we can use to connect our UI to.

So let me add that to start with.

As you can see, property declarations in Swift are very clean and simple.

And we just needed to add this IBOutlet attribute so that we could connect to it from Interface Builder.

Now that that's in place, let me go back to my storyboard.

So I'll select my prototype cell, and I need to associate the class with it.

If I pull down this menu, you see that Interface Builder has already recognized our new class using our Swift indexing support.

So I'll select GamesTableView Cell.

Now, you may notice there's a new module field here.

Another great way that Swift improves the coding experience is by associating classes with the modules that they are declared in.

That allows you to use short, comfortable class names while still ensuring that your classes won't collide across targets and projects.

With that in place we can set up our connections.

I'll close the Utilities panel and open our source code in the Assistant Editor.

And now I can wire up my connections just like you would expect.

I'll set the name, the state label, and we have a custom progress view here.

OK, that should be enough to let us get started with our custom cell.

So now let's fill in the details of the controller.

I've already added the basic subclass template with a couple tweaks, but we need to fill in the details.

So the first thing that every controller class needs is access to the model data that it's going to present.

For our application, most of our model data is stored in a user session class.

So let me add a property to hold that now.

So I'll call it userSession and declare its type.

Naturally, we have live issue support in Swift, and if I pop this open I can see it's telling me there's an undeclared type here: userSession.

I haven't imported that class yet.

Now, in Swift, all of the classes in one target are automatically visible to each of the source the Swift implementation files.

You no longer need to worry about manually importing the headers for each of the classes that you use.

[ Applause ]

Yep. However, you do still need to import the modules for the frameworks that you depend upon.

To go along with iOS 8's new framework support, Xcode now has support for you to define modules out of your own frameworks.

And those modules can be used in both Swift and Objective-C.

But we've already started taking advantage of that in our application by moving all of our model code into this new CoreShutterbugs framework that you can see.

That means, to use this fix this problem, all I need to do is type Import CoreShutterbugs just like I would for any other framework on the system.

And of course the error goes away.

Now, our table view is going to have two different sections.

We'll have one for the in-progress games and then one for the completed games.

So I want to start by creating a utility method that lets me easily get the appropriate list for each section.

I'm going to call it gameListForSection.

And what I want to return here is the result of the user sessions "getFilteredGameList" method.

You can see that even though this is a method that we declared in our Objective-C source code in another framework, I still get code completion and even the documentation for that method in my Swift source code.

So I'll complete that out.

And what I want to get is the in-progress list when the section number is 0.

I'm also going to add a cast here to a game array.

What I'm doing here is taking advantage of Swift's typed collection support to tell the compiler that each object in this array is an instance of my game class.

That way, whenever I use this array later in the code, the Swift compiler will know the exact type of each object.

There's one more utility I'd like.

In a table view you frequently want to get the data associated with a particular cell, and that cell is represented by an index path.

So I'll create a method that lets me easily get the game for a particular index path.

Going to call that one gameForIndexPath, and it returns an optional game.

With those methods in place, should be easy to write our table view data source.

Let me drop that in.

What I'm doing here: setting the number of sections to be 2...

I'm going to return an appropriate number of rows for each section using that first utility method we added, and I'll use gameForIndexPath to easily get the particular game and then propagate its data into our custom cell whenever we need to dequeue a new cell.

I've also added a prepareForSegue method to set up our destination view controller when the transition happens.

OK, we're almost done, but I'd like to do one more thing before we call our controller a wrap.

You can see that I'm already modifying the separatorInset on this table to give our table a little bit of a custom look.

That's all right, but I just heard about iOS 8's new Separator Effect property, so I'd like to try it out here.

I know that it's called "tableview.separatorEffect," but I can't remember the exact object that I'm supposed to assign to that property.

In Xcode 6, if we jump to Definition, it'll take us right to UITableView, but it's rendered in Swift.

Even though this is actually an Objective-C header in the system framework, Xcode has dynamically translated it to the Swift interface just like the compiler would see.

And even though this is happening on the fly, we take great care to preserve all of the API comments that you need to use these libraries effectively.

Now that I'm here, I can see that separatorEffect is a UIVisualEffect.

And if I navigate onwards to that?

Ah, now I remember.

What I want is a UIVibrancyEffect, and I'm going to use a Dark blur style to go with that.

So let me add that to my code.

Now, when I go to specify the style here, I'm going to take advantage of Swift's advanced type inference, and that lets me just type ".dark".

The compiler is going to automatically infer the right enumeration type to use here because it's obvious from the context.

That saves me having to type the full enumeration name and can really save a lot of typing.

OK, that should do it for our controller, but there's one last thing we need to set up.

Remember that UserSession property that I started off by creating?

We've never initialized it anywhere.

So to fix that, let's take a very quick look at the other side of Swift development: using your Swift classes inside Objective-C.

The place that we want to initialize this object is in the sign-in controller's prepareForSegue method.

And if I go to Sign-in Controller, you'll notice this is an Objective-C file.

And of course in Objective-C before you use your classes, you need to import them.

But our class is defined in Swift, so how can we do that?

Well, when you're using Swift in a target, Xcode will automatically generate a new header for you that contains the declarations of each of your Swift classes.

All that you need to do to use those classes is import that header.

For this target it'll be called Shutterbugs-Swift, and I've added the Import Now.

You'll also notice I'm taking advantage of the at-import syntax in Objective-C to import my own CoreShutterbugs framework.

So with those in place I can fill in the rest and prepare for segue.

I get the Games View Controller and I'll set its userSession property.

What you'll notice is that even though GamesTableViewController is a...

Swift class that we just defined, we can use it in Objective-C just like any other class and we can assign this property.

And if I came back to this code later and I'd forgotten what the type was, I can even use Quick Help to get the view as Objective-C would see it, and it even includes the description of my property, even though I only ever wrote that one place in my Swift source file.

So with those in place, let's see how it looks.

I'm going to build and run, and Xcode will launch our app in the iPhone 5s simulator.

There's our great looking sign-on screen.

And if I click through to play Shutterbugs...

There you have it.

A new landing screen completed entirely in Swift, and with this great-looking vibrancy effect to boot.

[ Applause ]

We've integrated Swift support throughout Xcode 6 so that you can use the same great development features that you're already familiar with to immediately start working with our new language.

And with that, I'd like to turn things over to Jon Hess to talk to you about our brand new tools for visual interface development.


[ Applause ]

Thanks, Daniel.

I'd like to show all of you how you can take advantage of the new features of Xcode 6 to design the visual aspects of your application.

Let's head over to the demo machine.

I have a spec from my designer to implement a circular image view.

It's going to take a square images input, crop it to a circle, and optionally desaturate the color.

Now, I'm finding Xcode's new playgrounds feature to be indispensable when working on features like this.

I love being able to see the results of my code side by side as I write my code.

I have a playground set up just for this.

It starts with a sample image, and you'll have a basic function to manipulate a graphics context and return a new image.

I'm going to paste in a bit of new code.

It will take an input image, optionally desaturate it, and two sample calls to render my image.

Here in the Timeline I can see all of the results of my code.

And by pressing this button, I can bring in a persistent preview of any of the values.

That's our starting image...

and here's the two outputs.

Right now all three look the same because I haven't done anything to process the image.

I'm just taking my source image and drawing it raw to the destination.

OK, the first step is to crop to a circle.

I'm going to create a Bézier path with an oval inscribed in our square, add that to the clipping path and now we have circular images.

Things look good.

I'd also like to desaturate my image.

I'm going to simply wash over it with a white color and use a special core graphics blend mode that subtracts out the color instead of adding white on top.

And now you can see that our third call produces a desaturated image.

Things look great.

I'm ready to start using this in my application.

Going to grab a copy of this code and head over to my class that I've been working on.

Here's my prepareImage function.

It's not implemented yet.

I'm simply going to paste in my code from the playground and I'm ready to start using this in my storyboard.

I'll option-click here to open it in the Assistant.

And down in the lower left corner you'll see the square view.

This is where I'd like my circular image view to be.

In Interface Builder's Inspector I can see this is still an instance of just regular UIView.

I'll type, Interface Builder will autocomplete, and you'll see it filled in the module name as well.

My circular image view class is defined in a framework, while my storyboard is in the main application.

So the module name and the class name together complete the reference to my class.

Now, I've still got a white square here.

At this point Interface Builder is doing what it's always been capable of doing.

It's saying this UIView will be an instance of the circular image view at runtime.

In Xcode 6, we can make it an instance of the circular imageView at design time as well.

Let me show you how to do that.

We've added a couple of new source attributes that you can add to your classes.

The first is IBDesignable.

It goes right here at the top of your class, goes in the same place for Objective-C, spelled a little bit differently, but it has the exact same result.

Interface Builder is able to take our class, build our framework, instantiate it, and render it live into the canvas.

You can see it here.

Now, you may be wondering, "where is that silhouette coming from?"

Down here in my source file I've overridden a new method, prepareForInterfaceBuilder.

This is going to be invoked on our view right before it renders into the canvas, and it's a last minute chance for us to do any additional setup.

Here, I'm simply making sure that we always have an image prepared.

Now, I'd like to just configure my image directly in Interface Builder, and option in my saturation as well.

No problem.

We have another new source attribute: IBInspectable.

I can put it here in front of my property, and when I return to Interface Builder I can see in Inspector that they have two new fields that've directly derived these values.

Let's pick another image.

All right, that looks great, but when the user comes here, I'd like them to be focused on this photograph, not distracted by the bright colors in this player image.

That's where our saturation comes into play.

Let's tone this down a bit.

You can see the canvas is updating right away.

And things look good.

Let's make sure it looks good with another image.

Oh, yikes, she got squished.

I'm not sure what's going on here, but I suspect it probably has something to do with my prepareImage function that I just wrote.

I'm going to go ahead and put a breakpoint here.

And with my view selected, I can choose Debug Selected Views.

Interface Builder is going to kick off a request to render this view live in the canvas so that I can see just what's going on.

[ Applause ]

Now, I'm not sure what the problem is here, but stepping into the code...

Oh, actually I can see it right away.

Bringing up the Quick Help the Quick Look on this rectangle, I can see it really is a rectangle.

It's much wider than it is tall.

And interface Builder is taking that rectangular image, or my view is, and squishing it down into that square and we're getting this crushed image.

I think what I want instead is to produce a square image and draw the source image centered in the destination.

Interface Builder is going to automatically pick up my changes, re-render the canvas...

and I can see we're in business.

Things look great.

All right.

I'm done with this scene.

My next set of steps after this is typically to head over to my iPad storyboard and make much the same set of edits.

Let me close this out...

head over to my iPad storyboard...

and [sighs] I can see that I have a lot of work to do.

I haven't even started on this scene yet.

No problem.

Xcode 6 solves this for us as well.

We have a new feature, Universal Storyboards, that allows us to build a single storyboard to target both the iPad and the iPhone.

I'm going to head back over to my iPhone storyboard.

[ Applause ]

Thank you.

And I want to show you just how easy it is to get started with Universal Storyboards.

In the File Inspector there's a new checkbox, Use Size Classes.

I'm going to go ahead and enable them.

Size classes are a foundational new technology that form the underpinnings of the new adaptive user interfaces in iOS 8.

With size classes, I can customize which views and constraints participate in each of my layouts.

Adopting size classes also upgrades all of the segues in my storyboard to their new adaptive counterparts from iOS 8 segues that, for example, know to present a popover on the iPad and a modal transition on the iPhone.

Now, you can see Interface Builder is rendering my canvas here as this square.

This is an abstract representation that's meant to remind you that you're not editing for a specific device, you're editing for all devices.

If I want to see how things look on a specific device, I can open the Enhanced Preview Editor in Xcode 6.

Here you can see that auto layout does a great job of translating my interface to the screen of a 4-inch iPhone.

I can zoom out and I can add more screens as well.

Here's how my interface will be presented on an iPad in portrait.

And you can see as well that auto layout has translated my screen all the way up.

But I had a custom layout just for iPad.

How do I achieve that with this new feature?

Well, let's get started.

The first order of business is that this top bar should be short.

I'm going to go ahead and shorten it up and tell Interface Builder to update the constants of all my constraints from the frames in the canvas.

And, well, you can see they both got short.

Well, I'm editing both interfaces at once; it's a universal storyboard.

How do I edit just one of them?

Let me undo this change.

Down here in the bottom center of the canvas is a new control for picking which size class you're editing within.

Right now we're editing the size class for Any width at Any height.

It's the basis for all of them; all layouts inherit from this.

It's represented as this choice here in the center.

As I move away from the center things get more specific.

Down here in the bottom right corner is the Regular width, Regular height layout.

It's the largest, and it's the basis of my iPad layouts.

I'm going to choose it, and Interface Builder enlarges the canvas to remind me that I'm working in a specific size class now.

Let's go ahead and make that bar shorter again and update the constants.

And now you can see that the iPad has changed while the iPhone has remained just the way that I designed it.

Down here in the bottom left of the scene I have a completely new layout in mind.

Rather than just editing the constraint constants, I want new constraints.

No problem.

I'll select all three of these views and have Interface Builder clear the constraints in only this size class and reposition.

I'm going to have the image front and center.

Hmm, right about there?

Maybe a little lower.

And I've sized this image view arbitrarily.

I need to pin its size.

I'll start with an explicit width constraint.

And now I've said that the width should be, you'know, some constant whatever this happens to be (120 points).

I want the height to be the same, but rather than duplicate in the constant, new since last year, I can add an aspect ratio constraint saying the width and the height should be equal.

[ Applause ]

[ Background Sounds ]

[ Laughter and applause ]


[ Laughter ]

I could continue those edits, position the views underneath, and have Interface Builder add the remaining constraints to produce an iPad layout that was unique to the iPad interface, while maintaining my iPhone layout just the way that it was.

Now, I'd like to turn it over to Ken Orr to tell you what's new with debugging in Xcode 6.

[ Applause ]

All right.

Thanks, Jon.

Good morning.

So I've just taken over the photo details screen from another engineer on our Shutterbugs team, and I'd love to give you a sneak peek of that UI now.

OK, so the first thing I'm going to do is I'm going to run...

and then we will sign in to the game...

I'll navigate to this in-progress game, and I'm going to click on this particular picture.

And then here we are at the Photo Details UI.

So what we're seeing in this case is a picture that Paula took.

We see a list of all the other players in the game along with comments they've made on this particular photo and whether they like it or not.

And, you know, as I look at this UI here, I'm a little bit skeptical that all of these players are missing their picture.

So they're all showing this kind of placeholder image, and that's not something I'm expecting to see here.

So let's go ahead and let's dig into that.

Now, I'm relatively new to this code base, but I do know that our problem here, it's going to be in one of two places.

So it's either going to be on the model side of things, that maybe the image data just isn't there, or it's going to be over on the UI side of things: We have the image data, but we're not pushing it to the screen.

So we want to figure out exactly where that problem is.

So the first thing I need to do here is figure out what view controller is responsible for this view here.

And I think it is this guy, photoDetailViewController.

So what I want to do is I want to set a breakpoint in this view to appear.

And then let's try to trigger that and see if we are in the right place.

We'll navigate away, we'll come back, and there we go.

OK, we hit the breakpoint, good.

So we're probably in the right place.

But I'd like to be really sure that we're in the right place.

And I'm going to do that by using the brand-new Quick Look for UIView in Xcode.

So now I can just mouse over this view here to get the data tip, which is the view owned by this view controller, and I can click on our little Quick Look button.

And just like that I can see a rendering.

[ Applause ]

Yeah. I can see a rendering of this view or any subclass of UIView right here in Xcode while I'm stepping through my code.

And of course if you're developing a Mac app, this works great for NSView too.

All right.

So now, step one complete; we know we're in the right place.

Good. But what we care about is the model objects.

And I think our model objects are these GameComments.

Looks like we have a GameComment for every row of data here.

So these rows are backed by a GameComment.

Now, when I'm debugging, I really love to use Quick Look.

I'm a really visual guy.

Quick Look is a really great way to visualize my objects when I'm stepping through my code.

Wouldn't it be great if we could have custom Quick Look representations for our own classes?

Well, in fact, now inside of Xcode you can do just that.

And we've gone through our project and done it all throughout our classes.

Let's see if we have one for this GameComment that we're investigating.

And sure enough we do.

And what we'll see is that somebody's implemented this new debugQuickLookObject method.

So this is a method that you can implement in your own classes.

And it's a method that Xcode will call when you initiate a Quick Look from the debugger.

Now, from this method you can return anything that has a built-in Quick Look inside Xcode.

So maybe an image, or a Bézier path, or a string, or in this case an attributed string, which is going to let us have a little bit more complex visualization.

So we're going to be able to take text and an image and put those together in a nice visualization of our model object.

Now, I'm really curious.

I want to see what this actually looks like.

So let's go back to where we're paused and I'm going to mouse over our GameComments array.

I can see that there's three of them, which matches what I see on the screen; that's good.

And then I'm just going to press the Quick Look button, and, boom, just like that, I'm seeing my model object exactly the way I wanted to see it.

[ Applause ]

And of course we can arrow down through these.

Annnd... great.

So now we know we've eliminated the model as being our source of our problem here.

We can see the player image is right here, so we know it's not a model side issue.

So let's get rid of this breakpoint and let's continue onward.

OK, so the issue must be up here in the UI, and, you know, whatever view is responsible for drawing this bit of UI isn't doing its job.

Now, like I said, I'm new to this code base.

I'm not really sure what views are responsible for pushing these particular pixels to the screen.

So how are we going to deal with that?

How are we going to debug this issue?

Well, Xcode 6 introduces a brand new way to visualize your app when you're debugging.

So you can press this new Debug View Hierarchy button right here.

And Xcode will pull in a representation of your entire view hierarchy right inside of Xcode where you can see things like snapshots of all your views, their frames, and all sorts of other interesting properties that...

when you combine them together, they help to give you a really great understanding of why your app looks the way it does.

Or maybe more importantly, why it doesn't quite match your expectations.

So I can, for example, let's click on this label here and open the Inspector.

And I can see that this is a UI label.

I can see its text.

I can see its font.

I can see its font color.

All the things that I'm used to seeing when I'm designing my UI in IB, well, I can see those right now when I'm debugging it as well.

Really, really powerful.

So what we care about, though, is this little picture right here.

So let's select that guy.

And what I'm interested in seeing is what cell owns that picture, so what cell is probably doing the wiring up of the model data to the UI controls.

Now, I can use Xcode's jump bar to see the entire view hierarchy of the selected object, and so I'm going to go up here and I'm going to see that...

that view is in this gameCommentTableView cell.

So let's find that over here in the navigator, and it's this guy, OK.

Looks like a very simple class.

It has this useGameComment method which takes the model data, and then it looks like it wires it up to the UI controls.

So what I see here is I see that the player's name is pushed into this player label.

I see that the comment is pushed into the comment label.

What I don't see is I don't see us taking that player image and pushing that into anything.

So that's probably our problem here.

And it was really easy to find that using Xcode's new View Debugger.

So I'll go ahead and fix that later.

And that is probably going to take care of this missing image that we're seeing.

But, you know, as I look at the UI here, it doesn't quite match the design that I was looking at earlier with my designer.

So there's supposed to actually be a little button right around here in the bottom left of the picture that lets me like this image.

So I'm supposed to come to this UI and say, "I like Paula's picture."

But right now I can't do that.

Now the question then is where is that button?

Well, maybe the button was never added to the view hierarchy.

Maybe it's hanging out off-screen somewhere.

Maybe it's the wrong size.

Maybe its alpha component is wrong.

Maybe it's hiding behind another view.

There's all sorts of really visual kinds of problems that we could have with this control.

And they're all made really easy to track down with the new View Debugger.

So let's go back over here to Xcode and let's look at our view hierarchy again.

So what I want to do now is I just want to explore this view hierarchy.

I want to look through and see if that button is in fact here.

So the first thing I'll do is I'll just sort of twist this guy sideways.

I want to peek behind some of these other views.

[ Applause ]

Sure. And then I want to pull these views apart.

So let's do that and, hey, I see a little something peeking out right back here.

That could be our button, but there's still some stuff in the way.

So I want to peel back some of the views in the front so I can just hide things from the front backwards.

Yeah, very nice.

[ Applause ]

And sure enough our button is hanging out right here.

So let's select that.

And the next question I'm asking myself is, "Why is our button down here?"

And I know we're using auto layout in this project, so I'd like to look at the constraints that we're using here so I can show the constraints for this particular view.

And just like that, Xcode hides all the other views that aren't relevant and shows me just the constraints for this particular control.

[ Applause ]

And we can really easily see that the button is pinned to the bottom left, which is not where we want it.

We want it pinned to the bottom of the picture above.

So that's something that might be really hard to track down before but is really easy to track down now.

OK, so with Xcode 6, as we've seen, you have the ability to visualize your app when you're debugging like never before.

You can create custom Quick Look representations of your own classes that show your data exactly the way that you want to see it.

And view debugging, well, that adds an entire new dimension to the way you can explore and interact with your app at runtime.

Really, really powerful.

And I think you're going to find it really insightful as well.

And with that, I'd like to turn it over to Kate Stone to talk a little bit more about how we can enhance the performance of our app.

Thank you.

[ Applause ]

Thank you, Ken.

It looks like we have a spectacular game coming together.

We think our users are going to be really happy with a lot of these new features...

if we can just make sure that we ship a quality product.

And of course that's the last piece of the development process, is to make sure that what we're about to send out into the world is going to live up to expectations.

My team has done the right thing every step of the way.

We've tried to make sure that what we have is a product that is high-quality because, of course, we've got a set of unit tests that are running on this.

So I've got the product up and running.

I can go to my Test navigator.

And the Test navigator shows that I have several suites of unit tests here.

So I can go ahead and run those one last time, make sure that when the game comes up we put it through its paces, we're green across the board.

Looks good.

From a functional perspective, the game is doing exactly what we expect.

And that's great because I've got one last change I wanted to make to the game.

I was thinking about tinkering with some new filters to give a little bit more life to our images.

And specifically here, I've taken advantage of a Swift feature to let me build an extension to the UIImage class.

So I can take an existing class and add the ability to apply filters to it.

And so I have a variety of filters here.

The "vignette" filter is one I was thinking about toying with.

So maybe I should go ahead and build one more test, but this time a performance test to make sure it's going to live up to my expectations.

It's straightforward.

All I do is go and ask for one new file, pick the test case class you're probably already familiar with.

I'm going to go ahead and use Swift for that.

And you'll note that of course like all templates, I have that choice of Swift or Objective-C, but Xcode knows that I've been using Swift throughout the conference, so it's the default for me.

I'm going to call this "PerfTests," put it in my existing group with my tests and let Xcode create that file for me.

So now I have what should be fairly familiar.

It's got the usual setup and teardown methods, but written in Swift.

It's got a functional test.

We're not focused on any of those today, so I'll just set those aside and focus on the one new method that's been put in place: the ability to test for performance.

So I'm going to testFilterPerformance here.

And all I need to do is fill in this measureBlock call.

Now, you saw the Objective-C syntax on a slide earlier.

The Swift syntax is really clean.

It's just a call to measureBlock that passes one trailing closure that does the actual work.

And so in this case for my work, I'm going to go ahead and fill in a test image (I'll pick up one of the player images) and then go ahead and apply a vignette filter to that.

But the vignette filter's not part of my test project.

So, again, we're getting a live issue here, reminding me that I don't have access to that class directly.

So all I need to do is import the Shutterbugs module and I have everything I need to exercise the test; indexing has found the test; I'm one click away from building my project and running that test and seeing just how long this takes.

It's going to run it a number of times to figure out how long it takes and whether there's any variation.

And when it's done, it will tell me exactly how long it took to run and what kind of standard deviation I'm seeing; 4 percent in this case.

So I'm getting pretty consistent run-to-run timings on this.

Sounds good, but it's taking a little longer than I wanted it to.

So what I'd really like to do is twist this open and see that I haven't set a baseline.

I haven't set a target for my timing, and I really wanted the target.

I wanted something that was snappy to live up to our users' expectations.

So I can go and establish a baseline either based on what I have now, or I can go in and edit that and say, you know, 0.25 seconds is more what I had in mind here.

And now I'll get a reminder every time I run this test that I'm not living up to expectations.

This test is going to fail red because it wasn't fast enough.

Well, we could take time to tinker with that, but I did apply a number of different filters as extensions to UIImage here, so let me just go back and choose another one of these.

I'm going to use the noir filter.

Rebuild, retest and make sure that that's meeting expectations.

Looks good; we're all green.

So across the board we're in great shape to ship this product.

But what if I'd had a problem that I wasn't able to take care of here?

What if I had a performance issue I needed to investigate?

Well, of course Instruments is the answer to all such questions.

Instruments is a great way to get more detail about what's going on in your project.

So I'm just going to bring up a context menu for this test and choose to profile that particular filter exercise.

Behind the scenes, we're going to go ahead and build specifically for profiling and launch Instruments.

And now we get our first glimpse of the new Instruments UI.

Instruments has been overhauled dramatically this release, both to be consistent with the new OS X Yosemite, but also so that it's more familiar for people who are comfortable with Xcode already.

We start off with the Template Chooser.

Here, I can see at a glance what device I'm targeting, what I'm planning on running, and find the right template to exercise what I'm looking for.

And I'm just going to look at memory in this case.

I can look at what I've been using recently or pick from the complete list.

When I choose that template, I then go into Instruments proper, and the Instruments main window is also dramatically overhauled.

You'll see a few things at a glance.

One is if it's not immediately recording.

How many times have you chosen a template, found that it starts recording immediately, stop it, go back and tinker with the settings?

Now we give you an option to go in and change those settings before you record or to go straight to recording.

So what I'd like to do is be able to browse through and make sure that I've got the settings I want.

And you see that the settings are now all centralized in the Inspector, again, for familiarity for Xcode users.

So I can make sure that my allocations instrument is set up the way I want, my VM Tracker is set up the way I want.

And when it's all good, I go to the new, overhauled toolbar sleeker, cleaner, taking up less screen real estate than ever to start recording.

And we start recording.

And as always, Allocations is tracking everything that's going on.

We're getting a recording of all the malloc regions, all the Objective-C objects, everything we could possibly want.

We could go in and look at that in a little bit more detail.

Perhaps we'd like to filter down to a subset of this.

Well, filtering is now just a simple click and drag; no modifier keys needed.

[ Applause ]

So I can see all kinds of detail about all kinds of objects, but I can narrow in on something like my PerfTests class.

I know that was allocated.

And of course Swift objects are represented alongside everything else here.

We can see the module name as well as the class name and get details.

So that I can see for this particular class what instances were allocated and when that instance was allocated, what stack trace that instance came from.

So a ton of detail right at our fingertips.

And of course that carries over as well, but if I want to look not just at individual objects but overall statistics where are objects coming from I can see that I'm allocating about 15 megs total during the process of bringing the app up and running the tests.

So what part of that is actually in my applyNoirFilter?

Well, I'll go ahead and filter down and we can see that it's just about 430 K that we're taking.

That sounds reasonable, and indeed my stack trace here is showing me, highlighted in black, my code so that I can see at a glance where it is.

And rather than drilling down a step at a time, I can just click on my code and see where in the stack trace that's occurring and look in detail at what's going on.

So Instruments, again, the perfect way to dig in and understand more deeply what's going on.

We hope you will come to a session later this afternoon to learn more about it.

And that brings us back to Xcode.

Everything's working the way we want.

Of course my next step is to check in.

And when I check in, Xcode Server is going to start doing its work.

And we can see that we have a server set up that my team has been using.

It's the perfect way for a small group of engineers to work together.

And we've got overviews here of what's going on in my project.

So I can see recent activity, my success tree, (which is looking good, we're being successful) and my complete history off to a little bit of a rocky start initially, with one failed build, but all in all looking good.

And our unit test count is creeping up.

I can see historically what failures occurred so I might be interested in digging into some of that, but I'm really most interested in my most recent integration.

And so if I drill down to that integration and look at all the tests that are running, I could see that I'm not the only one who's been doing performance tests.

Because beside my green checkmarks here, I'm also seeing variance from baseline.

So at a glance, I can see for this last run that we're doing well against the baseline in a couple of tests that my coworkers have been adding.

Looks great.

Let's twist one of those open and see, in fact, that we're tracking baseline against individual devices.

So as we exercise it in all devices we have individual targets, perhaps for different generations of hardware.

And I think these numbers are great, but I want to make sure we don't slide from here either.

So I can go in and edit that baseline right there and accept the last run as the baseline target for all future runs.

This is spectacular because it means that for my machine I can change the baseline, push that back to the server, and that baseline will be updated on all my coworkers' machines so they're measuring against the same targets that I am.

So I think we've got a spectacular round-trip process here for you.

You're going to love it.

And to wrap things up, I'd like to turn it back over to Mike.

Thank you, Kate.

OK, that's Xcode 6.

The seed is out there available to all of you, so try it out and please let us know what you think.

This is going to be a great week.

We have a ton of sessions that will go into even more detail about all of this stuff.

Have a great show.

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US