- Inherits from:
- NSObject
- Package:
- com.apple.yellow.foundation
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.
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. |
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:
.app
"..framework
"..bundle
" but can
be something else (for example, ".preference
").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.
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.
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.
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. |
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.
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.
- 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
public NSBundle()
public NSBundle(String aString)
public static NSArray allBundles()
public static NSArray allFrameworks()
public static NSBundle bundleForClass(Class aClass)
See Also: mainBundle, bundleWithPath
public static NSBundle bundleWithPath(String path)
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
public static String localizedString(String aString)
public static String localizedString(
String aString,
String aString)
public static String localizedString(
String aString,
String aString,
String aString)
public static String localizedString(
String aString,
String aString,
NSBundle aBundle,
String aString)
public static NSBundle mainBundle()
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
public String bundlePath()
public NSDictionary infoDictionary()
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
public boolean load()
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
public String localizedStringForKey(
String key,
String value,
String tableName)
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
public String pathForResource(
String name,
String extension)
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)
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:<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 null
,
the same search order as described above is followed, minus bundlePath.
See Also: localizedStringForKey, pathsForResources
public NSArray pathsForResources(
String extension,
String bundlePath)
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:<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 null, the same search order as described above is followed, minus bundlePath.
See Also: localizedStringForKey, pathForResource
public Class principalClass()
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:NSPrincipalClass
. For non-loadable
bundles (applications and frameworks), if the principal class is
not specified in the property list, the method returns nil.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
public String resourcePath()
See Also: bundlePath
The following notification is declared and posted by NSBundle.
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.