Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2011-306
$eventId
ID of event: wwdc2011
$eventContentId
ID of session without event part: 306
$eventShortId
Shortened ID of event: wwdc11
$year
Year of session: 2011
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2011] [Session 306] Maximizing ...

WWDC11 • Session 306

Maximizing Productivity in Xcode 4

Developer Tools • iOS, OS X • 47:26

Xcode 4 delivers a wealth of new features to help you be more productive than ever before. Join engineers from the Xcode team as they teach time-saving tips, and demonstrate workflows geared toward the power user, to help you work faster and more efficiently.

Speakers: Brooke Callahan, Mike Ferris, Ron Lue-Sang

Unlisted on Apple Developer site

Downloads from Apple

HD Video (1.11 GB)

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Good morning. Hi. It's great to see the room almost full this hour of the morning. My name is Mike Ferris, and I'm really glad to be here today to talk to you about how to get the most out of Xcode. This is going to be our plan for the morning.

I'm going to talk first about the Xcode workspace window, and about how you can work with Xcode with the way that it's set up right out of the box. Then we'll talk about how you can customize Xcode to suit your particular working style. And then finally, we'll spend some time delving into the source editor to show you how to get the most out of this key piece of Xcode.

Let's start with the workspace window and how Xcode works. Now we understand that there are a lot of different ways that people think about developing software, and Xcode offers flexibility to allow you to work the way that you want to work. But before we start talking about how to customize Xcode, I want to spend some time talking about how Xcode works without customization.

First, we'll review the workspace window. This is going to be familiar to a lot of you by now. I just want to make sure that we're all using the same terminology. On the left-hand side is the navigator area. This is the starting point for almost all activities that you'll perform in Xcode. You choose files or symbols from your project that you need to edit. You can search through your content to find all the stuff that you want to visit.

You can work through issues that you've introduced as you've been authoring code, and you can trace through what your application is doing as you're debugging. The majority of the window is given over to the editor area. This is where most of the interesting work goes on in Xcode.

You author your code here, design interfaces, create data models, and construct your projects and targets, all in the editor. As you can see, the editor area can host multiple editors. In this case, we have an interface builder editor and a source editor. The editor is the primary point of focus for most of your development activities in Xcode.

And finally, on the right side of the window, when you need it, is the utility area. On the top, we have the inspectors, which show you detail about whatever is selected in the editor or the navigator. And on the bottom is the library, which offers you access to various kinds of template content that's available for you to add to your project or documents.

So these three areas, the navigator, the editor, and the utilities, are all used in almost all of the work that you'll do in Xcode. All right, now that we've oriented ourselves, let's actually talk about how Xcode works. Xcode is set up to help you progress through the activities that you need to perform as a software developer, while content gets brought to you. The workspace adapts to the task at hand, and through navigation and the specific actions that you perform, Xcode knows when you're switching between the different activities of software development.

Let me show you what I mean. I might start browsing around in my project, trying to figure out an approach for a problem I'm trying to solve. Then maybe I focus in on my code to do some authoring, and Xcode's workspace adapts to this new task. I might decide to do a little refactoring, and again, the workspace adapts.

I go on to do some unit testing. And then maybe I do some debugging. And as I move through these activities, Xcode's workspace is adapting and bringing me the content that I need for each one. Now, to really show you what this is like, I'd like to do a demo now.

We're going to use an application that was developed by somebody who works on Xcode, that is an app for bird watchers, to record the birds that they've seen. And we'll be modifying this application to fetch thumbnail images of the birds from a server, so that you can see them before you've found them. And let's go to demo now.

First, let's take stock of how far I've gotten with this task already. I've kind of already gotten started. Let's just sort of look around and browse through the project a bit and see what I've done so far. Browsing through the project, again, is a common activity when you're trying to either familiarize yourself with a particular code base, or you're looking for an approach to solve a problem.

So, a lot of the time when I'm navigating, I'm going to start with the project navigator, where all the content of my project is listed. Let me load up my UITableViewCell subclass right now. And you can see that I've already added a new property to hold an outlet to the image view I'll use to display these thumbnails. Okay. Now, another common way to navigate in Xcode is to use OpenQuickly.

I can type in a bit of the file name of the thing that I want to load, and OpenQuickly will give me a list. Now, I've already added a new class to this project as well that's going to help me manage the fetching of these thumbnail images. So let me load up its header file now.

