« How to Create, Load, and Use Multiple Nib Files

by H. Lally Singh

In Mac OS X, application management is a single drag & drop operation: drop the application into /Applications to install, and drop it into the Trash to uninstall. This simplicity and power is just the tip of the iceberg. What we're seeing is just one use of a more general facility
Cocoa calls bundles.

This article is about Nib files, and how
to use them in your applications. Nib files are just specialized bundles, so we'll talk about
bundles first.

You see, Bundles are cool.

// Bundles

A bundle is a directory containing code and resources. Applications, frameworks,
Interface Builder (IB) Interface Palettes, and Nibs are all bundle types. The
NSBundle Foundation
class, along with the
NSBundle Additions
found in Cocoa, allow you to easily access and load a bundle's contents.

Getting a reference for your application's NSBundle is easy:

NSBundle * b = [NSBundle mainBundle];

Getting a reference for a given bundle inside your application is equally easy:

pathForResource:ofType: finds a given resource inside the
receiving NSBundle's bundle directory, whether that resource is
represented on disk as a file or directory.

Also, you can load a bundle's Principal Class, which is typically the
first class listed in Project Builder(PB)'s "Files" tab for non-.app bundles. Say I had a
class called BundleClass, and I ran the following code (after
running all the code above):

Suffice it to say, NSBundle is cool, and is the basis
for applications, frameworks, Nibs, and a few other types of packaged data. There
are plenty of useful methods for dealing with NSBundles, so do yourself a favor and check out the documentation.

// Nibs: A Special Type of Bundle

Now we come to the meat of this article: Nib files. Nib files are bundles that contain
resources created by Interface Builder (IB). When you create a new Cocoa project, one
Nib, MainMenu.nib, is automatically created for you. In MainMenu.nib, you can
setup a menu bar (duh) and any additional windows, panels, or drawers you want.

Nibs contain
archivedinstances of all the
objects you built in IB. This includes
instances of NSMenu, NSWindow,
and any of your own classes you instanciate in IB. Once the Nib
is loaded, every instance archived within it is unarchived
into a running instance.

But, what do you do when you want a variable number of instances for a given
window or set of windows? For example, for the document window in MDI applications like
TextEdit? This is where we have to use more than one Nib file.

// Making a New Nib

Using a Nib is simple, in fact we all do it every time we make a new Cocoa application.
Using more than one Nib is almost as simple: just create
one with your original application in Project Builder (PB). Choose "Cocoa Document-based Application"
under File..New Project. Under the "Resources" group in your newly-created project,
you'll see MyDocument.nib. MyDocument.nib
is a Nib loaded for each individual document opened in the application.

The other way to add a Nib is just to create a new one in Interface Builder (IB) and add
it to your project. In IB, just hit File -> New -> Cocoa -> Empty, save it,
and add it to your project.

// Multiple Client Windows Made Easy

Now that you've got a bright shiny new Nib, it would probably help to be able to do
something with it. But how do you get references to all the stuff inside the
Nib once you load it? In your new Nib, you'll see an object instance called "File Owner." This
instance is there to hold a set of references for the newly created objects
unarchived from the Nib you just loaded. You can add outlets and actions to it like
any other object.

So, build your Nib like any other, and then connect everything you need externally accessible
to File Owner. You can also set File Owner's class to anything you want. You can leave it as
NSObject, set it to NSDocument like in
the MyDocument.nib created in Project Builder (PB), or make it your own class.
It's infinitely flexible, go have some fun with it.

So, all this talk and still no code? Here's how you load the Nib into your
application: