PATH  Documentation > Mac OS X > Foundation Reference: Java



Table of Contents

NSBundle


Inherits from:
NSObject
Package:
com.apple.yellow.foundation

Class at a Glance


An NSBundle represents a location in the file system that groups code and resources that can be used in a program. NSBundles locate program resources, dynamically load executable code, and assist in localization. You build a bundle in Project Builder using one of these project types: Application, Framework, Loadable Bundle, Palette.

Principal Attributes


Commonly Used Methods



localizedStringForKey Returns a localized version of a string.
pathForResource Returns the path for the specified resource.
principalClass Returns the principal class, dynamically loading code if needed.


Class Description


An NSBundle is an object that corresponds to a directory where related resources-including executable code-are stored. The directory, in essence, "bundles" a set of resources used by an application into convenient chunks, and the NSBundle object makes those resources available to the application. NSBundle can find requested resources in the directory and can dynamically load executable code. The term bundle refers both to the object and to the directory it represents.

Bundles are useful in a variety of contexts. Since bundles combine executable code with the resources used by that code, they facilitate installation and localization. NSBundles are also used to locate specific resources, to obtain localized strings, to load code dynamically, and to determine which classes are loaded.

Each resource in a bundle usually resides in its own file. Bundled resources include such things as:

The Project Builder application defines four types of projects that build bundles as file packages. A file package is a directory that the Workspace Manager presents to users as if it were a simple file; the contents of the directory are hidden. The four types of Project Builder bundles are:

For all types of bundles, the executable-code file of a bundle (of which there can be only one) is in the immediate bundle directory and takes the same name as the bundle, minus the extension. Bundles also encode (as a property list) the important attributes of the bundle, such as the main nib file name, executable name, document extensions, and so forth. You can access these attributes with NSBundle's infoDictionary method, which returns the file's contents as an NSDictionary.


The Main Bundle


Every application has at least one bundle-its main bundle-which is the ".app" directory where its executable file is located. This file is loaded into memory when the application is launched. It includes at least the main() function and other code necessary to start up the application. You obtain an NSBundle object corresponding to the main bundle with the class method mainBundle.


Framework Bundles


Frameworks are bundles that package dynamic shared libraries along with the nib files, images, and other resources that support the executable code and with the header files and documentation that describe the associated APIs. As long as your applications are dynamically linked with frameworks, you should have little need to do anything explicitly with those frameworks thereafter; in a running application, the framework code is automatically loaded, as needed. You can however, get an NSBundle object associated with a framework by invoking the class method bundleForClass specifying, as the argument, a class that's defined in the framework.


Loadable Bundles and Dynamic Loading


An application can be organized into any number of other bundles in addition to the main bundle and the bundles of linked-in frameworks. Although these loadable bundles usually reside inside the application file package, they can be located anywhere in the file system. Each loadable-bundle directory-by convention, with a ".bundle" extension-is represented in the application by a separate NSBundle object. Through this object the application can dynamically load the code and resources in the bundle when it needs them. For example, an application for managing PostScript printers may have a bundle full of PostScript code to be downloaded to printers.

