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: wwdc2012-402
$eventId
ID of event: wwdc2012
$eventContentId
ID of session without event part: 402
$eventShortId
Shortened ID of event: wwdc12
$year
Year of session: 2012
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2012] [Session 402] Working Eff...

WWDC12 • Session 402

Working Efficiently with Xcode

Developer Tools • iOS, OS X • 53:24

Xcode delivers a wealth of 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, Chris Hanson, Kelly Keenan

Unlisted on Apple Developer site

Downloads from Apple

HD Video (774.5 MB)

Transcript

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

My name is Brooke. I'm an engineer on the Xcode team. This session is about how you can most efficiently work with Xcode. Xcode supports a wide variety of working styles. When we were designing Xcode, we knew that different engineers would want to use their tools differently. So in this session, we'd like to show you three different ways to use Xcode. First, I'll show you my single window workflow. After that, Kelly will come up and show you her workflow using tabs and behaviors. And finally, Chris will come up and show you his keyboard-centric workflow using multiple windows.

All right, so let's look at how I use a single window. Xcode tries to automatically show you just what you need at the time for whatever your current activity is. and But sometimes you'll want to show or hide different parts of the window yourself, so it's convenient to know the keyboard shortcuts. After we look at that, we'll see how you can find and open content in the editor. And then we'll look at some source editor tips and tricks.

So let's see a demo. So I've got a bug to fix, but the first thing I notice here is that I've got the utility area open, and I know I'm not going to need it because I'm just going to be doing some source editing. So I can hide that with this button up here, but there's also a keyboard shortcut I like to use, Command-Option-0.

And if I want even more space for the editor, I can hide the navigator area with Command 0. Let's bring that back for now. So in my bug, I've got a crash in the app delegate. So I'm just going to click down here, type app del, and there's my app delegate. Actually, my crash report says what method I'm crashing in. So instead, I'm going to use OpenQuickly to bring that up with Command Shift O.

Type in the name of that method, save context. Open quickly is really powerful and actually kind of forgiving. It'll find files or symbols both in my project or in the SDK. And often I don't even need to type the name of what I'm looking for correctly. So now that it's found the method I'm looking for, I'm just going to hit return.

and it's shown me the symbol that I'm looking for. So what you just saw is an example of what we call navigation. Navigation is the act of opening a document or a specific location of a document in the editor. So, on to my bug. So I see in here it looks like we're calling abort.

That's probably where we're crashing. And it must be from the save error. And I've even got a comment here telling me that I need to fix the bug here. Okay, well... I wonder if NSManager object context has another method, another save method that might deal with this error for me. So I'm going to jump to the definition.

of the Save method in the Assistant Editor by holding down Command, Option, and clicking on it. So now I can, so that's brought up, and it's managed object context in the Assistant Editor, so I can use this as a reference while I'm still looking at my primary document that I'm working on.

This is what we call modified navigation. Normally, if I were to command-click on the saved method, it would open it up in the primary editor. But in this case, by holding down Option, I jumped to Definition in the Assistant Editor instead. So, looking around in an S-managed object context, I see no, there's no other save method, so... That's not going to help me. But there's something else I could try. Maybe I could, instead of fixing the error here, I might want to, I might try pushing the error onto the callers instead.

So if I click on the Assistant Editor category pop-up here, I see one of the new categories in the latest version of Xcode is Callers. I'll select that, and I see there are three different callers, and they're actually all right here, and none of them are doing any other error handling, so that's not going to help me either. Alright, so I'm done with the Assistant Editor for now. I'm just going to put that away with Command-Return.

Alright, so clearly I'm not going to fix this bug in front of all of you. Instead, I'm just going to make this comment a to-do to make it a little bit more obvious. You can see when I did that, it made-- it promoted that comment into the function pop-up.

As you know, the function pop-up will show you all the symbols in your document, but you can also annotate the function pop-up with to-dos, pragmas like this one here, or fix-me comments like this one down here. Another feature of the Function Popup you might not know about is you can actually search in it. So if I type "application," it'll show me just the matching entries in the popup.

and I can just click to navigate to one of those. Another way I like to use the function pop-up is With the keyboard shortcut, I can use, I can just press Control 6 to bring it up, arrow up to the method I'm looking for, and hit return, and I'm there.

Actually, I remember earlier I was in this file and I saw there's a really messy list of imports at the top here, and I'd like to clean that up. And I'm going to do this using Mac OS 10's tech services. Mac OS X has powerful tech services that, and since Xcode is, Xcode, like any Cocoa application, can take advantage of these for free.

The best part about it is that you can create them yourself, and I'd like to show you how right now using Automator. So all I need to do is click on Automator to create a new document. Let me zoom out. I'm going to click on Service and then Choose. This is going to create a new tech service that takes a selection from any application and replaces the selection with its output.

I'm going to add a run shell script that's going to run a bash script for me. It's going to sort and unique the text. And I'm just going to call that sort and unique. and then I'll just quit out of Automator. Now I can, I've got my text selected in Xcode, I can control click on it to bring up the context menu, I'll select my service and as you can see it sorted in ForB.

So I can keep my imports nice and organized, and I don't really have to care too much about it. The last thing I'd like to show you is how you can get back to documents you've already found. I could manually manage the files I'm working on with Windows or Tabs. On the other hand, I've already implicitly told Xcode I'm interested in those files by opening and modifying them. Thankfully, Xcode has a few ways to automatically surface the files in my working set.

Under the Related Items pop-up, there's Recent Files, which will show me the next 10 files I've been in. There's also History, which will show me not only the files, but all the places I've been to in those files. And I can just click this or hit back a few times until I get to what I'm looking for.

But my favorite way to get back to files I've already been in is with the Project Navigator. Most of the time, I work with this open using the Source Control filter. So I'll click that now. And now the project navigator is showing me just the files that I modified.

I like to start off any task this way. As I make changes, files are added to the list. This view helps keep me focused on just the bug I'm working on. And the best part is, now I've got one-click access to all the files that I'm most likely to navigate to next. So you just saw that you can easily organize Xcode's user interface with keyboard shortcuts.

You saw a few ways to find and navigate to your documents, and some source editor tips and tricks, and how you can get back to documents you've already been in through some automatic working set features in Xcode. Now I'd like to invite up Kelly Keenan to show you her workflow using tabs and behaviors. Thanks, Brooke. Hi, everyone. I'm Kelly Keenan.

And I would love to talk to you about three things today. The first is I'd like to talk about how I use task-based tabs in my workflow in my daily use. The second is how I use behaviors in conjunction with those tabs. And the third are some more editing tips and tricks that you all can use while working with Xcode. And the best way to show all these things, of course, is with a demo.

My favorite way to work, actually, is unlike a lot of my coworkers, is to just use a 13-inch MacBook Air on my couch. And so I use a one-window feature a lot. And I used to work this way, where I used a lot of dynamic user interface changes, where I moved things in and out all the time. But I found that I really need something a little more static, a little more concrete. And so I started using tabs.

So this is the way I usually work, which is I have a bunch of different tabs here. Now you can create new tabs by holding down Command-T. That'll give you a new tab, and you'll see one popped up on the end, and it's exactly like the tab I just came from. If I ever want to close a tab, I use Command-W. And to navigate between tabs, I can use Command-Shift-Square Bracket, otherwise known as Command-Curly Brace. And I can use that to easily move between all of my tabs.

Now, the first tab that I have here is one that I use a lot to work specifically with either storyboards or with my core data model. And you'll see I close most everything. I keep the utility window open so that I have the inspector in the library so I can edit my objects and drag objects out of the library.

And I use the tips and tricks that Brooke showed you about opening and closing assistants and things like that to be able to look at code when I need it, but make it go away whenever I don't want it there. Now, one of the things that I like about tabs is that I can keep each of the tasks that I do in a separate area, in a separate tab.

Only, when I go and look at the name of these tabs... You see that they're named after the file that's open in the primary editor. Now what I would really like to see here is what task I'm doing in this tab. And so I can edit my tab name by just double-clicking on it. And now I can call this a design tab. So now, whenever I change files in here, that tab name is going to stay the same, and I know it's where I go to edit my storyboards and my core data models. Now let's go to the next tab.

Again, we can command-shift, square bracket to get over. And this is where I do most of my source code editing. I usually start off with one tab like this, and I'll sometimes open two or three of them, depending on how many different files I'm looking at. Now I hide the navigators in the utility window, and I keep open the assistant editor, because a lot of times I want to look at some other code that's similar to what I'm working on, or related in some way. And so I use that jump bar a lot to move in between there. Now, since this is where I edit my code, I'm going to rename this tab "Edit." And then let's go to the next tab.

