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:
executable code
images
sounds
nib files and other archived user-interface definitions
string resources
Resource Manager–style resource files
localized versions of your resources
private libraries and frameworks
plug-ins and other loadable bundles
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.
Adding Configuration Information
Adding Executable Code
Adding Non-Localized Resources
Adding Localized Resources
Adding Platform-Specific Resources
Adding Additional Support Files
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 bundle name
The bundle identifier code
The bundle version
The bundle signature (similar to creator types on Mac OS 9)
The location of the bundle executable and entry point
Information about how the bundle should be handled by Launch Services
Information about the document types recognized by the bundle
The services exported by the bundle
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”.
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.
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
.
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.
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 |
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:
A Frameworks
directory contains any private libraries and frameworks used by the executable.
A PlugIns
directory contains loadable bundles that extend the basic features of the executable.
A SharedSupport
directory contains additional non-critical resources that do not impact the ability of the application to run. For example, this directory might include things like document templates, clip art, and tutorials.
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.
© 2003, 2005 Apple Computer, Inc. All Rights Reserved. (Last updated: 2005-11-09)