Inherits From:
NSObject
Conforms To:
NSObject (NSObject)
Declared In:
Foundation/NSBundle.h
- initWithPath:
| (designated initializer) |
+ mainBundle | Returns the NSBundle for the application wrapper. |
+ bundleForClass:
| Returns the NSBundle in which the class is implemented. |
+ bundleWithPath: | Returns the NSBundle at a location in the file system. |
- localizedStringForKey:value:table:
| Returns a localized version of a string. |
- pathForResource:ofType: | Returns the path for the specified resource. |
- principalClass | Returns the principal class, dynamically loading code if needed. |
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:
Application
. The application wrapper is a bundle that contains the resources needed to launch the application, including the application executable. This bundle is also known as the main bundle. Its extension is ".app".
Framework
. A framework is a directory containing a dynamic shared library and all the resources that go with that library, such as header files, images, and documentation. Its extension is ".framework".
Loadable Bundle
. Like an application, a loadable bundle usually contains executable code and associated resources. Loadable bundles differ from applications and frameworks because they must be explicitly loaded into a running application. (See "Loadable Bundles," below for more information.) The extension of a loadable bundle is conventionally ".bundle" but can be something else (for example, ".preference").
Palette
. A palette is a type of loadable bundle specialized for Interface Builder. It contains custom user-interface objects and compiled code that are loaded into an Interface Builder palette.
infoDictionary
method, which returns the file's contents as an NSDictionary.
You shouldn't attempt to create an NSBundle subclass since the designated initializer, initWithPath:
, might substitute another NSBundle for self
.
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
.
bundleForClass:
specifying, as the argument, a class that's defined in the framework.
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. (NEXTSTEP 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.
ld
(1) -bundle
flag on the cc
command line.
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 descriptions of pathForResource:ofType:inDirectory
and pathForResource:ofType:.
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.
When it finds a resource, an NSBundle checks if a resource of the name "Main-
$(PLATFORM_OS)" of type "nib" exists. $(PLATFORM_OS) represents the make variable of the same name, and takes on the same values that the make variable takes on at compile time. For example, on Windows, during a project build, "$(PLATFORM_OS)" in the Makefile.postamble
will yield the value "winnt". When "Main.nib" is found in a directory, the NSBundle also sees if "Main-winnt.nib" exists in that same directory. If it does, the NSBundle returns the path to the platform-specific resource; if it does not, it returns the path to "Main.nib". Note that for "Main-winnt.nib" to be found, a file named "Main.nib" must exist in the same directory (including language-specific resource directories). You typically give one platform-general version of a resource the name without this $(PLATFORM_OS) suffix, and give the platform-specific versions of the resource extended names. The values that $(PLATFORM_OS) can take are currently "winnt" (on OPENSTEP for Windows), "nextstep" (on OPENSTEP for MACH), "hpux"(on PDO for HP-UX), and "solaris" (on PDO for Solaris).
Another way to accommodate platform-specific resources is to use the inDirectory:
parameter of NSBundle's resource-searching methods. The inDirectory:
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 inDirectory:
parameter to manage platform-specific resources. This is not "automatic" functionality, however, since it requires the developer to specify the name of the platform-specific directory as well as replicate the required resources and language projects within that directory. The $(PLATFORM_OS) mechanism is simpler to use, particularly if the number of platform-specific resources is small.
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
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:
(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:
(NSString *)path
Returns an NSBundle that corresponds to the specified directory path or nil
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:
mainBundle
Returns an NSBundle that corresponds to the directory where the application executable is located or nil
if this executable is not located in a 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:
pathForResource:
(NSString *)nameofType:
(NSString *)extensioninDirectory:
(NSString *)bundlePath
Returns the full pathname for the resource identified by name, having the specified file name extension, and residing in the directory bundlePath; returns nil
if no matching resource file exists in the bundle. The argument bundlePath must be a valid bundle directory. The argument extension can be an empty string or nil
; in either case the pathname returned is the first one encountered with name, regardless of the extension. If bundlePath is specified, the method searches in this order:
bundlePath/Resources/
name.extension
bundlePath/Resources/
<language.lproj>/name.extension
bundlePath/name.extension
bundlePath/<language.lproj>/name.extension
The order of language directories searched corresponds to the user's preferences.
See also:
- localizedStringForKey:value:table:
, - pathForResource:ofType:
, - pathForResource:ofType:inDirectory:
,
- pathsForResourcesOfType:inDirectory:
bundlePath
Returns the full pathname of the receiver's bundle directory.
classNamed:
(NSString *)className
Returns the class named className. If the bundle's executable code is not yet loaded, this method dynamically loads it into memory. The method returns nil
if className isn't one of the classes associated with the receiver or if there is an error in loading the executable code containing the class implementation. Classes (and categories) are loaded from just one file within the bundle directory; this code file has the same name as the directory, but without the extension (".bundle," ".app," ".framework"). As a side-effect of code loading, the receiver posts NSBundleNotification for each class and category loaded; see "Notifications," below for details.
The following example loads a bundle's executable code containing the class "FaxWatcher."
- (void)loadBundle:(id)sender
{
Class exampleClass;
id newInstance;
NSString *str = @"/me/Projects/BundleExample/BundleExample.bundle";
NSBundle *bundleToLoad = [NSBundle bundleWithPath:str];
if (exampleClass = [bundleToLoad classNamed:@"FaxWatcher"]) {
newInstance = [[exampleClass alloc] init];
// [newInstance doSomething];
}
}
See also:
- principalClass
,
- load
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 NSExecutable, NSExtensions, NSIcon, NSMainNibFile, and NSPrincipalClass.
See also:
- principalClass
initWithPath:
(NSString *)fullPath
Returns an NSBundle corresponding to the directory fullPath. This method initializes and returns a new instance only if there is no existing NSBundle associated with fullPath, in which case it deallocates self
and returns the existing object. fullPath must be a full pathname for a directory; if it contains any symbolic links, they must be resolvable. If the directory doesn't exist or the user doesn't have access to it, this method returns nil
.
It's not necessary to allocate and initialize an instance for the main bundle; use the mainBundle
class method to get this instance. You can also use the bundleWithPath:
class method to obtain a bundle identified by its directory path.
See also:
+ bundleForClass:
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 YES if the method successfully loaded the bundle's code or if the code had already been loaded. Returns NO if the method failed to load the code.
- classNamed:
, - principalClass
localizedStringForKey:
(NSString *)key value:
(NSString *)value table:
(NSString *)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 nil
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 nil
or if a localized string for key can't be found in the table. If value is nil
or an empty string, and a localized string is not found in the table, the method returns key. If key and value are both nil
, the method returns the empty string.
localizedStringForKey:value:table:
to log a message when the method can't find a localized string.
If you set this default to YES (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.
The following example cycles through a static array of keys when a button is clicked, gets the value for each key from a strings table named Buttons.strings
, and sets the button title with the returned value.
- (void)changeTitle:(id)sender
{
static int keyIndex = 0;
NSBundle *thisBundle = [NSBundle bundleForClass:[self class]];
NSString *locString = [thisBundle
localizedStringForKey:assortedKeys[keyIndex++]
value:@"" table:@"Buttons"];
[sender setTitle:locString];
if (keyIndex == MAXSTRINGS) keyIndex=0;
}
See also:
- pathForResource:ofType:
, - pathForResource:ofType:inDirectory:
,
- pathsForResourcesOfType:inDirectory:, + pathForResource:ofType:inDirectory:
pathForResource:
(NSString *)name ofType:
(NSString *)extension
Returns the full pathname for the resource identified by name and having the specified file extension. If the extension argument is nil
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).
The following code fragment gets the path to a localized sound, creates an Sound instance from it, and plays the sound.
NSString *soundPath;
Sound *thisSound;
NSBundle *thisBundle = [NSBundle bundleForClass:[self class]];
if (soundPath = [thisBundle pathForResource:@"Hello" ofType:@"snd"]) {
thisSound = [[[Sound alloc] initFromSoundfile:soundPath] autorelease];
[thisSound play];
}
See also:
- localizedStringForKey:value:table:
,
- pathForResource:ofType:inDirectory:
,
- pathsForResourcesOfType:inDirectory:
, + pathForResource:ofType:inDirectory:
pathForResource:
(NSString *)name ofType:
(NSString *)extension inDirectory:
(NSString *)bundlePath
Returns the full pathname for the resource identified by name, having the specified file name extension, and residing in the directory bundlePath; returns nil
if no matching resource file exists in the bundle. The argument bundlePath must be a valid bundle directory or nil
. The argument extension can be an empty string or nil
; in either case the pathname returned is the first one encountered with name, regardless of the extension. If bundlePath is specified, the method searches in this order:
<main bundle path>/Resources/
bundlePath/
name.extension
<main bundle path>/Resources/
bundlePath/
<language.lproj>/
name.extension
<main bundle path>/
bundlePath/
name.extension
<main bundle path>/
bundlePath/
<language.lproj>/
name.extension
The order of language directories searched corresponds to the user's preferences. If bundlePath is nil
, the same search order as described above is followed, minus bundlePath.
See also:
- localizedStringForKey:value:table:
,
- pathForResource:ofType:
,
- pathsForResourcesOfType:inDirectory:
, + pathForResource:ofType:inDirectory:
pathsForResourcesOfType:
(NSString *)extension inDirectory:
(NSString *)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 nil
. The extension argument can be an empty string or nil
; if you specify either of these for extension, however, all bundle resources are returned. Although there is no guaranteed search order, all of the following directories will be searched:
<main bundle path>/Resources/
bundlePath/
name.extension
<main bundle path>/Resources/
bundlePath/
<language.lproj>/
name.extension
<main bundle path>/
bundlePath/
name.extension
<main bundle path>/
bundlePath/
<language.lproj>/
name.extension
The language directories searched corresponds to the user's preferences. If bundlePath is nil
, the same search order as described above is followed, minus bundlePath.
See also:
- localizedStringForKey:value:table:
,
- pathForResource:ofType:
,
- pathForResource:ofType:inDirectory:
, + pathForResource:ofType:inDirectory:
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 nil
. 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:
Info.plist
). NSBundle obtains the principal class from the dictionary using the key NSPrincipalClass. For non-loadable bundles (applications and frameworks), if the principal class is not specified in the property list, the method returns nil
.
ld
command line. In the following example, Reporter would be the principal class:
ld -o myBundle -r Reporter.o NotePad.o QueryList.o
The following method obtains a bundle by specifying its path (bundleWithPath:
), then loads the bundle with principalClass
and uses the returned class object to allocate and initialize an instance of that class.
- (void)loadBundle:(id)sender
{
Class exampleClass;
id newInstance;
NSString *path = @"/tmp/Projects/BundleExample/BundleExample.bundle";
NSBundle *bundleToLoad = [NSBundle bundleWithPath:path];
if (exampleClass = [bundleToLoad principalClass]) {
newInstance = [[exampleClass alloc] init];
[newInstance doSomething];
}
}
See also:
- classNamed:
, - infoDictionary
,
- load
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.
Key | Value |
---|---|
NSLoadedClasses | An NSArray containing the names (as NSStrings) of each class that was loaded |
NSBundle posts NSBundleDidLoadNotification to notify observers which classes 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.
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.
Copyright © 1997, Apple Computer, Inc. All rights reserved.