So this tab I use just for finding, and I'm going to call it find right away. And so, for example, I use a lot of multi-file finds, and I see I have an author property here, and I'm just going to search for that. And now I can easily look between all of the different files that that selection is in.

and I are all the time knowing that if I go back to my edit and my design tabs, they're exactly where I left them. But I could use this tab to just search everywhere throughout the project and not have to worry that I've lost my place in what I'm doing. So while we're in the find tab, I have a couple tips and tricks I want to show you about finding. Now, I think you're probably all familiar with using Command F, and that will open a find bar at the top to do an in-file find.

Now, the trick I'd like to show you is that you can make a selection in your editor, and now if you hit Command-E, it actually takes that selection and puts it into the find pasteboard without opening the find bar. And now I can Command-G through my file and just search for that selection. I do this all the time for finding, because I don't want to open the find bar. It's great, but if all I'm doing is looking for one little thing, I can do that quickly.

Command-E, Command-G. So now I want to be able to change these three instances of display. So I want to make a selection here, and one of the things I can do is I can double-click on this curly brace, and it will select that whole block of code, which is kind of handy. Now, you might have seen earlier, if I do Command-F to open the find bar, I can change it to replace. Now if we scroll in over here, I want to change the word display with the word show.

Now my options are find all, replace, well, replace all, replace and replace and find. But we have a new one, which is if I hold down the option key, it'll change to in selection. I'm going to scroll back out before I do that, and when I do hold down option, in selection, and now it changes show in the three instances that were inside of that selection. If I command G, it still exists in the rest of the file, just not in that selection anymore.

So those are the tips and tricks I want to show you about finding. And so let's look at our next tab. Now in this last tab, this is the tab that I use to review what I've been working on. And to do that, I use what Brooke showed, where I keep the file navigator open and I...oops.

And I keep the source control filter turned on so that all I see are the files that I personally have edited recently. And I also use the comparison editor. By doing this, I can quickly, if somebody comes into my office and wants to do a code review, I just switch to this tab. I'm like, "Oh yeah, here's all the stuff I've changed already." So let's name this one our review tab.

Now, there's two other tabs that I keep normally open, and I'd like to show you how to use behaviors to dynamically open these tabs. So, behaviors lives in Xcode's preferences, and we can open that using Command-comma. We can click on Behaviors, and the idea of behaviors is that on the left, your left, we have triggers, and on the right is where you can set up actions or UI changes that will happen when those triggers happen. So in this case, I want to look at Build Generates New Issues.

And when a build generates a new issue, like a warning or an error, I want it to open a new tab. Well, I want it to show a tab named, and in this case, I want to show it a tab named Build. Now what's going to happen is, if that tab already exists, like it does in my project at the moment, whenever a new issue or warning happens when building, it's going to open that existing tab. Now if that tab doesn't exist already, it will create a new tab and open that up when a build issue appears. So you could also set a bunch of these other options, and Chris is going to show you how to do that in a little bit.

But the other trigger I want to change is when the run pauses, I want to show a tab named Debug. And this way, if I hit something like a breakpoint, it's going to show me a debug window. So let's try that. Now I can Command-W to close this window.

And we're going to use Command-R to build and run. And earlier, before the demo, I put an error in here. So that you'll notice that we opened up the Build tab. It shows the Issue Navigator. I can click on that issue. And right down here, it says, oh, I needed to put an underscore in there. So now I can build and run again.

And this time, it hits the breakpoint I put in earlier and opens up the debug tab so that I'm all ready to do my debugging. And the great thing about using task-based tabs is at any point I can go back to the other tabs and they're exactly the way I left them. So let's then go back to the edit tab and I have some editing tips and tricks I want to show you.

We can stop that from running first. Okay, so back in the editor. Now, Brooke showed you Open Quickly for navigating, and I want to show you an additional thing that you can use with Open Quickly. So you type Command-Shift-O to open quickly. I can type in my root, look for root view controller. Now, if I press Return right now, it's going to open in the primary editor. And if I press Option-Navigation, so if I Option-Return, it's going to open the assistant editor.

And there's another option that you might not know about yet, which is if I hold down Option-Shift-Return, and I are going to show you how to use the navigation chooser. This allows me to use either the mouse or keyboard to determine where I want this file to open. I can use the arrow keys to just arrow around and I can open into a new tab, I can open into the existing editors or I can add a new assistant editor. If I hit return here, it opens a new assistant editor for me.