You can see that the primary API on this new class is a method that will start fetching the thumbnail image for a particular bird in the background, and then when it's finished, it's going to invoke a completion block. Now, of course, Xcode also knows that interface files and implementation files come in sets, and it's really common to want to move between them, so we offer another form of navigation that's based on that.

if I use the jump to next counterpart command, Xcode will take me from the header file to the implementation for this class. And here we can see that the way that this class works is it's going to use an NSOperation queue to manage a bunch of fetches for all the various birds that we need to find thumbnail images for.

Now, as I'm working in Xcode, Xcode is analyzing my project and the code in my project, so that it knows a lot about the APIs that I'm using, the APIs that I'm defining, all of this stuff. Making use of that information is also another really common way to want to navigate around your code.

So, for instance, I can select this method, addOperation, on the NSOperation queue, and choose jump to definition if I want to see more about that. And it's going to jump me to the framework header where NSOperationQueue is defined, and take me to the declaration of the addOperation method. And, of course, I can see all the rest of the API on NSOperationQueue.

As I'm navigating, Xcode's editor is capturing my navigation history. And so another very common way to navigate through my project is to use that history. So let me do that now to navigate back to where I was. All right, so now we've kind of gotten our bearings. We've seen how-- familiarize ourselves with how far we've gotten. Let's actually change activities to source code authoring and finish this up.

Now, to do that, the first thing I'm going to have to do is add a property to my model class to hold the thumbnail image when it comes back from being fetched. And since I have a mention of my model class right here, I'm actually going to use jump to definition again. This time, I'll do it via another gesture, which is to hold the command key down. You'll notice that as I hold the command key down and pass over things in my file, that Xcode highlights the symbols.

If I click on one of them, it executes that jump to definition command. So I can just command click on anything to jump right to where it's defined. To add this property, I'm going to need to make some changes to a couple of different files. So this turns out to be a really good use for the Assistant Editor, and I'm going to turn that on now.

You'll notice that as I turned on the Assistant, Xcode automatically brought me the header file for this class that I was looking at. Now we're going to learn more about the Assistant Editor later in the talk, but for now, the important thing to remember is that one great way to use the Assistant is to have it set up to just let Xcode try to bring you things that it thinks you're likely to need, based on whatever you've chosen to see in the primary editor. To add this property, I'm going to add a couple of instance variables.

I'm going to add a getter. And since this is a little bit tricky, I can't really use the automatically generated getter. Instead, I'm going to have to keep track of whether I've already started fetching the thumbnail for this bird. And if I haven't already started fetching it, then we'll go in and actually use that bird image fetcher class to start fetching. And then we'll go in and actually use that bird image fetcher class to start fetching.

And when the completion block fires, when the image has been fetched, we'll go ahead and save that thumbnail for this bird. And then of course, down at the end here, we need to return the thumbnail image. Now since the fetching goes on in the background, the first time I call this method on any given bird, I'm actually going to get nil returned to me, because I don't have the image yet. But then later, after the fetch is completed, it'll get assigned into the property, and from then on, I'll have access to that thumbnail image.

Now, as I was adding that, I noticed something that has been bugging me for, you know, 30 seconds now, and it's time to fix it. I have this method, initRecordWithDictionary, and I just noticed that this method starts with the word init, but it's a class method. And that's really sort of not right, according to Cocoa naming conventions. Init methods are typically instance methods that initialize an instance that's already been created.

This, it turns out, is a convenience method that actually creates an instance. And the naming pattern for that would, the more appropriate naming pattern, would be to actually call this method, to start this method with the name of the class. So I'm gonna switch activities briefly here, and fix that now while I'm thinking about it. And to do that, I'm just gonna select the symbol, and hold the correct modifier key, to get the context menu, and just choose to rename this.

So we're switching to refactoring at this point. Type in the new name. And then Xcode's going to show me what it thinks it needs to do to accomplish this renaming. So of course, it's going to change the declaration of this method and the definition. And it found the one place in my code where I'm actually calling this method, and we'll change that too. So that all looks good. We'll go ahead and accept those changes.

And OK, well now I feel much better. The method is named correctly. Let's change activities again. We're going to go on to our next implementation task. So we will start authoring code again. Now in this case, actually not so much code. We need to do some interface work.

