The Cocoa-Carbon Advantage

September 7th, 2006

I’ll let you in on a little secret. Well, it shouldn’t be a secret by now, but you’ll know I’m talking about you when I say that not everybody has gotten the memo yet. Don’t be embarrassed – today is the day you come into the light (not the “just died and moving on to a happier place” light, but close to it).

Cocoa is better than Carbon. And Carbon is better than Cocoa.

If you admit to me with a straight face that you know only one and refuse to venture into the other, I will immediately form the opinion that you are a bad programmer. A programmer I’d hate to be stuck in a MacGyver episode with. You couldn’t program your way out of a box. Or an NSRect. Or a RgnHandle. You sad, pathetic sack of unadaptable protoplasm. I loathe you. Actually, I love you. You make it easier for me to shine. If you don’t embrace and use every appropriate tool at your disposal on Mac OS X, well, you deserve to write crappy software! (And yes, in case anybody is wondering, I do think this means sometimes POSIX is better than Carbon, and Python is better than Cocoa, or Ruby is Cocoa — it all depends on what you’re trying to do).

The saddest thing in all of Macdom is the sight of Cocoa and Carbon purists crying in their mailing list beers because a given task is “impossible” in the API of their preference. Often a fearless API-hopper like Jim Correia or John Stiles will pop up and cheerfully announce a one-line solution to their woes. In the opposite API than the original poster had hoped, of course.

“Thanks for the response, but I’d like to keep this as pure as possible.”

Excuse me, I thought you wanted a solution. You idiot! What they really mean to say is “I learned this framework 10 years ago and I’ll be damned if I have to learn anything new now.” Yes, believe it or not, even Cocoa has idiots from 10 years ago who refuse to admit that there is value in Carbon. But by sheer force of numbers, the Carbon idiots are the sadder of the bunch.

Wake up people! It’s 2006. It doesn’t matter what you program in, it’s how you get the job done. Arguing about whether to use Carbon or Cocoa is like arguing about whether to use a net or a hook to catch a fish. You use whatever the circumstances call for. If you don’t, you die. (This, from the vegetarian, city-dwelling Mac programmer).

Why am I rambling on in this unusually caustic mood? Just a good excuse to get this off my chest and toss some code out that I’ve been meaning to share. It’s nothing special, but it will be good to seed google with it, and it is very well suited to the genre of code that can only be accomplished by a Carbon/Cocoa double-play.

Download NSImage+RSCarbonIcon (Free MIT License).

Update: See reader comments below. This class may be pointless in the wake of knowledge that an equivalent Cocoa call does the same thing:

[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode([whateverTypeCode])]

Update 2: I confirmed my suspicion that the two approaches wouldn’t always return the same icon. Though in general the NSWorkspace call is quite reliable, consider the kColorSyncFolderIcon (‘prof’) type. Icon Services gets the expected image, while NSWorkspace apparently associates ‘prof’ with the profile file itself:

Note though, that the returned ColorSync folder is pixelated and old. It looks like Apple doesn’t use an icon on their ColorSync folder anymore. To my surprise, NSWorkspace is on the whole more reliable than GetIconRef, providing at least some icon at times when GetIconRef falls down. For instance:


Those are somewhat excusable because they’re sort of outdated. Neither icon is particularly correct, in any case. But the Icon Manager’s ultimate point of shame is that it fails while NSWorkspace succeeds in representing a sound file’s icon:

So NSWorkspace is, unless you are looking for an antique ColorSync folder icon, the preferable choice both for ease and functionality. Kind of takes the sizzle out of my example of where Cocoa should make use of Carbon, but it surprisingly demonstrates an example where Carbon clients would perhaps benefit by using NSWorkspace instead!

(Icon examples generated with the help of Paul Kim’s icon browsing test app)

This simple category on NSImage lets you easily produce an NSImage based on a Carbon “Icon Manager” type code. You’ll find a long list of these type codes in Icons.h, beneath the kSystemIconsCreator enumeration. Generic folder? No problem. Computer icon (inaccurate, but hey)? No problem. All of these NSImage at your disposal, which would otherwise “be impossible.”

It’s also useful in that it demonstrates how to properly make use of Carbon IconFamily data in a mixed-endian world. Thanks to a little documented caveat, these structures must always be treated as big-endian. So even if you figured out how to use the Carbon Icon Manager by yourself, maybe you’ll find it useful that this code sample ensures endian-safety across both PowerPC and Intel platforms.