So that's what I wanted to show you about navigation. Now there's two other main topics I want to talk about in editing. And to do those, I'm going to close the Assistant Editor, or in this case, just open the Primary Editor using Command-Return. Now I want to talk about code completion and code snippets.

And it's hard to really talk about them separately, so we're going to talk about them at the same time. Now this is a core data project, and I see that I have a title and an author property here. And I'd like to check both of them to make sure that they aren't empty. And so I'd like to validate them.

And to do that, I'm going to go look to see if there's a code snippet that will help me to do this. If you look through some of the menus, you'll find some very specific commands that you can use. And in this case, there's commands that open very specific libraries, even. So I can use Control Option Command 2, and that actually opens the code snippet library specifically.

Now you'll see we have a bunch of code snippets available to us. And I can start typing "valid" and I see that I have a Core Data Property Validation method that I can use. Now I'm going to make a little space for it. And all I have to do is drag it out of the code snippet library and drop it in here.

Now, as part of this code snippet, there's two placeholders, and I can move between the placeholders using Tab or Shift Tab. When I'm ready to accept the placeholder, I just start typing. And in this case, I need a capitalized property name. And the first one I want to validate is title. So I'm going to type in "title." and then tab to the validation code.

Now I need to write some code. This is going to be fun because I need to show you code completion and if any of you have done big demos before, this is where things go wrong. So the next thing I want to do is I want to know if value ref is equal to nil, then I'm going to have some problems. I need to write out an error.

Well, actually, if it's not nil, I don't remember. Okay, let's just go along with it. I know what I'm supposed to write. Let's just write the correct thing. Okay, so if I start typing if, what you see is the code completion window shows up. Now, there's a couple things you can do here. One is I could just press Return and accept it, but that wouldn't make much for a demo. So, what I want to tell you about is if you want it to go away, you can type Escape.

If you want it to reappear, you can use control space. And I could accept it, or in this case, sometimes you're just typing along and you just want to ignore it. We'll go right ahead. Just keep typing. Nobody's going to stop you. Now what I want to show you is that code completion has given me a suggestion to remind me that I need to put an ending parentheses here. We're going to accept it a little bit later, but I want to show you that if you do remove what you have, it's going to go away.

If you type again, it's going to come back. And I can now just keep typing and you'll see code completion offers the parameter that I have. So to accept this, all I have to do is hit tab. And I can continue on my merry way and try not to type crazy stuff.

So now I want to check to see if it's an empty string. So I'm going to type in value ref, tab again to accept that, and is, let's type the right thing today, equal, okay. So the next thing I want to show you is... Partial completions. So, let's move the cursor out of the way a little.

You'll see that there's a little gray underline. And so what that shows is if I type tab right now, it's just going to partially complete to the end of that word. So it's just going to partially complete equal. So I can hit tab, and then I can keep typing.

So if I want to, tab again, and then string, and then I can tab to finally finish what I was doing. So, now I can type in that I want to check for the empty string. And here I can tab to accept the square bracket that was there. And I could tab to accept this ending parenthesis as well. However, I want to show you another trick, which is usually if you're ending an expression for an if statement, the next thing you're going to type after this is an open curly brace.

So we have a little trick, and I can just type it right now. So if I just type the open curly brace, surprise, it gives me the ending parenthesis and the open curly brace in the right spot. Yeah, you can clap for that, that's good. It's exciting, I like it.

So now if I hit return, I can continue on. And so now what I need to do is I need to check to see, well, I want an error in this case because value ref was nil and value ref or value ref was, you know, an empty string. So now I got to check to see if there's an error before I can put an error in there.

So I got to make sure it's not equal to null. So I can start typing if. In this case, I'm just going to return. And I want to know if out error is not equal to null. Or do I want it is equal to null? Who knows? It's yes or no. Somebody tell me, quick.

Keep going? Okay, good. Just checking. I should have brought my notes. So this next part, well, yeah, this next part, part of what I want you to watch as we're finishing this up is the number of characters, like the characters I'm actually typing versus how much code gets written.

Because, you know, I want to go through this next part fairly quickly. I am going to show you a couple other things, but let's just start typing. We're going to make a dictionary, and one of the things I want you to notice here is that we've added Quick Help into the code completion.

