About | Buy Stuff | Industry Watch | Learning Curve | Products | Search | Twitter
Home » Learning Curve

Inside the Bundle

There's a huge difference between software on Windows and OS X: with the former (Windows) the OS vendor continually create some of the ugliest dirtiest code in history and seldom measure up to third party vendors who often do a much better job.

With the latter (OS X) it's exactly the opposite: the OS vendor's products are paragons of software engineering and stand as yardsticks against which the efforts of third party suppliers often fall short.

Anyone who makes the effort to look inside OS X application bundles sees the difference.

There's actually another difference as well: Windows programs are monolithic, looking like just so much binary gobbledegook to the naked eye, modifiable only with special tools (if then) whilst OS X programs are actually file hives which can make sense to the naked eye and can be modified with a number of typical system tools.

Following is a brief look at what's supposed to be inside OS X application bundles, what's not supposed to be in there, how all this is supposed to work, what Apple do, what ISVs do not (but should).

*.app

The cover for an application bundle is the 'app' directory. It's treated as the application itself; the actual executable is embedded further down (and in theory may be in any one of several different places). The only item in the app directory is the subdirectory 'Contents'.

*.app/Contents

This is where it all starts. On OS X you'll find at least three, perhaps (with Apple) four items.

*.app/Contents/MacOS

The directory for the OS X executable. Generally there's only one file in this directory too.

The name of the executable is generally the name of the app directory minus the '.app' extension but it need not be so - Firefox being one accessible example. The name is set in 'Info.plist' - see below.

Apple executables are always 'install' builds - that is to say they contain absolutely no debugging information. There is a trick to making these program files so lean but it's not obscure; however it's something not all ISVs care about, even if the frequency of properly stripped executables is relatively high.

You can sometimes save hundreds of kilobytes here: some ISVs are so sloppy they send you megabloat monsters that only need a couple dozen kilobytes on disk. Apple don't commit such indiscretions; ISVs do.

*.app/Contents/Resources

The repository for the resources used by the application. These generally include image files and 'NIBs' - NeXTSTEP Interface Builder files.

The resources can also be organised according to language. The directories for this generally will have the extension 'lproj'. The system will determine which language is most appropriate at runtime.

Programs do not generally specify an exact location as they cannot know which language will be used. The 'API' for finding resources goes through the NSBundle method 'pathForResource:' - the system will start at the Resources directory and work down from there.

If your application is not localised - if it has only one 'lproj' directory - the contents of the directory can be safely moved up to Resources and the 'lproj' directory removed. See the structure of Safari as an example of how this can be done.

Resources may also contain help files - and in several notorious cases can contain embedded compressed and obfuscated executables. Some of the cover applications in question demand your admin password; finding out that they at runtime unleash hidden programs can't be comforting.

*.app/Contents/Resources/*.lproj/*.nib

NIB (NeXTSTEP Interface Builder) files are actually directories containing at least three common files used to construct the visual representation of an application: classes.nib, info.nib, and objects.nib (or keyedobjects.nib).

These files are used by Interface Builder at development time (and in fact Interface Builder will not function without them) but it's only the lattermost - (keyed)objects.nib - that's used at runtime.

Thus classes.nib and info.nib are expected to be cleaned out of release packages; if you check your Apple bundles you'll see Apple have done this - but check an ISV product at random and you're very likely to find them still there.

As the files do absolutely nothing, they should be (and by Apple are) removed.

Each of these files consumes a minimum of four kilobytes on your disk, no matter the touted 'official' size. And so it adds up fast: a typical OS X setup has over three thousand (3,000) NIBs [sic]; each NIB requires otherwise an additional 8 KB of storage requirements (at least).

That's 24 MB (23.4375 MB) and that's a conservative estimate.

*.app/Contents/Resources/*.icns

Icon files are actually image directories containing images for up to four different resolutions: 16x16, 32x32, 48x48, and 128x128 pixels. The ADC Icon Composer can be handy for inspecting icon files.

OS X icon files use only four resolutions, but many legacy icons have others that are never used. As OS X does not recognise other resolutions, simply opening and saving these files with Icon Composer can make them leaner.

*.app/Contents/Resources/InfoPlist.strings

This is a special 'strings dictionary' with localised version information.

*.app/Contents/Resources/*.tiff

Image files are sometimes not compressed, and here even Apple can screw up from time to time. A popular format for image files is 'TIFF' and this format admits of a non-lossy compression which too many vendors forget to use.

TIFF files that are just too big in comparison to their display can probably be compressed.

*.app/Contents/Info.plist

This 'property list' (dictionary) file determines how the application runs. It tells the system where the application icon is located, what Cocoa class (usually NSApplication) starts the whole thing off, where the executable is located, what the version is, and so forth.

It also itemises the file extensions the application can handle.

This is a very important file: it's absolutely necessary for the application to run.

version.plist

Apple products generally have this file but not many ISV products do.

PkgInfo

This is an eight byte file the contents of which are also found in Info.plist. It's supposed to help speed up Finder, but if Finder can't find it (and as long as it's not part of a Carbon app) it will look for Info.plist and get the information there.

Many people feel it's time to stop cutting Finder slack - and if you're not running Finder, it's all irrelevant anyway. And as it takes 4 KB on disk for a mealy bit of data that's going to be found in another file anyway, you might want to remove it - and you'd get support from a lot of people in that decision.

About | ACP | Buy | Forum | Industry Watch | Learning Curve | Search | Twitter | Xnews
Copyright © Rixstep. All rights reserved.