FastScripts 2.3 Beta Release

September 3rd, 2006

I imagine FastScripts users might be feeling a little neglected, what with all the attention I’ve been giving FlexTime over the past several months. But worry not, I’ve been collecting improvements for FastScripts all along, and am nearly ready to release a 2.3 version of the app.

It’s actually pretty close to ready for shipping. But it would be nice to have a little 3rd party testing, because quite a bit has changed. Click here to download the 2.3b2 release.

The most “scary to me” parts that have changed are all infrastructure-level. At the user feature level there were a bunch of minor enhancements and these more substantial changes:

  • Grayscale Menu Icon. For years a vocal minority has copmlained about the colorful FastScripts icon being both distracting and clashing with the appearance of Apple’s icons. They finally convinced me to agree with them. I know some people will miss the old icon, so I’ve left it in as a preference choice. The grayscale icon will probably see a few minor tweaks before 2.3 ships, so let me know what you think of it.
  • Modifier-free Shortcuts. Up until now FastScripts has only supported keyboard shortcuts where some modifier key is held down (except for the special case of Function Keys). I was hesitant to add support for plain keystrokes, because it’s easy to imagine users getting themselves into trouble. But there are a few examples where overriding a bare keystroke (usually in an application-specific context) is a useful thing to do. Just beware that you won’t be able to type that keystroke into any text after you’ve set the shortcut. FastScripts will warn you when you attempt to set such a shortcut, so don’t worry too much.
  • Preference Window Overhaul. Well, maybe overhaul is too strong, but things have been shaken up. I’ve added a new “General” tab to house a new UI for controlling whether FastScripts is in your Login Items or not. That feature is long overdue. I’ve also moved some other preferences into that pane, where they seem better suited.

I’m really looking forward to hearing your impressions. Please let me know especially if you run into any problems.

Subservient Blips

September 2nd, 2006

I was pleased by the kind of “cheezy space film” mood David Van Brink’s pointless applet put me in, so I got the wild idea of creating a Mac OS X screen saver out of it.

Since I don’t do Java and am not sure how difficult it would be to use it directly in a screen saver, I decided to do a more-or-less verbatim translation to Objective-C Cocoa. This turned out not to be too much work, and the process I adopted was to paste David’s Java code into my Cocoa source file, #ifdef’d out. I then proceeded to bite of chunks of the code and translate them into equivalent Cocoa. This was motivational because I got visual feedback on my progress, even if it wasn’t too pretty at first:

Some of the bugs were surprisingly charming:




Though not as charming as the final product, with most if not all of the bugs ironed out.

Download Subservient Blips 1.0
Download Source Code (Requires Xcode)

In David’s applet you can add new blips by clicking the window, but in the screensaver that would just stop the screensaver from running. Thanks to Mark Dalrymple for pointing out that I can still grab keystrokes without waking up. Press “b” to add a new blip, and “i” to toggle the stats display.

If you like the screen saver, donate some cash and I’ll split the proceeds with David.

Update: Well, I just can’t put this thing down. I decided to play with the background color and I think this looks just amazing with a medium gray backdrop. I’ve decided to update the binary download with this setting.

If you don’t like it, well, build your own!

FlexTime 1.0.3

September 1st, 2006

I released FlexTime 1.0.3 today, the most substantial “bug fix” update yet. This version fixes a few teeny bugs, expands scripting support to include “time remaining” and “elapsed time” for activities, and extends the “shorthand input” to the duration text box. So now you can just type “30s” or “15m” for instance into the duration box for 30 seconds and 15 minutes respectively.

This release also contains the first non-English localization of FlexTime. Alexander Repty volunteered to do a complete translation to German, including the help files. Thanks, Alexander! I’m really excited about this and am now looking forward to adding support for other languages.

The support for scripted access to elapsed time for activities was motivated by this forum post, where a user was looking for a good way to present “motivational encouragement.” I’ve included in the examples folder a scripted cue that demonstrates a good use for this. Let’s take a ridciulously arbitrary example. Say I’ve scheduled my Listerine gargling into a FlexTime routine, and want to be regularly prompted with info about my progress, I just set the intervals cue to “Run Script” and choose the Encouragement Cue script file:

The script is written such that it will show text for 2 seconds each time it is run, containing the elapsed and remaining times:

Pretty nifty.