So this will help you pick between the suggestions that you have. And so I'm going to create a dictionary, going to call it User Info. I have to type that whole thing because, sadly, Xcode doesn't know what I want to call my variable names. And now, oh, I'm going to use one of these cool new literals. Yeah, that's awesome. Like the dictionary literal thing. Now I've got to remember this hard thing. NSLocalize, localize, I can, oh, I don't want, description key, oh, that looks good. Awesome. And I'm going to call it, title is empty. Okay, I need, oh, I need this. Okay.

Yeah, semicolon. And I want to put this into OutError. Tab equals NSError. That looks good. Error with domain. Oh, sweet. NSCoco. Yeah, that one. NSManagedObject something valid. Validation error. Sweet. I am so grateful for this right now. User info. And the last thing I need to do is set validation result equal to no.

Okay, the only way I could possibly get through this today is thanks to code completion and my code snippets, because there's no way I was going to remember NSLocalize dictionary key right in front of you. Description key, yeah, see I can even say it right. So that's one of the powerful things about code completion is really being able to get the right, the things you're looking for quickly and easily and accurately.

I also want to validate author. And so I'm going to have you watch me do this all again. Just kidding. What I really want to do is I could just copy and paste this, but it's probably likely I'm going to use the same bit of code over and over again in other projects. So what I'm going to do now is drag this code, if I had more space here, into my code snippet library. And now at the bottom, I have this little code snippet.

And if we double-click on it, Let's scroll in here a little bit so you guys can see this. So this is the code that's going to be entered into my project if I drag it in. And I want one of those cool placeholders, so I'm going to have to edit this. Edit. Okay. And I want title to be a placeholder like we saw in those other things. So in this case, let's scroll this out a little bit. I'm going to use angle brackets and hash marks.

So, angle brackets and hash marks delineate my placeholder. And here I'm going to remind myself I need a property name. So I can put that in there. I'm going to copy this and put it down here in my description key, because I want that same name there. And now back at the top, in my code snippet library, I don't want to just leave it as my code snippet, so I'm going to call it Property Validation. The key thing here is using the completion shortcut. In this case, I'm just going to call it PropVal. Awesome.

So, hit done. Ooh, go the other way. Sorry if I'm making you all seasick. Hit return. Now, here I can just start typing prop val. Code completion knows about my new code snippet already. I hit return. It shows up here. I have a property name. I type in author. I hit tab. I hit author again. Author. And I'm done. So, that's how you can make your own code snippet.

Thank you for dealing with my typing on stage. These are the things that we just went over in the last few minutes. I showed you how to use task-based tabs as part of your workflow and set up a tab-based environment. I showed you how to use behaviors so that you could dynamically open those tabs when you need them. And I showed you some new editing tips and tricks.

Hopefully they were new to you. One is using the navigation chooser to be able to decide where to open your files. Another is code completion and how to type your code fast and accurately using it. And the third was snippets and how to make your own code snippets. So I'd like to invite Chris Hanson up here to talk to you about multiple window workflows and keyboard shortcuts.

So I'm Chris Hanson. I'm also an Xcode engineer. And I really like to use a multi-window workflow. That lets me bring up auxiliary content around what I'm working on and keep it sort of organized spatially, while keeping my primary and my assistant editor focused on the task on which I'm working.

I'd also like to show you how you can really drive Xcode from the keyboard. That lets you get around your code really fast and work with Xcode sort of naturally, where you just think about what you want to do with your code and your fingers know how to do it. And how almost everything in Xcode from the keyboard is configurable, so you can really optimize it for what you would like to do.

So I'm just going to go straight into demo, and I'm just going to bring up my checkout of the project that we've all been working on. Now the first thing I'd like to show you is how to actually get to new windows in Xcode. It's pretty simple. You just double-click on a file and Xcode will open it in a new editor-style window.

And this is great both for just general editing, especially if, say, you resize your main window a little bit, resize that down, and I can arrange some of my other windows around here. I can open up, say, a data model and put it in a nice big window, independent of the main window that I'm working in.

And that really lets me sort of organize my work spatially, because now I know I just need to go over here to get to my root view controller. Over here, I have my app delegate. Down here, I have my data model. And I can get around these windows both using the mouse and using the keyboard. Because on OS X, we have a standard keyboard shortcut for going between windows, just like we have one for going between applications. So to go between applications, you would use Command-Tab.

and Command-Shift-Tab. Well, to go between windows, you use Command and the Backquote key right above the Tab key. So it's really easy to remember and it really leverages how your fingers kind of want to work already as you're working with OS X. So I'm going to hold down the Command key and press Backquote and that rotates me forwards through my list of windows. And it does it in spatial order. Now, if I add in the shift key, I go the opposite direction.

