A representation of the code and resources stored in a bundle directory on disk.
- iOS 2.0+
- macOS 10.0+
- tvOS 9.0+
- watchOS 2.0+
Apple uses bundles to represent apps, frameworks, plug-ins, and many other specific types of content. Bundles organize their contained resources into well-defined subdirectories, and bundle structures vary depending on the platform and the type of the bundle. By using a bundle object, you can access a bundle's resources without knowing the structure of the bundle. The bundle object provides a single interface for locating items, taking into account the bundle structure, user preferences, available localizations, and other relevant factors.
Any executable can use a bundle object to locate resources, either inside an app’s bundle or in a known bundle located elsewhere. You don't use a bundle object to locate files in a container directory or in other parts of the file system.
The general pattern for using a bundle object is as follows:
Create a bundle object for the intended bundle directory
Use the methods of the bundle object to locate or load the needed resource
Use other system APIs to interact with the resource
Some types of frequently used resources can be located and opened without a bundle. For example, when loading images, you store images in asset catalogs and load them using the
init(named:) methods of
NSImage. Similarly, for string resources, you use
NSLocalized to load individual strings instead of loading the entire
.strings file yourself.
Finding and Opening a Bundle
Before you can locate a resource, you must first specify which bundle contains it. The
NSBundle class has many constructors, but the one you use most often is
main. The main bundle represents the bundle directory that contains the currently executing code. So for an app, the main bundle object gives you access to the resources that shipped with your app.
If your app interacts directly with plug-ins, frameworks, or other bundled content, you can use other methods of this class to create appropriate bundle objects. You can always create bundle objects from a known URL or path, but other methods make it easier to access bundles your app is already using. For example, if you link to a framework, you can use the
init(for:) method to locate the framework bundle based on a class defined in that framework.
Locating Resources in a Bundle
You use an
NSBundle object to obtain the location of specific resources inside the bundle. When looking for resources, you provide the name of the resource and its type at a minimum. For resources in a specific subdirectory, you can also specify that directory. After locating the resource, the bundle routines return a path string or URL that you can use to open the file.
Bundle objects follow a specific search pattern when looking for resources on disk. Global resources—that is, resources not in a language-specific
.lproj directory—are returned first, followed by region- and language-specific resources. This search pattern means that the bundle looks for resources in the following order:
Global (nonlocalized) resources
Region-specific localized resources (based on the user’s region preferences)
Language-specific localized resources (based on the user’s language preferences)
Development language resources (as specified by the
CFBundlekey in the bundle’s Info.plist file)
Because global resources take precedence over language-specific resources, you should never include both a global and localized version of a given resource in your app. When a global version of a resource exists, language-specific versions are never returned. The reason for this precedence is performance. If localized resources were searched first, the bundle object might waste time searching for a nonexistent localized resource before returning the global resource.
When locating resource files, the bundle object automatically considers many standard filename modifiers when determining which file to return. Resources may be tagged for a specific device (
~ipad) or for a specific screen resolution (
@3x). Do not include these modifiers when specifying the name of the resource you want. The bundle object selects the file that is most appropriate for the underlying device. For more information, see App Icons on iPhone, iPad and Apple Watch.
Understanding Bundle Structures
Bundle structures vary depending on the target platform and the type of bundle you are building. The
NSBundle class hides this underlying structure in most (but not all) cases. Many of the methods you use to load resources from a bundle automatically locate the appropriate starting directory and look for resources in known places. You can also use the methods and properties of this class to get the location of known bundle directories and to retrieve resources specifically from those directories.
For information about the bundle structure of iOS and macOS apps, see Bundle Programming Guide. For information about the structure of framework bundles, see Framework Programming Guide. For information about the structure of macOS plug-ins, see Code Loading Programming Topics.