Xcode Index

If you use Xcode often, surely you appreciate the “Code Sense Index.” This is the magic cache of symbolic info that allows tricks like command-double-clicking a variable name to jump to its declaration, or Opt-Period to complete a function name. Indexing makes life for programmers about one bajillion times easier.

Unless. Ughh!!!!! Angst, angst, angst! It’s got crap in the index. You jump to a definition, make a load of changes, build, run, and … nothing’s changed. What on earth? You thought for sure you fixed it. Finally you stumble upon the nuanced fact that the source file you’re editing isn’t located in your project directory. In fact, looking at the full path you see fragments like “.bak” or “old” or “copy” in the hierarchy. This is some bogus copy of your source base that you moved aside, but somehow Xcode caught up with it.

I’m not exactly sure how this happens, but I suppose the recommended procedure for fixing it is to click the “Rebuild Code Sense Index” button from the Project Inspector window. Heck, for all I know this might work. But it gives no feedback – no sense of whether the reindexing has started, or when it will be done. And especially no feedback about what it chose to index. Well, truth be told you can see some vague feedback about the indexing progress if you open the “Activity Monitor” window. But it’s still not completely reassuring.

I stumbled on the “xcodeindex” command-line tool, which is a real gift. With this you can not only explicitly remove the index, but you can recreate it with a variety of debugging log levels set, to see exactly what’s going on.

But Apple really made my day by including a “dump” option. For instance:

% xcodeindex -project FlexTime.xcodeproj dump > MyIndex

Yields a tab-delimited file containing all the indexed terms that Xcode knows about for my project. Nifty!

Anatomy Of An Index Dump

The index file contains thousands of rows divided into 5 tab-delimited columns detailing the symbol name, description, type, language, and file. Let’s take a look at a sample line from my FlexTime index, column by column:

adaptPlaybackToDisappearingItem:

This is the symbolic name, what I would have to double-click on to get Xcode to wake up and notice it was an indexed term.

-[RoutineDocument(Running) adaptPlaybackToDisappearingItem:]

This is the description, which seems to be what Xcode displays for instance in the popup menu when there are more than possible choices. Clearly this description will vary based on the language the symbol happens to belong to.

Instance Method

The type is probably the most interesting column, after name. In this case I’m told it’s an instance method. Other rows in the output include types like “Instance Variable,” “Function,” and “Type.”

Objective-C

Language. Well, that’s pretty obvious.

/Users/daniel/Sources/FlexTime/RoutineDocument+Running.m

Source file. Everything has a source file, including items from the System APIs, which point into the root volume or the appropriate SDK.

Great Expectations

What’s really exciting about this index dump file is that I can read it. You can read it. We can write scripts to do nifty analysis tricks with it. Xcode’s standard project indexes are kept in some (presumably) proprietary binary format that we dno’t have easy access to, but the dump file opens things up to the masses.

For instance, sometimes I’d really like to know the answer to questions like “which of my custom classes is depended upon by the fewest of its peer classes?” I’m not sure how I would figure that out (no doubt some of you will comment with another clever solution), but I’m pretty sure I can whip up a Python script to do the trick with this dump file.

Update: Well, call off the party balloons. The index dump file is cool, but not quite as cool as I was imagining. I just realized that because the “Instance Variable” types don’t indicate the type of the variable, they’re not very useful for tracking down dependencies.