But sometimes I know exactly what window I want to be in. I know, for example, if I'm editing some code over here in my app delegate, okay, now I want to make a change in my root view controller, and I know it's just over there. I don't necessarily want to use the mouse to do that. So I can bring up the navigation chooser just by pressing Command J.

And then, while holding down the command key, I can use the arrow keys to, instead of targeting a new area in this window, switch which window I'm targeting in this navigation chooser. So I'm going to pick the window that contains my root view controller, hit return, and my insertion point is now over here. And to get back, I can just bring up the navigation chooser, switch back, and there I am.

And that makes it really easy to not only use multiple windows, but also get between them as you're editing, so you can make changes in several of them sort of at the same time. Now, one other thing that we've added in the latest version of Xcode is the ability for behaviors to not just target new tabs, but also target new windows. So to do that, well, let's say I want to bring up a console window anytime I run my application.

What I'm going to do is go straight to my Behaviors menu and choose Edit Behaviors. And that's a nice shortcut to the Behaviors tab of Xcode's preferences. And I'm going to edit the Run Starts trigger, so that any time Xcode starts running something, It's going to show a tab named Console, but it's not going to show that tab in the active window.

Instead, it's going to show it in a separate window. I'm going to make sure that it's hiding the Navigator, that it's showing the Debugger with just the Console view, and that it's hiding some other areas of the window that I don't think I need in that Console window, in particular, the big Editor area.

So now that I've set this up, I can just press Command-R to run. Xcode builds my application, starts running it in the simulator, and you can see it brought up this console window, and I got some log output in it from my application. I love this because I like to work on multiple monitors at once, and I just like to throw my console window over on a different one. In fact, for right now, I'm just going to resize it down here and keep it sort of down below. Now, as we've been talking about behaviors, there are lots of triggers that are built into Xcode. But you can also create custom behaviors.

If I just edit behaviors here, one thing I like to do is keep my editing UI when I'm working on source code organized kind of like Kelly showed. But like I said, I like to use multiple windows rather than tabs. So what I'd like to do is have a simple way to just arrange Xcode's UI to be exactly how I like it while I'm editing. What I'm going to do is press this plus button at the bottom of the list of behaviors, and that lets me create a new one. I'm just going to call this behavior source editing.

And this command symbol here, this cloverleaf, means that I can assign it a key shortcut. So I'm going to assign it F13 and click away to accept it. And that means any time I want to edit sources the way that I like to, I just have to press F13 and whatever I'm looking at in Xcode will reconfigure itself to be the way that I want it.

And to do that, I'm going to just hide the project navigator. I'm going to make it hide any debugger, hide any utilities. I'm going to leave the toolbar alone in whatever window I'm looking at. And I'm going to make sure that the editor is showing as an assistant editor.

So now, if I'm working on Core Data Books App Delegate here, and I want it to be arranged like I like an editor arranged, I just have to press F13 and Xcode's UI rearranges itself. For the next part of the demo though, I'm actually going to bring back the Navigator with Command-0, and I'm going to switch back to just the primary editor with Command-Return.

And most of what you're going to do in Xcode is editing. You're going to be editing your project, you're going to be editing your data models, you're going to be editing your user interfaces, and most of all, you're going to be editing source code. So I've got a few more editing tips and tricks for you.

And to start with, as an OS X application, we support all of the standard OS X text editing gestures. So for example, you can arrow around in your code, you can add in the modifier keys like command and option to change how far you're jumping by using the arrow keys.

You can throw in the shift key to extend your selection, all the usual stuff. But in addition to the max standard editing gestures, OS X supports a bunch of Emacs keyboard shortcuts as well. So if I want to go to the next line, I can press control N, you know, because I'm kind of an Emacs user from way back.

My fingers are just used to that. I want to go to the next line, I try to hit control N, and Xcode doesn't beep at me, it just says, oh, you're using Emacs keys, I'm going to go to the next line. I can use control B and control F to go backwards and forwards in my text.

I can even use keys like control E and control A to go to the end and the beginning of the line. All those kinds of Emacs gestures. But we don't just support cursor navigation. We actually have support for advanced Emacs concepts like the kill ring. And this isn't something that Xcode adds specifically. It's actually global throughout OS X because it's part of Cocoa.

