< Previous PageNext Page > Hide TOC

Anatomy of a Modern Bundle

Modern bundles reflect a structure that is different from the bundle organization that came before Mac OS X. This bundle type is used by applications and plug-ins and is the most common type of bundle.

Bundles have evolved significantly over the years but the overall goal has been the same. The bundle organization makes it easier for the application to find its resources while making it harder for users to interfere with those resources. Because the Finder treats most bundles as opaque entities, it is difficult for casual users to move or delete the resources an application might need.

Everything an application requires should be stored inside its bundle directory. This includes the following types of resources:

The basic structure of a modern bundle is very simple. At the top-level of the bundle is a directory named Contents. This directory contains everything, including the resources, executable code, private frameworks, private plug-ins, and support files needed by the application or plug-in. While the Contents directory might seem superfluous, it identifies the bundle as a modern-style bundle and separates it from document and legacy bundle types.

Inside the Contents directory, you can add numerous other directories and files to implement your bundle. The following sections explain the types of files you can add. These sections are cumulative, that is, each section builds on the contents of the previous section to show you how to build a more full-featured bundle in stages.

Contents:

Adding Configuration Information
Adding Executable Code
Adding Non-Localized Resources
Adding Localized Resources
Adding Platform-Specific Resources
Adding Additional Support Files


Adding Configuration Information

For the Finder to recognize an executable bundle as such, you need to include an Info.plist file (also known as an information property list file). This file contains XML property-list data that identifies the configuration of your bundle. For a minimal bundle, this file would contain very little information, most likely just the name and identifier of the bundle. For more complex bundles, the Info.plist file includes much more information, such as the following:

The exact information you put into your Info.plist file is dependent on your bundle’s needs and can be localized as necessary. For more information on this file, see Runtime Configuration Guidelines.

Important: Bundle resources are located using a case-sensitive search. Therefore, the name of your information property list file must start with a capital “I”.

Adding Executable Code

The most important thing to add to an executable bundle is your executable binary. This is the file compiled from your source code and linked into a form that can be executed on the target computer. Binaries that run natively on Mac OS X go in the Contents/MacOS directory inside your bundle. If you have a helper application or other binary code that runs only the Classic compatibility environment, you can put it into a MacOSClassic directory instead.

Listing 1 shows a bundle whose main executable runs natively in Mac OS X but that uses a helper tool that runs only in the Classic compatibility environment.

Listing 1  A bundle with executable code

    - MyBundle/
        Contents/
            MacOSClassic/
                Helper Tool
            MacOS/
                MyApp
            Info.plist

Some bundles include an alias to the main executable at the same level as the Contents directory. This is a legacy feature to make it easier for users on Mac OS 9 systems to find and launch the application. It is not needed for applications that run only on Mac OS X.

Adding Non-Localized Resources

Resources in your bundle belong in a separate Resources directory just inside the Contents directory. This is where you put image, sound, nib, strings, and icon files among others. The top-level Resources directory contains resources that apply to all localized versions of your application. You can also put global resources in a custom subdirectory. If you have language-specific resources, put them into language-specific subdirectories, as described in “Adding Localized Resources.”

Note: You should always place resources in the Resources directory as opposed to embedding them in the resource fork of your executable file. The use of resource forks is not recommended as it precludes the use of your bundle on non-HFS file systems. Resource forks are also not supported by Mach-O executables.

Listing 2 shows a bundle that includes some resources in the native language of the program. The files in the WaterSounds directory are considered global resources just like Hand.tiff, Horse.jpg, and MyBundle.icns.

Listing 2  A bundle with global resources

    - MyBundle/
        MyApp /* alias to Contents/MacOSClassic/MyApp */
        Contents/
            MacOSClassic/
                Helper Tool
                MyApp
            MacOS/
                Helper Tool
                MyApp
            Info.plist
            Resources/
                Hand.tiff
                Horse.jpg
                MyBundle.icns
                WaterSounds/
                    Water1.aiff
                    Water2.aiff

One special resource that belongs in your top-level Resources directory is your application icon file. By convention, this file takes the name of the bundle and an extension of .icns; the image format can be any supported type, but if no extension is specified, the system assumes .icns.

Adding Localized Resources

Within the Resources directory, you can create one or more additional subdirectories to store language-specific resources. The name of each directory is based on the language and region of the translation followed by the .lproj extension. For all languages, you can use either the ISO 639 or ISO 3166 standards for specifying language directories. The ISO 639 format is as follows:

language.lproj

The ISO 3166 format is as follows:

language_region.lproj

For both formats, the language and region designators are two-letter ISO codes. For each language, you must include a language-specific resource directory and may include one or more region-specific directories as well. For example, for the English language, you would put all of your English resources in an en.lproj directory and could include a copy of some resources specific to the United States in a en_US.lproj directory. For backwards compatibility, NSBundle and CFBundle also support human-readable names for several common languages. For more information, see “Language Designations” in Internationalization Programming Topics.

Each of your language-specific resource directories should contain a copy of the same resource files. The names of the files must all be the same; only the content of the files differs based on the language. When your application asks for a resource file, Mac OS X uses the current language preferences to return the file from the appropriate directory.

Listing 3 shows a bundle that includes localized resources for multiple foreign languages. Notice that the region-specific directories do not contain a full complement of resources. If a region-specific version of a resource is not found, the bundle interfaces search in the language-specific directory (in this case en.lproj) for the resource. The language-specific directory must contain a complete copy of the language-specific resources.

