How to make a custom bundle act as a file
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.
October 14th, 2007 at 13:48:52
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.
October 14th, 2007 at 14:02:52
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.
October 15th, 2007 at 02:47:17
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…