< Previous PageNext Page > Hide TOC

Locating and Opening Bundles

Before you can access a bundle’s resources, you must first obtain an appropriate NSBundle or CFBundle object. The following sections outline the different ways you create these objects from your code.

Contents:

Opening the Main Bundle
Locating Bundles by Path
Locating Bundles in Known Directories
Locating Bundles by Identifier
Searching for Related Bundles


Opening the Main Bundle

The main bundle is the bundle that contains your running code. This is the most commonly used bundle for any program and is what you use to load your strings, images, and other resource files. Because it is a meta bundle, the main bundle is the easiest to retrieve. To get it, call either CFBundleGetMainBundle function or use the mainBundle class method of NSBundle. Listing 1 shows an example of loading the main bundle from a Carbon application.

Listing 1  Locating the main bundle from Core Foundation

CFBundleRef mainBundle;
 
// Get the main bundle for the app
mainBundle = CFBundleGetMainBundle();

Listing 2 shows this same code example written in Objective-C and using the NSBundle class.

Listing 2  Locating the main bundle from Cocoa

NSBundle* mainBundle;
 
// Get the main bundle for the app.
mainBundle = [NSBundle mainBundle];

When getting the main bundle it is still a good idea to make sure the value you get back represents a valid bundle. In particular, you might get a NULL value for the main bundle in the following situations:

Locating Bundles by Path

If you want to access a bundle other than your main bundle, one way to create an appropriate bundle object is with a path to the bundle. The CFBundleCreate function in Core Foundation takes a CFURLRef specifying the path to the bundle and returns a corresponding CFBundle data type. Similarly, you can use the bundleWithPath: method of NSBundle to create a bundle object from an NSString.

Listing 3 shows an example of how to create a CFBundle from a string specifying the path. The main trick is to convert the string to a CFURLRef object so that it can be passed to the CFBundleCreate function.

Listing 3  Locating a Core Foundation bundle using its path

CFURLRef bundleURL;
CFBundleRef myBundle;
 
// Make a CFURLRef from the CFString representation of the
// bundle’s path.
bundleURL = CFURLCreateWithFileSystemPath(
                kCFAllocatorDefault,
                CFSTR("/Local/Library/MyBundle.bundle"),
                kCFURLPOSIXPathStyle,
                true );
 
// Make a bundle instance using the URLRef.
myBundle = CFBundleCreate( kCFAllocatorDefault, bundleURL );
 
// Any CF objects returned from functions with "create" or
// "copy" in their names must be released by us!
CFRelease( bundleURL );
CFRelease( myBundle );

The preceding example can be rewritten for Cocoa using the code shown in Listing 4.

Listing 4  Locating a Cocoa bundle using its path

NSBundle* myBundle;
 
// Get the main bundle for the app.
myBundle = [NSBundle bundleWithPath:@"/Local/Library/MyBundle.bundle"];

Locating Bundles in Known Directories

Even if you do not know the exact path to a bundle, there are still situations where you can search for it by name. One example is if your application contains several embedded plug-ins in a PlugIns directory. Because this directory is inside of your application bundle, you can use the CFBundle functions for locating resources to get the path to each plug-in.

To load a set of plug-ins, use the CFBundleCreateBundlesFromDirectory function to create new CFBundle objects for all of the plug-ins in a given directory. Listing 5 is similar to the previous example, but this time the code retrieves CFBundle objects for all of the plug-ins in the application’s PlugIns directory.

Listing 5  Obtaining bundle references for a set of plug-ins

CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef plugInsURL;
CFArrayRef bundleArray;
 
// Get the URL to the application’s PlugIns directory.
plugInsURL = CFBundleCopyBuiltInPlugInsURL(mainBundle);
 
// Get the bundle objects for the application’s plug-ins.
bundleArray = CFBundleCreateBundlesFromDirectory( kCFAllocatorDefault,
                    plugInsURL, NULL );
 
// Release the CF objects
CFRelease( plugInsURL );
CFRelease( bundleArray );

Locating Bundles by Identifier

Bundle identifiers make it possible to locate already loaded bundles at runtime. This is a useful way for your code to locate its own bundle at runtime. Storing a bundle identifier can be more efficient than storing a reference to the bundle itself. When you need to access the bundle again, you can use the identifier to retrieve the CFBundle object.

Each bundle you create should have a bundle identifier in its information property-list (Info.plist) file. The CFBundleIdentifier key contains the bundle identifier string, which traditionally uses Java-style package naming conventions. For example, a Finder plug-in from Apple might use the string com.apple.Finder.MyGetInfoPlugin as its bundle identifier. Including the domain name of your company in the string helps avoid collisions with bundle developers in other companies.

Listing 6 shows how to retrieve a bundle using its bundle identifier. Remember that a bundle identifier can only be used to locate an existing CFBundle instance (including the main bundle and bundles for all statically linked frameworks). If your bundle has been opened and its code is running, then you can locate it using its bundle identifier.

Listing 6  Locating a bundle using its identifier

CFBundleRef requestedBundle;
 
 // Look for a bundle using its identifier
 requestedBundle = CFBundleGetBundleWithIdentifier(
        CFSTR("com.apple.Finder.MyGetInfoPlugIn") );

You can also locate bundles by their identifier in Cocoa. The NSBundle class defines the class method bundleWithIdentifier: to find and return an existing bundle.

Searching for Related Bundles

If you are writing a Cocoa application, you can obtain a list of bundles related to the application by calling the allBundles and allFrameworks class methods of NSBundle. These methods create an array of NSBundle objects corresponding to the bundles or frameworks currently in use by your application. You can use these methods as convenience functions rather than maintain a collection of loaded bundles yourself.

The bundleForClass: class method is another way get related bundle information in a Cocoa application. This method returns the bundle in which a particular class is defined. Again, this method is mostly for convenience so that you do not have to retain a pointer to an NSBundle object that you may use only occasionally.



< 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.