Safe Haquery
Volume Number: 17
Issue Number: 2
Column Tag: Mac OS X
The Art of Safe Haquery, Categorically Speaking
By Andrew Stone
The Subtitle in Italics
The Cocoa newcomer is constantly barraged with enthusiasm and praise of the Cocoa
APIs by the early Cocoa adopters. These lofty feelings are indeed merited by the
powerful and easy to use Cocoa development environment. Although Cocoa comes in both
Java and Objective-C flavors, it's Objective-C which shines for ease of adding new
functionality to existing classes through the Objective-C language mechanism known
as Categories. This article will show you how to add and change functionality of an
existing Cocoa class, the NSSavePanel, by using a category, a subclass and a tool which
reveals all the methods in a class, classdump.
First, I must explain the spelling of haque and haquery, and how that came to be. In the
field of Computer Science, we lovingly refer to the art of clever programming as
hacking. But alas, the free press (albeit, controlled by only 5 men) has taken to using
the term "hacker" for people engaged in unlawful computer cracking. Take back our
term! By adding a slightly continental twist, voilĂ , le haque!
Before we embark on how to go below the API to accomplish tasks unaccomplishable
through normal means, I am required by the unwritten laws of the unformed guild of
responsible programmers to give my short lecture on using undocumented, unexposed
API: Don't do it - you'll regret it - your program will break in a future release. The
lecture always sounds better in the positive: if you strictly adhere to the Cocoa API,
then not only will your application continue to function in future releases, it will
actually run better as the dynamically loaded frameworks it depends on receive bug
fixes from Apple.
That said, when you've decided that the only way to obtain behavior you desire is by
using undocumented API, you need to make that code as safe as possible by assuming
that the Apple implementation will change underneath you. We'll go over the tricks and
tips when we look at the code below.
First, I wanted the ability to let the user create a new directory in a preset folder. I
wanted to reuse the NSSavePanel because it knows how to get the name of a new
directory and run as a sheet, Cocoa style. But the SavePanel is designed to allow the
user to browse the directory structure and I don't want to allow that. When the
SavePanel is in its "minimum" state with the File browser hidden, it's almost perfect
for my needs. By disabling both the "reveal the browser" button and the Favorites
popup, the panel is perfect for my needs:
Figure 1. This save panel has been tweaked to allow the user to create a new folder in
the current folder only - there is no way for the user to navigate to other folders.
Unfortunately, there is no API to make the SavePanel not display the browser, New
Folder button, Favorites popup, and other interface items which allow the user to
leave the directory explicitly set by the program. So - how the heck can one