I'm going to need to make some space in my interface to show this thumbnail image. So I'm going to get the nib file for the-- and I'm going to use open quickly again. I know that it's related to my bird cell class, that UITableViewCell subclass. And yeah, actually here it is. It's this nib file right here. And I'm going to use open quickly again.

I know that it's related to my bird cell class, that UITableViewCell subclass. And yeah, actually here it is. It's this nib file right here. That time I used OpenQuickly using the command key equivalent, which is how you would usually use it. You'll notice that as I loaded up the interface file, the Assistant has brought me some new content again.

It actually decided to show me my bird cell class, which happens to be the class used for the table view cell that's in this nib file. In fact, the assistant has discovered a couple of things that it thinks I might be interested in. You can see that from the little indicator up here.

And so if I want, I can see what else it thought I might want to see. And it turns out to be the root view controller, which is the file's owner of this nib file. And it turns out that actually the bird cell is what I really want, I mean, need in a minute. So we'll leave it there.

So to complete this, I just need to move some things around to make room to show this thumbnail. So I'm going to select a few of the elements here. We'll just move them over a bit. I'm going to move the checkmark for whether I've seen the bird or not over to this side.

And then since that's about the right size, I'll just duplicate it back over here to act as the thumbnail. Since I don't actually want this thing to come up with a checkmark in it by default, we'll open the utilities and clear out that default image as well. So it'll start off empty, and then the idea is that once the image has been fetched, we'll see it appear.

All right, let me put away the utilities. Now, this looks about the way that I want it to. I'm not a UI designer. And so now, the only thing I have left to do is to make sure that in my code, I can set the image into this image view.

And that's why I added that outlet that we saw earlier to the bird cell class, so that I can have a pointer back to this image view. So I hold the correct modifier, and I can just drag out a connection, and connect that right up to the image view, the outlet that I added. OK. I think I'm done. So I'm going to change activities again, and I'm going to start testing.

Now of course, before I started, while I was working on this earlier, of course, the first thing I did was I wrote a new test case for my unit test to make sure that this was all going to work properly. So that's what we're running now. And that's what failed.

So since the test failed, Xcode decided that the most likely thing is that I'd probably want to see Y, and so it brought me to the issue navigator. And I can click on the failure issue here and get taken to my test code exactly where the test failed.

Now it turns out that what this test is doing is it's trying to make sure that that thumbnail property on the bird record class is working the way that we want it to. Which is that the first time you call it, it comes back and it says nil, but then at some time later it's supposed to get the real thumbnail. And when the real thumbnail comes in, I expect that if I'm observing that thing, I should be told that it's changed, because now there's an image there. But I'm never getting the key value observing notification that I'm expecting.

Now, I could, you know, make you sit here and watch me debug this, but instead, let's skip to the end. It turns out that I made a mistake when I was implementing that thumbnail accessor that we added earlier. So I'm going to use, jump to definition again, but since, again, I have a call to the method right here, jump directly to that method declaration, or definition.

And the problem is that key-value observing can work automatically as long as you're doing sort of normal stuff. But here, we're doing something kind of tricky, and when that completion block fires, we're just assigning the new image directly into our instance variable in a way that key-value observing really can't know anything about. And so it doesn't really know that the value for that property has changed, and it won't be sending out the notifications. I can help it out.

It's easy to, you know, overcome this. You can simply tell key-value observing that you're doing this. And the way that you do that is before you make the change, you tell it that you're about to make a change. And after you're done, you tell it you finished making the change. That ought to take care of it, but let's make sure. We'll run our test again. And here they go.

and this time they succeeded. So I could go on and probably the next thing that I would do is I would debug my application, make sure those thumbnails are showing up in the UI where I expect them. After everything's working correctly, I would transition activities again and I would check my stuff into SCM, and then I would go on to whatever the next task is in my day. But I think you guys get the idea of how this works. So let's go back to slides, please.

So here's a way of thinking about software development, one way of thinking about software development, that matches the way Xcode works by default. Software development is a complex endeavor, and you have to perform a lot of different activities and manage a ton of different content. The focus is on moving from one activity to the next, As the content that you need is brought to you.