And if you're interested in a little bit more of how this Cocoa text editing works, the Cocoa Event Handling Guide has some detailed information on that from an API level. Now, as you're editing, you're probably not going to be thinking in terms of, "I want to change this sequence of characters to that sequence of characters." Instead, you're probably going to be thinking at a more semantic level, "I want to change this identifier to that." So let's say in my root view controller here, down at the bottom, oops, I switched in the wrong window.

Okay. Down at the bottom of root view controller, I have a method called add view controller did finish with save. And the second parameter to that method is just called save. Well, I think did save might be a better name for it. So of course, I could use find and replace to replace all of those.

But we actually have a feature called edit all in scope. So if I put my insertion point in that identifier, Xcode gives us a nice little underline under that identifier and under any other matching identifiers that are in the same scope. That indicates that I can edit that identifier in scope and Xcode will automatically propagate my changes to all the other instances. Love it. So to do that, I could choose it from a menu, but I'm just going to press Command Control E. Whoops, I pressed Command Control W instead.

I'll go back to that. There we are. And Xcode remembered my place in my file. I'll zoom in again. And this time I will press Command-Control-E. And now you can see that underline became a box around the save identifier. And we have a grayed out box behind the other instance of that identifier.

So I'm just going to start typing did save, and I'm going to control D and type S to make it all nice and properly capitalized. And you can see that not only did the one that I'm actively editing change, but so did the other instance of this identifier in this method. And it doesn't really matter how many instances of it we have. It's not just limited to one. It could be five, it could be ten. It'll do all of the identifiers.

Now, as I'm working, I probably also want to reference other code and documentation. Brooke was working on a bug earlier where he was seeing a crash in the app delegate, and he's asked me to take a look at it. Maybe I might have an idea of what to do. So he said it was in the SaveChanges method. I'm just going to use OpenQuickly to get there. It's actually called SaveContext. And I'm just going to use my counterparts.

Oh, actually, this is up at the top, so I'm going to use my pop-up to get down to the definition of this method and take a look at it. Well, the issue is basically to do with NSManagedObjectContext returning an error from saving. So what I'm going to do is take a look at some documentation on the save method.

Now, I could do this by holding down the Option key, my cursor changes to a question mark, and I can just click on that identifier and I get quick help. And new in the latest versions of Xcode, quick help doesn't just show an abstract, it also shows the parameters and return values of a lot of framework methods.

And I can click out of that to put it away, but I'm often just editing with my keyboard. I don't necessarily want to have to use the mouse just to bring up some quick documentation. So what I can do is press Command-Control-Question Mark, or Shift-Slash as you type a question mark, and that brings up the quick help pop-up. It appears to have brought it up in the wrong place, but I think it was matching my cursor position, so I'll just try that again.

Command-Control-Shift-Slash. Yeah. So when I bring this up with the keyboard, I can just press Escape to dismiss it, and my insertion point is back where I left it. So I don't actually have to take my hands off the keyboard just to see some quick documentation about what I'm working with. And that includes things around my code.

Now, one other thing I might want to do is jump to a definition of another method. Brooke showed you how you can just command click. to replace your primary editor with the contents of what you've jumped to, and how you can command option click to open it in a new assistant.

Well, I like to use multiple windows, so what I'd really like to do is have that kind of gesture open what I'm jumping to in a new window. I'm going to put the assistant editor away, and if I say I want to see the definition of NSError, I can command double-click it, and it just opens in a new window for me. It's that double-click gesture again.

But again, sometimes I don't want to take my hands off the keyboard to do that sort of thing. So, well, to bring it up in the Assistant Editor, I would just type Command-Control-Option-J, and that goes into the Assistant Editor. But my Assistant Editor is often looking at something that's already related to what I'm working on. So I'd really like to bring this up in a separate window.

And the way I can do that is to change one of Xcode's preferences under the General pane for how navigation behaves. Brooke talked about modified navigation, and this lets you tweak it to match your workflow. Here, I'm going to say optional navigation, which is the navigation that happens when I press the Option key. Instead of using an Assistant Editor, should use a separate window.

Now, if I put this Assistant Editor away with Command-Return, And I press Command-Control-Option-J to jump to definition. I get the definition of NSError in a separate window. I can use my page up and page down keys to scroll through it, and then I can press Command-W to put that window away. And my primary editor is exactly as I left it.