The executable code files in loadable bundles hold class (and category) definitions that the NSBundle object can dynamically load while the application runs. When asked for a certain class (through the invocation of classNamed: or principalClass), the NSBundle loads the object file that contains the class definition (if it's not already loaded) and returns the class object; it also loads other classes and categories that are stored in the file.

The major advantage of bundles is application extensibility. A set of bundled classes often supports a small collection of objects that can be integrated into the larger object network already in place. (Preferences is one example of this.) The linkage is established through an instance of the principal class. This object might have methods to return other objects that the application can talk to, but typically all messages from the application to the subnetwork are funneled through the one instance.

Since each bundle can have only one executable file, that file should be kept free of localizable content. Anything that needs to be localized should be segregated into separate resource files and stored in localized-resource subdirectories.


Note: To create a loadable bundle-a bundle with dynamically loadable code-without using Project Builder, use the ld(1) -bundle flag on the cc command line.


Localized Resources


If an application is to be used in more than one part of the world, its resources may need to be customized, or "localized," for language, country, or cultural region. An application may need, for example, to have separate Japanese, English, French, Hindu, and Swedish versions of the character strings that label menu commands.

Resource files specific to a particular language are grouped together in a subdirectory of the bundle directory. The subdirectory has the name of the language (in English) followed by a ".lproj" extension (for "language project"). The application mentioned above, for example, would have Japanese.lproj, English.lproj, French.lproj, Hindi.lproj, and Swedish.lproj subdirectories. Each ".lproj" subdirectory in a bundle has the same set of files; all versions of a resource file must have the same name. Thus, Hello.snd in French.lproj should be the French counterpart to the Swedish Hello.snd in Swedish.lproj, and so on. If a resource doesn't need to be localized at all, it's stored in the bundle directory itself, not in the ".lproj" subdirectories.

The user determines which set of localized resources will actually be used by the application. NSBundle objects rely on the language preferences set by the user in the Preferences application. Preferences lets users order a list of available languages so that the most preferred language is first, the second most preferred language is second, and so on.

When an NSBundle is asked for a resource file, it provides the path to the resource that best matches the user's language preferences. For details, see the description of pathForResource.


How NSBundles Locate Resources


A bundle's resources are typically stored in a directory named Resources within the bundle directory. Within the Resources directory are non-localized resources and localized resource directories (English.lproj, Swedish.lproj, and so on). Generally, when an NSBundle looks for resources, it starts at the top, in a non-localized location, and searches "downward" toward the localized directories.

For example, suppose you want to find a resource with name "Main" and type "nib". NSBundle searches the Resource directory at the "top" non-localized level for the file Main.nib. If it doesn't find the file there, NSBundle then searches each of the language subdirectories in the user's preferred order of languages. By this scheme, the localized version of a resource that also exists at the top level will not be found, but the non-localized one will be. For this reason, you should place all non-localized resources in the top level of Resources, and you shouldn't put any localized resources there.

The bundlePath parameter is intended for locating resources of a common type or purpose that are put in a single directory; for example, all images could be put into a directory called Images within the Resource directory. (However, note that the Application Kit's imageNamed: class method in NSImage does not support searching arbitrary directories for images.) You can thus use specialized resource subdirectories and the bundlePath parameter to manage resources. This is not "automatic" functionality, however, since it requires the developer to specify the name of the directory as well as replicate the required resources and language projects within that directory.




Method Types


Constructors
NSBundle
Getting an NSBundle
bundleForClass
bundleWithPath
mainBundle
allBundles
allFrameworks
Getting a bundled class
principalClass
Finding a resource
pathForResource
pathsForResources
resourcePath
Getting the bundle directory
bundlePath
Getting bundle information
infoDictionary
Managing localized resources
localizedStringForKey
Loading a bundle's code
load


Constructors



NSBundle

public NSBundle()

Description forthcoming.

public NSBundle(String aString)

Description forthcoming.


Static Methods



allBundles

public static NSArray allBundles()

Returns an array of all the application's non-framework bundles. This includes the main bundle and all bundles that have been dynamically created but doesn't contain any bundles that represent frameworks.

allFrameworks

public static NSArray allFrameworks()

Returns an array of all of the application's bundles that represent frameworks. This includes frameworks which are linked into an application when the application is built and bundles for frameworks which have been dynamically created.

bundleForClass

public static NSBundle bundleForClass(Class aClass)

Returns the NSBundle that dynamically loaded aClass (a loadable bundle), the NSBundle for the framework in which aClass is defined, or the main bundle object if aClass was not dynamically loaded or is not defined in a framework.

See Also: mainBundle, bundleWithPath



bundleWithPath

public static NSBundle bundleWithPath(String path)

Returns an NSBundle that corresponds to the specified directory path or null if path does not identify an accessible bundle directory. This method allocates and initializes the returned object if it doesn't already exist.

See Also: mainBundle, bundleForClass



localizedString

public static String localizedString(String aString)

Description forthcoming.

public static String localizedString( String aString, String aString)

Description forthcoming.

public static String localizedString( String aString, String aString, String aString)

Description forthcoming.

public static String localizedString( String aString, String aString, NSBundle aBundle, String aString)

Description forthcoming.

mainBundle

public static NSBundle mainBundle()

Returns an NSBundle that corresponds to the directory where the application executable is located or null if this executable is not located in an accessible bundle directory. This method allocates and initializes the returned NSBundle if it doesn't already exist.

In general, the main bundle corresponds to an application file package or application wrapper: a directory that bears the name of the application and is marked by a ".app" extension.

See Also: bundleForClass, bundleWithPath




Instance Methods



bundlePath

public String bundlePath()

Returns the full pathname of the receiver's bundle directory.

infoDictionary

public NSDictionary infoDictionary()

Returns a dictionary that contains information about the receiver. This information is extracted from the property list (Info.plist) associated with the bundle. The returned dictionary is empty if no Info.plist can be found. Common keys for accessing the values of the dictionary are Executable, Extensions, Icon, MainNibFile, and PrincipalClass.

See Also: principalClass



load

public boolean load()

Dynamically loads the bundle's executable code into a running program, if the code has not already been loaded. A bundle attempts to load its code-if it has any-only once. Returns true if the method successfully loaded the bundle's code or if the code had already been loaded. Returns false if the method failed to load the code.You don't need to load a bundle's executable code to search the bundle's resources.

See Also: principalClass



localizedStringForKey

public String localizedStringForKey( String key, String value, String tableName)

Returns a localized version of the string designated by key in table tableName. The argument tableName specifies the receiver's string table to search. If tableName is null or is an empty string, the method attempts to use the table in Localizable.strings. The value argument specifies the value to return if key is null or if a localized string for key can't be found in the table. If value is null or an empty string, and a localized string is not found in the table, the method returns key. If key and value are both null, the method returns the empty string.

Using the user default ShowNonLocalizedStrings, you can alter the behavior of localizedStringForKey to log a message when the method can't find a localized string. If you set this default to true (in the global domain or in the application's domain), then when the method can't find a localized string in the table, it logs a message to the console and capitalizes key before returning it.

See Also: pathForResource, pathsForResources



pathForResource

public String pathForResource( String name, String extension)

Returns the full pathname for the resource identified by name with the specified file extension. If the extension argument is null or an empty string (""), the resource sought is identified by name, with no extension. The method first looks for a non-localized resource in the immediate bundle directory; if the resource is not there, it looks for the resource in the language-specific ".lproj" directory (the local language is determined by user defaults).

public String pathForResource( String name, String extension, String bundlePath)

Returns the full pathname for the resource identified by name, with the specified file name extension, and residing in the directory bundlePath; returns null if no matching resource file exists in the bundle. The argument bundlePath must be a valid bundle directory or null. The argument extension can be an empty string or null; in either case the pathname returned is the first one encountered with name, regardless of the extension. The method searches in this order:

The order of language directories searched corresponds to the user's preferences. If bundlePath is null, the same search order as described above is followed, minus bundlePath.

See Also: localizedStringForKey, pathsForResources



pathsForResources

public NSArray pathsForResources( String extension, String bundlePath)

Returns an array containing pathnames for all bundle resources having the specified file name extension and residing in the directory bundlePath; returns an empty array if no matching resource files are found. This method provides a means for dynamically discovering bundle resources. The argument bundlePath must be a valid bundle directory or null. The extension argument can be an empty string or null; if you specify either of these for extension, all bundle resources are returned. Although there is no guaranteed search order, all of the following directories will be searched:

The language directories searched corresponds to the user's preferences. If bundlePath is null, the same search order as described above is followed, minus bundlePath.

See Also: localizedStringForKey, pathForResource



principalClass

public Class principalClass()

Returns the NSBundle's principal class after ensuring that the code containing the definition of that class is dynamically loaded. If the NSBundle encounters errors in loading or if it can't find the executable code file in the bundle directory, it returns null. The principal class typically controls all the other classes in the bundle; it should mediate between those classes and classes external to the bundle. Classes (and categories) are loaded from just one file within the bundle directory. NSBundle obtains the name of the code file to load from the dictionary returned from infoDictionary, using "NSExecutable" as the key. The NSBundle determines its principal class in one of two ways:
ld -o myBundle -r Reporter.o NotePad.o QueryList.o

The order of classes in Project Builder's project browser is the order in which they will be linked. To designate the principal class, Control-drag the file containing its implementation to the top of the list.

As a side-effect of code loading, the receiver posts "BundleDidLoadNotification" after all classes and categories have been loaded; see "Notifications" , below for details.

See Also: classNamed:, infoDictionary, load



resourcePath

public String resourcePath()

Returns the full pathname of the receiving bundle's subdirectory containing resources.

See Also: bundlePath




Notifications


The following notification is declared and posted by NSBundle.

BundleDidLoadNotification

This notification contains a notification object and a userInfo dictionary. The notification object is the NSBundle that dynamically loads classes.

NSBundle posts BundleDidLoadNotification to notify observers which classes and categories have been dynamically loaded. When a request is made to an NSBundle for a class (classNamed: or principalClass), the bundle dynamically loads the executable code file that contain the class implementation and all other class definitions contained in the file. After the module is loaded, the NSBundle posts a notification with a userInfo dictionary containing all classes that were loaded.

The userInfo dictionary contains this key and value:


Key Value
LoadedClasses An NSArray containing the names (as Strings) of each class and category that was loaded

In a typical use of this notification, an object might want to enumerate the userInfo NSArray to check if each loaded class conformed to a certain protocol (say, a protocol for a plug-and-play tool set); if a class does conform, the object would create an instance of that class and add the instance to another NSArray.



Table of Contents