Nib files play an integral role in the development of your applications. They are a powerful type of resource that you use to store runtime objects and interface-related content. They are also the fundamental document type of the Interface Builder application.
Interface Builder 3.0 and later offer many options for creating and working with nib files themselves. Understanding these options can help save you time and effort during development. This chapter offers guidelines to help you create nib files that integrate well with your Xcode projects.
About Nib and Xib Files
Creating a Nib File
Saving Nib Files
Using Image and Sound Resources in a Nib File
Refactoring Your Nib Files
Files in the nib and xib formats play a very important role in the creation of applications. In their primary role, nib files simplify the code you have to write to create your application’s user interface. They provide a loadable set of objects that replace the code you would write to create windows, views, and other interface-related items. In some applications, nib files also provide a means to integrate these interface items with the existing objects in your application.
The nib and xib file formats themselves provide you with options for the development of your projects. Although they represent the same information, you use each type of file differently. The xib file format is preferred during development because it provides a SCM-friendly format, and because xib files can be compared with the diff command. At build time, Xcode automatically converts your project’s xib files to nib files so that they can be deployed with your application. If you have existing nib files, however, you can also continue saving to that same format.
Although the contents of a nib file can vary greatly in theory, in practice, there are usually a handful of standard configurations that developers include. The reason is that most developers use nib files for a very specific purpose: to load user interface items. This is particularly true for Carbon nib files, which can be used to store only user interface components, such as windows and menus. Nib files for other platforms offer more support for non interface components and for more complex configurations of your objects. For example, when you open a nib file for a Cocoa application, you might see any of the following items at the top level of the nib file:
Window resources
Menu resources (both menu bars and individual menus)
Views
Formatter objects
Controller objects (view controllers, array controllers, object controllers, and so on)
Core Data managed object contexts
Program-specific custom objects
Proxy objects, including File’s Owner
Some of these objects must be at the top level of the nib file. For example, windows and menus must always be at the top level of a nib file. In addition, controller objects are almost always at the top level. This is because controller objects cannot be embedded inside windows, views, or menus. (Cells and formatters are special because they work in conjunction with a view or control to implement its appearance.) Most other view-based objects are typically situated inside a window or view, although they can appear at the top level of the nib file as well.
The following guidelines can help you create nib files that achieve your application design goals quickly and efficiently.
Most new projects in Xcode come with one or two preconfigured nib files. A mistake made by many developers who are new to Interface Builder is to place all of their application’s windows and menus in these one or two nib files. The reason for the mistake is often convenience. (The template project usually loads the preconfigured nib files automatically, which saves the developer from having to add more nib-loading code.) Unfortunately, relying on this convenience can often lead to diminished performance and added memory pressure on your application.
When a nib file is loaded into memory, it is an all-or-nothing endeavor. The nib-loading code has no way of knowing how many objects are in the file or which ones are important, so the entire file must be loaded into memory. From this in-memory data, individual objects are then instantiated. For Cocoa and iPhone applications, all of the objects in the nib file are instantiated right away so that outlet and action connections can be reestablished. If your application uses only some of the nib-file objects initially, having all of the objects in memory is a waste.
For all projects, it is better to design each nib file so that it contains only those objects that are needed immediately in a given situation. When loaded into memory, such a nib file uses the smallest amount of memory possible while still having everything it needs to get the job done. Here are some design choices to consider when organizing your nib files:
For your application’s main nib file, include only your menu bar (or in the case of an iPhone application, just the main window).
For document nib files in Mac OS X, include only the document window and the objects (such as controllers) needed to display that window.
For other nib files, focus the nib file on a key object, such as a single window or panel that you intend to display. All other objects in the nib file should then facilitate the immediate operation of that window or panel.
For windows that change their embedded view hierarchies, if the hierarchy changes infrequently, consider storing any additional hierarchies in separate nib files. Load each view hierarchy only as it is used.
If you already have large nib files, you can use Interface Builder’s refactoring tools to break them into several smaller nib files. For information on how to use Interface Builder’s refactoring tools, see “Refactoring Your Nib Files.” For information about how to load nib files explicitly from your code, see Resource Programming Guide.
In Cocoa and Cocoa Touch nib files, the File’s Owner proxy object provides the key link between your application and the objects in the nib file. When you load the nib file, you must provide the nib-loading routine with a pointer to the object that should become the File’s Owner. As part of the loading process, the nib-loading code automatically recreates any connections between the object you specify and the nib file objects that have connections to the File’s Owner.
As you design the architecture of your application, it is important to consider which objects you want to manage your nib files. The presence of only one File’s Owner proxy object is not without good reason. It is usually best to have a single object coordinate the loading and management of a nib file and its contents. This single point of contact provides the desired barrier between your application’s data model and the visual elements used to present that data model and is at the heart of model-view-controller design.
Beyond the File’s Owner object, you can create additional controller objects directly in your nib file to manage subsets of the nib file. Using multiple controllers in this way lets you compartmentalize the window’s behavior into more manageable chunks. For example, if your window has multiple panes of disparate information, you could create separate controller objects to manage each pane. Each controller would continue to go through the File’s Owner to obtain additional information.
In iPhone applications, it is also possible to include proxy objects besides File’s Owner in your nib file. These additional proxy objects are almost always used to represent navigation controllers and other view controllers already in use by your application. The presence of these additional proxy objects does not diminish the role of File’s Owner though. The File’s Owner object is still responsible for coordinating the overall behavior of the nib file’s contents.
The objects at the top level of a nib file represent the main objects of interest to your application. Although technically you can place almost any object at the top level of a nib file, in most cases, doing so is rarely practical or necessary. Most applications use nib files to load a particular piece of the user interface, usually a window or menu. For Carbon applications, windows and menus are the only thing you can include at the top level of a nib file.
In addition to windows and menus, nib files for Cocoa and Cocoa Touch applications can include controller objects and formatters at the top level. Creating these objects from the nib file is often more convenient than creating them programmatically. And if their entire purpose is to manage the objects inside the nib file, it is also more practical to include them as part of the nib file.
The nib file format is the original file format supported by early versions of Interface Builder and is still used today as the format for object resources you load into your application at runtime. In Interface Builder 3.0, the nib file format was expanded to include some additional design-time information. This updated version of the nib format is still backwards compatible with the nib-loading infrastructure but is not compatible with older versions of Interface Builder. The xib file format was also introduced in Interface Builder 3.0 as a development-time format and was conceived as a way to provide tighter integration with your Xcode projects, particularly in the areas of SCM support, diff support, and refactoring. Xcode automatically converts files in the xib format to the nib format at build time.
The proliferation of file formats for Interface Builder documents means that you have to make some choices about which format to use for your own projects. Table 2-1 lists the guidelines you should follow for choosing an appropriate format. You only have to choose a particular format for Mac OS X applications. For iPhone applications, you must use the xib file format.
Development environment | Suggested format |
---|---|
If you are developing for iPhone OS or are editing and building solely in Mac OS X v10.5 or later… | Use the |
If you are editing solely in Mac OS X v10.5 but building in Mac OS X v10.4… | Use the 3.x |
If you are still editing and building in Mac OS X v10.4… | Use the 2.x |
Interface Builder 3.0 and later fully supports opening nib files created with Interface Builder 2.5.x and earlier; however, the reverse is not true. Attempting to open a version 3.x nib file in an older version of Interface Builder may generate errors or display the nib file’s contents incorrectly. If this happens, simply close the file and open it in Interface Builder 3.0. If you choose to save your nib files using the 2.x format and it includes items that are not compatible with earlier versions of Interface Builder, the Save panel displays a warning to that effect. You must remove the offending items before saving your nib file to the earlier format.
Because nib files can store user-visible strings, their contents must be localized along with the rest of your application during the localization process. Because nib files are external to your code, however, the localization process is straightforward. Like other resource types, you can store localized versions of your nib files in language-specific project directories of your application bundle.
For more information about the localization process for nib files, see “Localization.”
To create a nib file in Interface builder, choose File > New. Interface Builder displays the template chooser for creating your nib file. From this panel, you select the target platform and the starting template you want to use.
The starting templates simplify the nib creation process by providing you with preconfigured nib files that you would use in typical situations. The templates also provide you with objects that are configured correctly for on the target platform. Each application platform has subtle differences, both in what the nib file can contain and in the supported frameworks. For example, the Cocoa Touch platform supports classes from the UIKit framework while the Cocoa platform supports classes from the AppKit framework. The platform you choose therefore determines what content shows up in the library and inspectors.
The template chooser also includes nib templates for use with the IB SDK. These nib files are Cocoa nib files that you use to create Interface Builder plug-ins, which are add-on modules used to extend the set of objects in the library. For more information on how to create plug-ins, see Interface Builder Plug-In Programming Guide.
Note: For the Carbon and Cocoa platforms, the only way to include a menu bar resource in your nib file is to choose the appropriate template. The Application and Main Menu templates typically contain menu bar resources while other templates do not. Because menu bar resources are not included in the library, starting with these templates is your only option for creating one.
After creating a new nib file, the next step is to add your custom objects to it. For information about the objects you can include in nib files, see “Nib Objects.”
When you are ready to save your Interface Builder document, choose File > Save from the menu. For the iPhone OS platform, you must save your nib file using the xib file format. For the Mac OS X platform, you can save your document using any of the following file formats:
Development-time format (.xib
extension)
Deployment format version 3.x (.nib
extension)
Deployment format version 2.x (.nib
extension)
Depending on the situation and your needs, you may find yourself using one or more of these formats for a given project. For guidance on which format to choose for your project, see “Choosing the Best File Format” and the following sections.
The development-time nib file format is a text-based flat-file format introduced in Interface Builder 3.0. This format was added to make it easier to check nib files in and out of source-control systems. Files of this type have a .xib
extension and can be used only within the Xcode and Interface Builder environments. You cannot load .xib
files at runtime from your application code. Instead, when you build your Xcode project, Xcode compiles this format down into a deployable nib file and adds that file to your project bundle.
The development-time file format is the default file format for Interface Builder. You should use this format for any new (or existing) projects you are developing using Xcode 3.0 and Interface Builder 3.0 or later. To save a file using the development-time nib file format, do the following:
Choose File > Save (or File > Save As) to display the Save panel.
Select the XIB 3.x format from the File Type pop-up menu.
Click Save.
Important: Although it is a text-based format, you should never edit the development-time format by hand. The format represents a flattened archive of the nib file object graph. Even if you are cautious, making changes to one portion of this graph could cause unexpected changes to other portions.
The deployment formats provide compatibility with, and facilitate the direct modification of, existing nib files. You might use these formats when modifying a nib file for an existing application or if your nib files require backward compatibility with Interface Builder 2.5.x or earlier.
Interface Builder supports deployment formats in both 3.x and 2.x versions. The 3.x version is a more modern format supported by Interface Builder 3.0 and later. This format supports new objects that are available only in Interface Builder 3.0 and later. The 2.x file format creates a file that can be opened by any version of Interface Builder. For more information about the compatibility of the deployment formats, see “Choosing the Best File Format.”
Important: If you are developing applications using Xcode 3.0 or later, you should avoid using the deployment nib file formats during development. Instead, you should use the development-time nib file format and let Xcode create the appropriate deployment nib files for you. The development-time format makes it easier to integrate your nib file code with source-control systems and build scripts.
To save a file using one of the deployment nib file formats, do the following:
Choose File > Save (or File > Save As) to display the Save panel.
Select the NIB 3.x or NIB 2.x format from the File Type pop-up menu.
Click Save.
To view the image and sound resources contained in your Xcode project, use the media tab of the library window. This tab displays your Xcode project’s custom resources and some of the common resources available in the system. The contents of this tab are essentially read-only and intended as a way to browse your project resources without having to go back to Xcode.
Views that support image and sound resources usually provide a configurable attribute in their inspector window for selecting the appropriate file from the media browser. You can also integrate image and sound resources directly into your nib file using the following techniques.
Drag an image from the media browser and drop it onto a window to create an image view configured with that image.
Drag an image from the media browser and drop it onto a toolbar, button bar, or tab bar (depending on the platform) to create a new item for that view.
Drag an image from the media browser and drop it onto a control to assign that image to that control’s cell (where applicable).
Although you can reference image and sound resources from your nib file, those resources are still stored outside of the nib file itself. Interface Builder gets the list of available resources from the Xcode project associated with your nib file. Therefore, if you want to use image and sound resources in your nib files, add them to your Xcode project.
In addition to your project resources, the Cocoa and Cocoa Touch platforms make some standard system images available for applications to use. These images are displayed in the Media browser by default but you can also refer to these images by name. The reference documentation for the associated platform lists the constants containing the name strings you use to access them. In nearly all cases, the names used by Interface Builder are a shortened version of the constant name. For example, in Cocoa applications, Interface Builder uses the string “NSBonjour” to represent the image identified by the NSImageNameBonjour
constant. For a list of constants you can use in Cocoa applications, see NSImage Class Reference. For Cocoa Touch applications, these constants are spread across several classes in UIKit Framework Reference.
When in doubt about whether a control supports image or sound resources, check the inspector window. If a control includes an image or sound field as one of its attributes, then you can assign the appropriate resource to it. (For example, you can assign both an image and sound resource to a push button control in Cocoa.) In addition to typing the resource name in the appropriate field, the inspector window typically includes a drop-down list that includes the known resources from your Xcode project.
It is a common mistake for developers to use their application’s main nib file to store several unrelated windows and controller objects. A better design pattern is to use several smaller nib files, each containing only the objects and controllers needed to implement a single window or interface. Smaller nib files promote better efficiency and a smaller memory footprint for your application. If your application already has large nib files, however, breaking up those files by hand is difficult, tedious, and error-prone. To help with the process, Interface Builder provides a refactoring tool to do the job for you.
To use Interface Builder’s refactoring tool, open the nib file you want to refactor and choose File > Decompose Interface. Interface Builder iterates through the file’s contents to build a map of the object relationships in the nib file. The tool looks at connected outlets, actions, bindings, and at the window and view hierarchies. From that map, it then identifies distinct, unrelated groups of objects and creates new nib files for each distinct group. The command does not change the contents of your original nib file.
Note: Interface Builder’s refactoring support is also used by Xcode’s refactoring engine to propagate changes to your nib files during a refactoring session. For more information on refactoring your Xcode programs, see Xcode Refactoring Guide.
© 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-11-19)