Now these are all just Xcode's default key bindings. Let's say you really would rather use F5 for running your application. Almost all of the commands in Xcode are customizable in terms of how you invoke them from the keyboard. And you do that in Xcode's key bindings preferences. And you see, we show all sorts of commands here.

You can see the complete list of all of our commands, just our menu commands, or our text commands that you invoke from the keyboard. You can also see which commands have already been customized, and any commands that have conflicts either within Xcode or with system-level key bindings. I'm just going to switch back to all, and I'm going to look for some running-related command that I can bind to F5. I'm just going to type in run here. And I see that I have run in the product menu.

Well, to change that key binding, I just double-click it, and I'll press my new key, F5, and I'll click out to accept that binding. Now, I have some text down at the bottom here that says that it's already bound to something and my new binding won't take effect until the conflict is resolved. And they also have this little icon here indicating that there's a conflict with my key bindings. I can see that in the conflict button.

And looking through here, there are just these two major conflicts. I need to resolve that before F5 will do anything. And since I'm not doing much OpenGL work right now, I'm just going to highlight the OpenGL command that's bound to F5 and press delete to unbind it. And that leaves F5 bound to my run command. And now, if I close the prefs and press F5, Xcode asks me if I want to stop the app that's already running. It builds my app, it runs it, my console window comes up exactly where I left it, and everything is good.

Now let's say I want to bind a text editing command like "end." I don't want "end" to scroll to the end of the file, which is the default for the Mac. I actually want it to move my insertion point to the end of the current line, because that's just how I prefer to work.

Once again, I can just bring up Xcode's key bindings preferences using Command, Command, Comma to bring up the Prefs window. And I'll start typing End. You can see we have a lot of different commands whose name includes the text End. So if I just start scrolling down here, at the bottom, I have Scroll to End of Document. And it's bound to a key with a symbol here. Now if I zoom in on that, it's a little downward rightward facing arrow. And it's highlighted.

It turns out this is the symbol for the End key that will appear in menus and such. And it's highlighted because Xcode didn't just search for commands that contain the term End in their text. It also searched on the name of the key. So if I want to see all of the commands that involve arrow keys, I can actually type in Arrow. And I can see all of the commands that involve left, right, up, or down arrow keys. If I want to see commands that involve the Control key, I can type Control.

And that'll show me all commands that use Control in their binding, which include a lot of those Emacs commands that I like to use. I can even stack these, for example, by adding in Command as well. And that shows me all of the commands that involve both the Control key and the Command key. Xcode knows to And these terms together. And that's it.

Thank you. Now, Xcode isn't the only thing that lets you customize your keyboard shortcuts. OS X itself also lets you do that using the keyboard pane in the system preferences. The first thing I like to do, because I do use a lot of those Emacs commands, as you can see if you've been watching what I type, is fix my control key. I prefer the control key to be where caps lock is on most keyboards these days. It just makes for a lot less distance to reach when invoking those commands. I can do that just in the modifier keys section.

And now I can make my caps lock key a control key and those Emacs commands are a lot more comfortable. I can also assign keyboard shortcuts and change them for a lot of the OS X defaults. And I can even assign keyboard shortcuts to things like services that I create.

So Brooke added this sort and unique service. If I wanted, I could actually bind it to a keyboard shortcut and then anywhere in OS X that I have text selected, I could press the keyboard equivalent for that service and have that text sorted and unique. And like I said, the Koko event handling guide talks a lot about how the key binding mechanism in OS X works, at both the programmatic level and from a user level.

Now I'm going to take us back to our slides. And well, what did we talk about? I showed you how you can use multiple windows to really organize your work spatially. So you can have some main text that you're working with, some main tasks, and then the auxiliary content that you're using with that task around what you're working with.

And I showed you how you can really drive Xcode, both for text editing and for getting around from the keyboard. That lets you efficiently edit your text and build up muscle memory or leverage the muscle memory that you already have by modifying Xcode's key bindings to what you prefer.

Now we have some related sessions on Xcode this week, such as working with schemes and projects in Xcode tomorrow, source control management in Xcode on Thursday in Nob Hill, and debugging in Xcode also on Thursday. If you'd like any more information about Xcode, you can always contact our developer tools evangelist, Michael Jurowicz. You can check out our Xcode 4 user guide in the documentation, and if you'd like to take a look at the sample code that we've been demoing with, it's called Core Data Books, and it's just available on Apple's sample code site. Thank you very much. Thank you.