How to make a custom bundle act as a file

2007-10-14 13:39:52 UTC

Recently, Gus Mueller had a blog post about a new plug-in for his image editor Acorn. One thing I noticed is that the plug-in is delivered as a folder:

The plug-in is a bundle, but since it shows up in Finder as a folder, users can navigate into it and poke around. It’s unlikely that anything really serious will come of it, but you never know what the average user will wreck when he or she goes exploring in the internals of something.

Fortunately, there are two solutions.

The ad-hoc solution: Turn on the bundle bit

The Mac OS X Xcode Tools include a program called SetFile that, among other things, lets you set the bundle bit on an item:

% SetFile -a B ImageIO\ Export.acplugin

Note that case matters here: If we use an uppercase B, the bit is set; if we use a lowercase b, the bit is cleared.

Those of you who came from the Classic Mac OS may remember that the bundle bit originally indicated that a file contained a ‘BNDL’ resource (which simplified scanning a folder full of applications to see which ones had some icons to display). I doubt Mac OS X uses it for that purpose anymore.

Its new purpose is for directories: Finder will check for the bundle bit, and if it finds it, it will list the directory as a package.

Packages are directories that Finder treats as files (such as .app bundles). That’s exactly what we want. Here’s how the plug-in appears after running the above command:

(Note that to get the change to show in Finder, you have to either quit the Finder—such as by logging out—or use AppleScript. I use a command-line tool I wrote that calls -[NSWorkspace noteFileSystemChanged:] with the path to the changed item.)

The permanent solution: Define all items of this type as packages

In the current version of Acorn, it’s up to Jens Ayton and other plug-in authors to set the bundle bit on their plug-ins. I think a lot of host apps have this problem.

However, a host app can take care of this for all its plug-ins. All it has to do is have a declaration of its plug-in type (in Acorn’s case, that’s .acplugin) in its Info.plist, with LSTypeIsPackage set to true in the declaration.

Then, plug-in authors don’t need to do anything, because all plug-ins of that type will be shown in the Finder as packages, simply because the declaration in the host app’s Info.plist says so. No more setting the bundle bit; in fact, that bit is then ignored.

3 Responses to “How to make a custom bundle act as a file”

  1. Mike Abdullah Says:

    I feel I should point out that really going forward you ought to also set up a UTI for this. Apple provides an existing UTI specifically for this.

  2. Peter Hosey Says:

    I agree. I may have more info up to a month from now; UTIs are still rather flaky in Tiger, so I’ll test a UTI-only solution on both OSs after Leopard comes out.

  3. Jens Ayton Says:

    Hey look, it’s me!

    I intended to poke Gus about this, because doing it in the app (with both a file type declaration and an exported UTI) is clearly the Right Thing. Then I decided to contribute an icon while I was at it. Then I got distracted…

Leave a Reply

Do not delete the second sentence.