Docsets can have bugs

If you’ve grabbed the latest AppKiDo (0.988; release notes here) and it seems to be a bit slower starting up, here’s why.

AppKiDo is a documentation browser for the Cocoa APIs. As such, it needs information about all sorts of API symbols: class names, protocol names, method names, function names, typedefs, and constants. This information is scraped from two places: Objective-C header files and special bundles called docsets.

A docset contains a bunch of HTML files (the documentation) along with a “docset index” — a SQLite database file named docSet.dsidx. One thing the docset index does is it maps each API symbol to two file paths:

  • The header file where the symbol is declared.
  • The HTML file where the symbol is documented.

The way AppKiDo is designed, it needs to know what framework every symbol belongs to. NSString and its methods belong to the Foundation framework, NSView and its methods belong to the AppKit framework, and so on. I’ve been getting this framework information by querying two tables in the docset index:

  • ZHEADER, which contains paths to header files, along with the name of the framework each header file belongs to. NSString.h belongs to the Foundation framework, NSView.h belongs to the AppKit framework, and so on.
  • ZTOKENMETAINFORMATION, which contains information about each API symbol, including a foreign key to ZHEADER.

(By the way, the docset index is actually a Core Data database. Normally one shouldn’t access Core Data’s underlying tables directly, but AppKiDo’s access is read-only so there’s no risk of corrupting the database, and SQL queries were simpler to implement than reverse-engineering the managed object model. Also, the docset index is relatively static, although that’s a topic for another discussion.)

Now here’s the thing. For some symbols, ZTOKENMETAINFORMATION is missing the foreign key to ZHEADER. This means you can’t tell purely by querying the database which header file those symbols are declared in or which framework they belong to.

As far as I can tell, this is simply a bug in the docset. I suspect if I studied up on how docsets get created (which I should really do someday) I’d have some idea why the bug is there. In any case, it’s there, and when I get a chance to write it up in more detail I’ll submit a Radar.

If you have Xcode 4, and if Apple hasn’t fixed the docset by the time you read this, you can see an example of this. In an iOS project, type “NSFetchedResultsControllerDelegate” and Option-click on it. You’ll see that the Quick Help popup is missing the “Declared In” line that appears for most other symbols.

Missing the

Compare this to the Quick Help popup for NSString:

Showing the

Because AppKiDo (or, for iOS docs, AppKiDo-for-iPhone) can’t tell what framework the affected symbols belong to, it never loads the documentation for those symbols.

My workaround was to add a second query that assumes the path to a symbol’s HTML file contains the name of its framework. This is not always true, but it’s true often enough for AppKiDo to figure out that NSFetchedResultsControllerDelegate belongs to Core Data.

Doing the second query means AppKiDo takes a bit longer to start up, which you may or may not be able to tell given how long startup is already. You probably wouldn’t notice except that the query contains a LIKE clause, which makes it relatively slow.

For more gory details, you can see the relevant commit on GitHub.

So now you know.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>