So this is software development as a continuous progression through activities. Xcode's workspace adapts to the task at hand, instead of providing you with a different place to go for each of these activities. And through navigation, Xcode brings the content to you, rather than sending you off to find where the content is.

All right, now the last thing that I want to talk about before we move on is navigation. So navigation is really kind of a key concept in Xcode 4. We've seen a number of different ways to navigate through your content, and we're going to see more as the talk goes on. Anytime you ask Xcode to show you a particular location in a file, that's navigation.

Now, not all movement within a file is navigation. So if you're just scrolling around or changing the selection or editing, that's not considered navigation. But any kind of intentional action on your part that says, I want you to take me to this place, that's navigation. Navigation is how you get Xcode to bring you your content, and navigation is what's captured as editor history.

The next part of this talk is going to be all about how to customize Xcode to suit your workflow. And a really important aspect of that is how you can modify what happens when you navigate. So to talk more about that, I'd like to invite Brooke Callahan up to tell you about how to customize Xcode.

Hi, I'm Brooke, and I'm here to talk to you about customizing Xcode to better meet your needs. I'm going to talk about two things. First, I'm going to show you how you can customize Xcode's behaviors to better fit your workflow. Do you find yourself hiding and showing different parts of the UI? Well, there's something we can do about that. Then I'm going to show you how you can change how navigation works. Do you prefer to do your editing in a single tab, or multiple tabs? Maybe you prefer to open each of your documents in a separate window. Modified navigation can make this a lot easier.

So what are behaviors? Behaviors are how Xcode reacts to high-level events. You can configure them in the Behaviors prep pane. If Xcode ever alerts you in some way, or reconfigures your window layout, it's probably because of one of the settings here. You can configure behaviors in several ways.

Behaviors can run alerts, like telling you when the build completes, or they can reconfigure the UI. They can also create new tabs for you, or reopen a tab that you previously closed. They can even run scripts. And if there isn't an automatic behavior for what you want to do, you can create a new one and assign it to a keyboard shortcut.

So let's take a look at this. So here you can see that I have the default settings. When a build generates new issues, Xcode will show me the issues navigator. When a build succeeds, Xcode will show me the bezel alert. So why might I want to change the alerts? Some operations in Xcode can take a long time, like building or a device restore.

If you notice this happening, and you're spending a lot of time waiting for Xcode to complete, you could change these settings to play a sound, or say the name of the behavior. That would free you up to do something else, like go back to your game of Angry Birds while you're waiting on Xcode. How many of you wish that you had a separate window for building or debugging? I see a show of hands, please.

Great. This is really easy to do with behaviors. If I build right now, Xcode shows me the issues navigator, but that's not really what I wanted. I would have preferred that Xcode leave what I was working on alone, and open a new tab or window for my build. So what I'm going to do is I'm going to change the behavior for when a build generates new issues, to show me a tab named Build.

I'm going to do the same thing for when a build fails. Now when I build, I get a tab named Build. And if I close this and rebuild, Xcode will recreate it again just the way it was. If I want a separate build window, I can just drag this out, and the next time I build, Xcode will recreate it as a new window. Because Xcode's remembering what window my tab was in the last time I had it. And the concept's the same for other operations, like debugging.

are using the search navigator. So that's great. Now I have a few different tabs that Xcode's creating for me automatically for these different operations that I'm doing. But now it's always taking me away from what I was working on. What I really wish I had was a way to get back to the work that I was doing. So this is the tab that I'm doing most of my work in. So I'm going to rename this. I'm going to call this Home. And now that I've given that a name, I can add a new behavior to take me back there.

I'm going to give this a keyboard shortcut, and have it show me the Home tab. While I'm at it, I'll have this reconfigure my tab the way I like it. I'll have it show the Project Navigator, Show me the standard editor, and hide the debugger and the utilities.

Now if I build, I can always press Command + 8 to get me back to my Home tab. So that's how you can customize behaviors. But what about modified navigation? So what is modified navigation? By default, navigation that starts in editor will happen in that same editor. Navigation that starts somewhere else will open in the primary editor. Modified navigation is how you can tell Xcode to open your document somewhere else.