Listing 3  A bundle with localized resources

    - MyBundle/
        MyApp /* alias to Contents/MacOSClassic/MyApp */
        Contents/
            MacOSClassic/
                Helper Tool
                MyApp
            MacOS/
                Helper Tool
                MyApp
            Info.plist
            Resources/
                Hand.tiff
                Horse.jpg
                MyBundle.icns
                WaterSounds/
                    Water1.aiff
                    Water2.aiff
                en_GB.lproj/
                    MyApp.nib
                    bird.tiff
                    Localizable.strings
                en_US.lproj/
                    MyApp.nib
                    Localizable.strings
                en.lproj/
                    MyApp.nib
                    bird.tiff
                    Bye.txt
                    house.jpg
                    InfoPlist.strings
                    Localizable.strings
                    CitySounds/
                        city1.aiff
                        city2.aiff
                Japanese.lproj/
                    MyApp.nib
                    bird.tiff
                    Bye.txt
                    house.jpg
                    InfoPlist.strings
                    Localizable.strings
                    CitySounds/
                        city1.aiff
                        city2.aiff

For more information about internationalization of your software and localization of its resources, see Internationalization Programming Topics.

Adding Platform-Specific Resources

In addition to localized resources, you can also add resources that apply to a specific operating system supported by the bundle. Platform-specific resources are created by adding specific identifiers to existing resource names. Mac OS X defines the identifiers macosclassic for Mac OS 9 resources and macos for Mac OS X resources.

Note: Support for platform-specific resources exists primarily to maintain compatibility with legacy applications. New applications should have only Mac OS X resources and therefore should not need platform-specific versions.

To construct a platform-specific resource name, insert a hyphen followed by the appropriate identifier immediately before the filename extension of the resource. For example, if you have a resource named Fish.jpg its Mac OS 9 name would be Fish-macosclassic.jpg and its Mac OS X name would be Fish-macos.jpg. If your bundle requests the resource Fish.jpg, it would get back a path to Fish-macosclassic.jpg on Mac OS 9 or Fish-macos.jpg on Mac OS X. If no platform-specific version existed, your bundle would get back a path to Fish.jpg.

Important: If you include platform-specific versions of a resource, you must also include the platform-generic version in the same directory.

Platform-specific resources can reside in the global Resources directory or in any of the language-specific subdirectories in your bundle. Listing 4 shows a bundle that includes platform-specific variants of the house.jpg file.

Listing 4  A bundle with platform-specific resources

- MyBundle/
        MyApp /* alias to Contents/MacOSClassic/MyApp */
        Contents/
            MacOSClassic/
                Helper Tool
                MyApp
            MacOS/
                Helper Tool
                MyApp
            Info.plist
            Resources/
                Hand.tiff
                Horse.jpg
                MyBundle.icns
                WaterSounds/
                    Water1.aiff
                    Water2.aiff
                en_GB.lproj
                    MyApp.nib
                    bird.tiff
                    Localizable.strings
                en_US.lproj/
                    MyApp.nib
                    Localizable.strings
                en.lproj
                    MyApp.nib
                    bird.tiff
                    Bye.txt
                    house.jpg
                    house-macos.jpg
                    house-macosclassic.jpg
                    InfoPlist.strings
                    Localizable.strings
                    CitySounds/
                        city1.aiff
                        city2.aiff
                Japanese.lproj/
                    MyApp.nib
                    bird.tiff
                    Bye.txt
                    house.jpg
                    house-macos.jpg
                    house-macosclassic.jpg
                    InfoPlist.strings
                    Localizable.strings
                    CitySounds/
                        city1.aiff
                        city2.aiff

Adding Additional Support Files

While executable and resource files are standard in most bundles, there are several other special directories that are not needed by most bundles. These directories include the following:

All of these directories are inextricably bound to the application. This is particularly true for frameworks. The dynamic shared libraries of embedded frameworks are revision-locked and cannot be superseded by any other, even newer, versions that may be available to the operating system.

Listing 5 shows the bundle structure for a fully-localized application that supports these directories.

Listing 5  The bundle layout of a complex application

    - MyBundle/
        MyApp /* alias to Contents/MacOSClassic/MyApp */
        Contents/
            MacOSClassic/
                Helper Tool
                MyApp
            MacOS/
                Helper Tool
                MyApp
            Info.plist
            Resources/
                Hand.tiff
                Horse.jpg
                MyBundle.icns
                WaterSounds/
                    Water1.aiff
                    Water2.aiff
                en_GB.lproj
                    MyApp.nib
                    bird.tiff
                    Localizable.strings
                en_US.lproj/
                    MyApp.nib
                    Localizable.strings
                en.lproj
                    MyApp.nib
                    bird.tiff
                    Bye.txt
                    house.jpg
                    house-macos.jpg
                    house-macosclassic.jpg
                    InfoPlist.strings
                    Localizable.strings
                    CitySounds/
                        city1.aiff
                        city2.aiff
                Japanese.lproj/
                    MyApp.nib
                    bird.tiff
                    Bye.txt
                    house.jpg
                    house-macos.jpg
                    house-macosclassic.jpg
                    InfoPlist.strings
                    Localizable.strings
                    CitySounds/
                        city1.aiff
                        city2.aiff
            Frameworks/
            PlugIns/
            SharedSupport/

For information on how to embed frameworks in your application bundle, see Framework Programming Guide.



< Previous PageNext Page > Hide TOC


© 2003, 2005 Apple Computer, Inc. All Rights Reserved. (Last updated: 2005-11-09)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.