Xcode Behaviors for fun and profit

Xcode has some great features that can easily slip by you. Recently I took the time to really take advantage of Xcode Behaviors.

Xcode Behaviors allow you to set up a user-defined sequence of events that should happen in reaction to various system events like building an app, executing the app and pausing on a breakpoint. The user-defined event sequences can adjust the look of the UI, launch new windows, tabs, hide/show navigator panes, play sounds, launch scripts, etc.

At any given point when I am using Xcode, I tend to have a certain task at hand that needs a particular set of tools given the context. I am generally either editing source code, running the app while watching the console output, debugging the app by stepping through code or editing IB/Storyboard files. Adjusting the UI by hand to put that context's particular set of tools within easy reach and maximize their use of the screen real estate is one of those deceptive death-by-a-thousand-cuts-time-sinks. If you add up all those small moments you're spending doing it, it adds up to a lot a time, and yet it seems like a small hassle during those individual moments.

Ok, so given these 'contexts' that I use Xcode in, here's what I want Xcode Behaviors to do for me:

  1. I want Xcode to start out in a layout optimized for editing code when I open a project.
  2. When I run an app I want the console output window to be large because I often find myself resizing that to make it larger to look at logging.
  3. When the debugger stops on a breakpoint I want the window layout to be effective for stepping through the code, and viewing the stack&variables.
  4. If I terminate the app manually, I want Xcode to automatically switch back to a layout optimized for editing code.
  5. If the app terminates abruptely/crashes I want to see the information on the crash in front.
  6. And the real kicker: I want something that works as consistently as possible regardless of whether I have an external monitor plugged in to my laptop or not, and yet still allows me to take advantage of that extra screen space an external monitor provides.

Because of #6, maximizing our use of tabs which can be named, opened, re-activated, and 'torn-off' to put on another screen seems our best option. This will let us do things somewhat consistently all in one xcode window or we can tear off a tab and put it on a second monitor as needed. Whatever context we're in, we'll have that named tab to remind us.

Our tab names will be: SourceEditing, Output (console), Debug, and InterfaceEditing. All should be automatically activated where possible based upon the above described needs.

Here's what the tabs will look like in [a single window] Xcode when we're done:

Customize existing Behaviors

Go to set them up in Xcode->Behaviors->Edit Behaviors...

Under Running->Generates output

Under Running->Pauses

Under Running->Completes

To make our SourceEditing and InterfaceEditing custom tab layouts let's create some custom behaviors.

Add Custom Behaviors

Custom Behaviors are user-defined sequences of events which you can bind to a hotkey in Xcode. After you create one, just click that little command icon next to the name to associate a key combination. Since Xcode does not have a way to default a behavior upon opening a project or a xib file, we set a custom behavior up to create our SourceEditing tab layout, and one for our InterfaceEditing tab layout. It's up to us to hit those hotkeys at first to initialize those tab layouts.

Under Xcode->Behaviors->Edit Behaviors...-> + Add

  1. Source Editing

  2. Interface Editing - a layout optimized for Storyboard and xib editing

  3. TerminalHere - (bonus) I often find myself needing to drop into the command-line in the project directory to either move things around, or run some git commands by hand. Just set it to run this script to launch a terminal in the project directory.

terminalhere.sh

#!/bin/bash

# Project Name:  $XcodeProject
# Project Dir:   $XcodeProjectPath
# Workspace Dir: $XcodeWorkspacePath

open -a Terminal "$(dirname $XcodeProjectPath)"  

Results

Awesome! So now we have context optimized 'modes' manifested as named tabs with particular layouts. For the most part those tabs switch automatically with a few exceptions. The tabs can all be kept together in one window on one screen or torn apart and spread across monitors. In addition to the keys we bound to switch to the SourceEditing and InterfaceEditing, you could bind keys to Switch to Output and Debug, or you could just use the standard tab switching keys Command-Shift-[ and Command-Shift-] . Overall, lots of things should be happening automatically, and you should be doing a lot less UI adjusting.

A small investment that pays dividends

The big win here is almost never having to manually resize, show, and hide various window panes within Xcode. Saving just two minutes a day adds up to an entire day of work every year.