The choices are Option, for a pre-configured destination, Option and Shift, to tell Xcode precisely where you want that document opened, or Double-Click for a new tab or window. So where does modified navigation work? If you're using DoubleClick, it works in the navigators. And that's just about it. But if you're using the keyboard modifiers, Option or Option + Shift, it works in that when you're clicking in the navigators, Anywhere in the jump bar, command clicking in the source editor, quick help.

stepping in the debugger with Open Quickly, and many of the commands under the Navigate menu. So let's take a look at this. So as you know, clicking the Navigator will open the file in the editor. If I hold down Option and click, it'll open in the Assistant Editor. If I click another file with Option-click, It will replace the existing document in the Assistant Editor. This is because I have the default setting to use a single Assistant Editor.

But if I prefer to open each of my documents in their own window, I would change this to use a separate window. Now if I option click, Xcode will open a new window with everything collapsed just for that document. And if I'm doing something else, and option click again, Xcode will find that window and bring that to the front.

If I'm working with this file for a little while, and I change the size of the window, scroll around a bit,

[Transcript missing]

Using separate splits, or using separate tabs. So it's all how you want to work with your files. You can also use Option + Shift to tell Xcode precisely where you want your document opened. I can use, I can tell Xcode to open my document in any of the existing editors, to create a new editor in a new split.

[Transcript missing]

My name is Ron Lu Saeng, and I will be the closing act for this, our session on maximizing productivity with Xcode. So we've seen some of the stuff we can do out of the box, some of the behaviors that Xcode gives you out of the box.

And we've seen customizing Xcode to work with the way you like to work. The focus on this last part of the talk will be on source editing. So I'll take the next 15 or 20 minutes just to focus on some of the behaviors, some of the functionality, that can really improve the quality of the time that you spend with your source code.

Before we get started, I just want to go over two terms, just to make sure you and I are on the same page. First of these two terms is standard editor. So this is how your workspace window looks when it's set to use the standard editor. Your single window just gets a single editor in it, one source file visible at a time.

So the first term is standard editor, the second term will be assistant editor. You can switch to the Assistant Editor, and your Workspace window will look like this. You'll end up with multiple smaller editors hosted by the larger assistant editor. All right, with those two terms out of the way, I just want to jump straight into demo. So we have our Sketch workspace open. Taking a look at Sketch with our navigator on the left, the editor in the middle, and the utility area over on the right.

Now, we're talking about maximizing productivity and the source editor. And for me, I really feel much more productive when I can see as much of my source code at once as possible, with as little distraction as possible. So, I tend to work with the utility area collapsed, and actually the navigator area collapsed.

[Transcript missing]

So that's one way of getting around without the navigators. The other way that I tend to get around my workspace is by using the jump bar that's up here, ever present in our editor. We can jump around to any of the files within our workspace, and once we get to a specific file, we have access, of course, to all the symbols within that file.

And over on the left side of the jump bar, we have our history. We can go back and forward in history for all of the navigation that we've done, jumping around inside of our file. And you'll notice you can see the full history just by holding down on the back button, the back or forward buttons.

And I don't know how clear it is back there, but you can see not just intra-file history, so all the places you've been within this file, but also cross-file history. There are times where you just want to see only the files that I've been in, the last location in the files that I've been in.

And you can get that quickly by just using the command key when you click and hold. And then over on the right side of the jump bar, can you guys see that clearly? We have our mini issues navigator, which lets us see all of the files in our workspace that have issues.

And then once we jump to that file, we can see the list of issues within that file. It makes it really easy to navigate all of the issues in your workspace without using up any extra space for the navigator area. So, let's see, that's two, right? Using open quickly, using the jump bar. The third option for navigating without the navigators would be another one.

The third option that we've seen is jump to definition, where you can just, whatever symbol you have selected, you can jump directly to that. Or just by using command click on any symbol. So with all of these options, I find I can dedicate as much space as possible to seeing my source code without using up the space for the navigator area.

Now there are times where you still want or need to use the navigators, but I find that the navigators come forward when I want them, when I actually want them anyway. So for instance, when I start a find in workspace operation, the find navigator comes forward for me. And once I'm done with it, I can just put it away. And likewise, I have a behavior set up so that whenever a build generates a new issue, the issues navigator comes forward for me.

And when I'm done working on that, I can just put the navigator area away. And likewise, if I'm debugging, and I hit one of my breakpoints, or I just pause the debugger for something, then the debug navigator comes forward. And otherwise, I just put the navigators away so it's not in the way.

So we can spend a lot more quality time with our source code instead of dealing with the navigators. And similarly, with the utility area, I find I don't really use the utility area unless, well, for me, unless I'm editing a nib. And in those cases, I use one of the behaviors that Brooke alluded to. I have a custom behavior for configuring my current tab just for nib editing, so that I get just the inspector area and nothing else along with the editor.

All right. So now I want to focus on actually writing code in the source editor. I'm going to use open quickly here, just to jump to a file that I know I want to make some changes in. I'll use a shortcut up here, control 6, which will pop the document item part of the jump bar, so that I can just start typing the name of the function I want to get to. I want to make some changes to this method, setColor. I want to just make sure that this method only does work when the old value and the new value are actually different. So I'll just add a little if block here.

I know that the old value is stored in a stroke color property. Now, notice that I'm getting code completion. I haven't done anything. I'm just typing, and as I go, I get code completion. And notice that I haven't typed the open square brace for this method call that I'm using. Xcode pretty much knows that's what I intend to do.

And if I add the closing square brace, it helpfully inserts the opening square brace for me. And this sort of behavior nests really nicely as well. Save a little time there. One other change I'm going to add here is manual KVO notification. So everybody's familiar with key value observing, key value coding, KVO, KVC. Yeah, you know me.

All right, so we have our manual KVO notification set up here. The indentation is a little funky. I'll just double-click the curly brace so that I can go up to the Editor menu and re-indent this block. All right, fix the indentation all at once. So we have a manual KVO notification within our setter. I know that that means I'm going to need to turn off automatic KVO notifications for this property.

Now, I know that I need to implement some method. It's like auto something. I can never actually remember what that method is. And code completion doesn't seem to know what it is either. It's okay. I'm just going to use open quickly. I know that method lives in keyvalueobserving.h. There we go. We can jump around here. Let's just type auto. There we go. Okay. So, we have the method that we need to implement.

Automatically notifies observers for key. And while I'm here, I see that there's a lot of great documentation right in the header for this class. Now, not all classes are this verbosely commented. So, a lot of times when I get to methods that I don't use often or are new to me, I like to see documentation anyway. I can use option click here just to get quick help documentation. I can also open up the inspector and use the quick help inspector to see documentation about the symbol.

Actually, what's really nice about using Quick Help in the Inspector this way is that as I mouse around, you'll notice the content in the Inspector actually updates, so that I get all the documentation for that class without ever having to jump out to the full documentation in the Organizer. Now, if I do want to go to the full documentation in the Organizer, I can get to that from either the Quick Help pop-up, pop-over, or the Inspector, or just by option double-clicking the symbol, and I go straight to the documentation in the Organizer.

Now I'm done looking at documentation. Okay, I see that actually the method I want to implement is just one with this naming pattern. Oh, you know what? I forgot to show you one other thing. Neat thing about quick help in the inspector, It doesn't only work in your source files, it also works in your nibs, and actually also works for build settings in your projects. So you can see, quick help shows you documentation for build settings that you might not have known actually... Oh, cool. Yes. Love it.

And I want to highlight this one. We didn't get here totally by accident. I do want to highlight this build setting, combining high-resolution artwork. If everybody's interested in high DPI, right? High-resolution artwork in your apps. There's actually a session immediately after ours in, I think it's Russian Hill? Mission Hill? Mission? On Aqua and high-resolution, where they're going to talk about exactly what this build setting does. All right. Enough of a side trip there.

Okay, we're implementing this method, key value observing, auto KVO turn off, all right. We know we need to implement this method, automatically notifies observers of key, Now I could just take this text, copy it, go back to our sktline.m, paste it, start typing, fill in all the details of the method, and the next time we run into having to do this, we would just do all of that again.

Which seems incredibly manual. Doesn't seem to improve our productivity at all. What I'd really like is for code completion to know about this pattern. And we can teach code completion about patterns like this by taking a look at our code snippet library here in the bottom of the utility area.

We can add a new code snippet just by dragging this text out of our editor and into the code snippet library. Down at the bottom here now, we get our own code snippet. Clicking it once, we get a little editor, where we can give it a title, a summary, a We can decide that this code snippet is valid for iOS or Mac OS. KVO happens to be useful on both.

We can define that this really only makes sense for Objective-C methods or classes. We can fill in - The implementation of the method however we like, including putting in code completion tokens. You can see another token here by, I add another token here by adding a less than, a pound, any string I want, another pound, and a greater than.

We can also specify that when code completion is trying to complete to this code snippet, that it should really only do that when we're typing into a class implementation. This wouldn't really make sense to add to a header file, for instance. And we can give our own shortcut to this code completion.

Okay, you can see the code completion tokens got bubble-ized, and hit done. You can head back to our sktline.m. Now we could drag this code snippet out of the library and into our editor at this point, or we could hide the utility area and just complete the completion that we started. And there we taught code completion about this new pattern. You can fill in all the details, and we're done. Actually, one last thing.

One last thing I want to change in this bit of code. I actually want to rename this local variable. - It's not exactly descriptive enough for me. So I could just use copy and paste, find and replace to do that. But that's again more manual work. And imagine if I had some terrible coworkers that just left it, the local variable is C. Find and replace for that wouldn't be very helpful either. But there is a way of automating this a little. So I don't know if you can tell that once I've selected this string, other uses of that symbol get highlighted, get highlighted in my editor.

This behavior is actually controlled by a preference up here in our text editing prefs. Highlight instances of selected symbol. If you've ever wondered what that does, well, now you know. Once I've selected this and Xcode shows me all of the other uses of that symbol, I can trigger an edit all in scope operation, either by the little triangle that shows up here, the little pop-down that shows up here, or by going up to the editor menu and triggering edit all in scope.

Now I can rename all uses of that in the enclosing scope. This is also a great way for you to rename IVARs in large files, for instance. Okay, so now I'm done talking about stuff that's useful in the standard editor. Actually, all this is useful in the standard editor and the assistant editor, but now I'm going to focus just on some of the neat features of the assistant editor. Now, there are multiple ways to switch to using the assistant editor. We can use the toggle up here in the toolbar, or we could just, we could use this.

Use the Navigate menu and use Open in Assistant Editor. So you can see what I have now is two independent views on the same source file. So I can manually navigate around on either side using the jump bars, open quickly, jump to definition on either side, manually managing the content of either side of these editors. I can even view documents that aren't in my workspace simply by dragging a file onto either of the jump bars.

Right, so, now that's another one of these manual things. We could instead switch the assistant to always keep the content that it shows in our subsidiary editor on the right. I always get that confused. Keep that content synced with what's shown in our primary editor on the left.

And there are multiple categories of relatedness. So by default, for source code, you can reset the Assistant Editor to switch to its default relatedness category, which is counterparts. So that for any header file you see in your primary editor, you'll automatically get its companion counterpart.m file in your subsidiary editor.

And now I said that there are multiple categories of relatedness. We have counterparts, superclasses, you can see all of your subclasses, siblings. We even put a categories category in your assistant editor's editor. Dog. And new in Xcode 4.1, we also have support for seeing the preprocessed or assembly representations of the file in your primary editor. So you can quickly get to the preprocessor and assembly results for any file in your workspace.

Oh, one of the other ones that we added. So we've seen we have preprocessor assembly as two of the three new categories that we have for the Assistant Editor. We also added the disassembly category. So that now as you're stepping through debugging, you can actually see the disassembly of the frame that you're in.

All right. And actually, that concludes our demo. I just want to recap what we've gone over so far. We've seen some of the great behavior and functionality that Xcode provides you out of the box. Kind of an idea of how Xcode tries to help you go from one activity to the next. And then we've seen how you can customize Xcode, how it behaves and how it looks, to better suit how you like to work.

And then we just went through some of the functionality in the source code editor, and how Xcode deals with navigation within editors, that can really improve the quality of the time that you spend with your source code. Now, if you have any other questions, I'd like to defer to Michael Jurvets, our DevTools evangelist. Check out the documentation. There's lots of great documentation about using Xcode up online. Check out the developer forums. We're all trying to answer questions. on the dev forums as well.

There are a bunch of related sessions, a couple that you might have missed on IB, one that's being repeated soon on storyboarding, some new features in Interface Builder. Lots of great sessions coming up, including the one that I mentioned about Russian Hill, fullscreen, and Aqua. Thank you for coming. Have a great rest of the week.