Until now, our focus has been the broad concepts of object-oriented programming and how Objective-C implements these concepts in the language. In this article, I want to get you started using the developer tools, with a bit of exposure to Project Builder, but more specifically Interface Builder. We will also create our first Cocoa application, which I think you will find to be quite rich in functionality despite its unique nature -- that is, it requires no coding on your part at all.
Project Builder and Interface Builder are the two developer tools for creating Mac OS X applications. Project Builder is Apple's integrated development environment (IDE) that allows you to edit, compile, and debug your application's source code. In addition to building the code, Project Builder helps you manage all the files that your application relies on.
Interface Builder, on the other hand, provides a set of tools that allow you to create a fully functional GUI in the true spirit of Macintosh by purely graphical means.
Rather than giving you a lengthy description of the developer tools, I want to present them to you as we create our application. So let's get started.
Apple's Project Builder IDE is akin to Codewarrior or to Microsoft's Visual Studio. It combines a source-code text editor, a front-end to the Objective-C compiler, and GNU debugger into an integrated interface for coding. Furthermore, Project Builder helps you organize and manage all the source files, frameworks, configuration files, and resources associated with your application. This collection of files is known as a "project."
Now that you've built a Cocoa app, do you have any observations to share with your fellow coders?
Included with Project Builder are several project templates for many standard types of applications and programs that range from device drivers and kernel extensions, to Cocoa, Carbon, and Java applications. Templates provide a skeletal set of files and resources common to all applications associated with the template. Additionally, any compilation and general configuration options are preset for the application. The type of application and project we're going to create today is a Cocoa document-based application.
Project Builder is found in the folder
/Developer/Applications. Once you have it started, we want to create a new project. Do this by selecting New Project from the File menu. Project Builder presents you with a list of all the possible project types; select Cocoa document-based application. Click Next. In the next screen you will be asked for a name to give your project and a place to keep it. You can put it wherever you like, but let's call it SimpleTextEditor. Click Finish, and the new project window will come up.
The project window has several elements. The pane on the left edge of the window is a list of folders (called "groups" by Project Builder because they do not represent real folders in the file system) that contain and organize all the various project files and resources. This is merely an organizational convenience, and since the groups do not reflect the organization of files in the file system, you are free to rearrange them to your heart's content without fear of Project Builder losing track of anything.
One thing to be careful about with this system has to do with deleting files from the Files and Groups list. You can delete files from the list by highlighting a file and clicking Delete. When you do this, you will see a dialog as illustrated below.
Unless you want your file to disappear from the disk, do not click the Delete button. Go with the default option; you'll be glad you did. I had this problem once or twice when I wasn't paying close attention to what was going on.
Associated with the Groups and Files list are several other tabbed views. The Bookmarks view holds placeholders for specific files or anything you want -- this is nice if you're working on a gargantuan application. I don't think we'll need that anytime soon. The Targets view allows you to set options that pertain to the compilation and execution process. Finally, Breakpoints refers to debugging breakpoints. A future column will be devoted to learning about the debugger.
The tabs running horizontally beneath the toolbar display status information returned by the compiler, runtime system, or debugger (Project Builder uses
gdb for compiling and debugging. For those of you who have experience with these GNU tools, these tabbed views display what you would see in a terminal with these tools.) Finally, the pane that dominates the Project Window is the text editor where you do most of your "coding."
I said in the beginning of the column that this application (as it is in this column) will require absolutely no coding on your part -- this is completely true. To see how this is true, let's go ahead and start with our application, a simple text editor. But first, a little background about how interfaces are built and stored in Cocoa.
Interface Builder does exactly what you would expect from its name -- it provides an easy way to build complex and functional user interfaces. Interface Builder provides prototypes of almost all controls and interface components -- buttons, windows, scroll bars, and sliders -- that are available in Application Kit.
Interfaces are built, then, by dragging these components onto a main window, and connecting them with Objective-C objects; these objects are the link between your code and your interface. To illustrate the process of creating an application interface, I will discuss some of the elements of Interface Builder (IB), and we will create your first application.
Cocoa handles interfaces through special files called NIB files, so named because of the file extension. These are the files that Interface Builder works with. A NIB file is basically an archive of every object that is part of you interface, with information about their attributes and connections between other objects. I mentioned previously that any object-oriented application is composed of a network of objects; NIB files are an archive of the object sub-network that deals with interfaces.
Every application with a graphical user interface has a main NIB file that is associated with the main window and main menu of that application. An application may also have any number of auxiliary NIB files. Usually, there is a NIB file associated with each unique window in an application. For example, a preference window would have a NIB file separate from the main NIB file.
Document-based applications such as the one we are creating have two NIB files initially. One archives the application-wide interface, which is usually just the menu bar at the top of the screen. The other NIB file keeps all the objects and information related to the document's interface, or rather the interface of the window in which your document's data is displayed. This interface may be nothing more than a scrollbar on the right side and a ruler across the top; nevertheless, it's an interface that users interact with and requires building.
(By the way, as a side note, the .nib extension is one of the relics of the NeXT operating systemm that lurk in Mac OS X that I spoke of in the first column -- NIB stands for NeXT Interface Builder. And while we're on the subject, you've probably wondered at some point or another why every Cocoa class name is preceded by an "NS-NS" which stands for NextStep. I just love this stuff!)
Also in Programming With Cocoa:
Going back to the Groups and Files list in Project Builder, open the group labeled Resources by clicking on the arrow to the left of it. Contained within this group are your application NIB interface files. All Cocoa-Document based applications have two of these initially,
MainMenu.nib is the application-wide NIB file, and
MyDocument.nib is the document-specific NIB file.
MainMenu.nib to open it in Interface Builder. In Interface Builder, you will see three windows. One is a your application's menu bar (the one that is in a floating window); another has several tabbed views that display all the objects archived by your NIB file. The third window contains what are known as palettes.
Palettes in Interface Builder are repositories of prototype object instances of the most commonly used Application Kit classes, grouped according by common function. It's possible to create your own palettes with custom controllers. The palettes used in interface builder are an excellent example of Cocoa's plug-in architecture, which we have spoken little about. Plug-ins that allow a user to add some custom functionality to an application are just one of the freebies in Cocoa.
Let's start by modifying out application's menu bar a bit. There is a palette that contains several standard, pre-built menus named Cocoa-Menus Palette. To add a new menu to the MainMenu, drag one of the prototype menus from the palette and position it where you like on your application's main menu. Menus can also be rearranged by dragging, and you can remove a menu by highlighting it and then hitting the delete key.
Save the NIB file in Interface Builder, close it, and return to Project Builder.
MyDocument.nib, and in Interface Builder, you will be presented with the same setup as before, except now there is a blank window rather than the floating MainMenu window. This window is the empty canvas for you to create your document's interface.
What you build here is what your document window's interface will look like at runtime. We're going to keep our document window simple with just a single interface component known as an
NSTextView, or more simply, a text view. The
NSTextView class is a front-end to and subclass of another class that deals with text,
NSText defines the fundamental functionality that Cocoa has for handling and working with large bodies of text;
NSTextView manages the way the user interacts with text data.
NSText let's you do things like programmatically control cutting and pasting, text selection. alignment, and attributes of the text-like color and font.
NSTextView, on the other hand, takes the primitive methods defined by NSText and create a more intuitive and rich interface to NSText's behaviors. I highly recommend that at some point to take the time and read the class references for the two classes. You can find them online at Application Kit Objective-C Reference, or through the Help Viewer by following the links to Cocoa Developer Documentation.
NSTextViews are created within an a scroll window, which is represented by the
NSScrollView class. What this does is give your text window the capability to scroll through large blocks of text that can't all fit in the window. Interface Builder puts these two classes together by default, so don't worry too much about
NSScrollView right now; I just wanted you to be aware of it.
NSTextView object is found in the Cocoa-Data Views palette. The
NSTextView is the largest of the three objects in this palette, and is nothing more than a blank space.
NSTextView object from the palette onto the window; anywhere will do. Once you place the NSTextView object into your main window, you can position it and resize it to your needs. The newest version of Interface Builder bundled with Mac OS X 10.0 adds a nifty feature where guidelines are displayed when object edges and corners come near sweetspots in the interface. These sweetspots correspond to object spacings and alignments that are standard in Aqua. This makes the task of creating consistent and well-designed user interfaces more manageable.
While we're here, let's modify a few things about the way our text view will act. Select the Text view and open the Inspector by choosing View Info in the Tools menu. The Info window should be labeled "NSTextView info"; if not, click on your text view again. An attributes info view should be displayed in the Inspector. If this is not shown, select it from the pull-down menu at the top of the window.
Now we want to enable the options for importing graphics and implementing undo services. The options are labeled "Graphics allowed" and "Undo allowed"; click the checkboxes so they are enabled.
Finally, select Size from the pop-up menu at the top of the Info window. This will allow us to set how the document window and text view will resize relative to each other when the entire window is resized. Click on the horizontal and vertical lines in the box within the window so that they look like springs. What this does is tell our application that when we resize the document window, the distance between the window border and the text view edges must always remain constant; the springs indicate that the size of the text view is free to resize so that this restriction can be accommodated.
The other option would be to change the lines connecting the text view edge to the window edge to springs (with the lines interior to the text view solid), which would cause the text view size to remain fixed when the window is resized, and the space between the two to freely change.
OK, so save the NIB file, and return to Project Builder where we will build and run our application, and with no coding, see all the free features provided by Cocoa.
Building and running an application are achieved by clicking on the hammer and monitor icons in the toolbar (you must wait for the application to finish compiling before you run it). Alternatively you can press command-R to accomplish both of these things.
When your application starts running, you will see a blank document window appear with the name of your document in the title, "untitled". Play around with the menus and take note of what commands are available. Spellcheck. Kerning. Ligature. Undo. And there are others....
You're probably a bit underwhelmed right now because you think that those menu items can't possibly do anything useful since you didn't write any code; they're just placeholders so you'll remember to implement them later. Think again. Type some text in the window and try them out, see what happens. Have some fun with it. Play with them all!
That's right, they all work! You get text and font styling, and even spellchecking and undo all for nothing! Remember when we enabled the "Graphics allowed" option in Interface Builder? Try dragging an image file -- any image file -- onto your window. It gets pasted in there! Are you impressed yet? This stuff is amazing!
This is the power of the Application Kit and Cocoa; you get all of this just because you had the good sense to own a Mac and try out Cocoa. And we're just scratching the surface of what's possible; this won't be the last time to see something like this. Congratulations! Welcome to the world of Cocoa!
So how is it that we get all this stuff for free? Let me explain. When we dragged that text window onto the main window of our application, we were creating an instance of the
NSTextView class in out application. Once we did that, we incorporated a wealth of code and functionality contained in
NSTextView and its parent class,
NSText. That is where the magic happens.
NSText is a great example of what I talked about in the first column -- Apple has put a lot of work into providing you with a rich set of tools to start out with so you don't have to reinvent the wheel. What
NSText provides is code that implements all the cool things we saw: kerning, font styling, spell checking, alignment, and rulers. All of this is programmed into the
NSText class, and we interact with it through instances of its subclass,
NSTextView. I encourage you to take a look through the class documentation for
NSTextView to gain a more detailed understanding of what's going on.
Unfortunately we can't get everything for free, but we're not doing so bad this far. You don't get to save your document yet, and open saved documents. However, it's not hard at all to add this, and the next column will focus on this.
Next time, we will take this application and add some code to it giving it some more functionality such as saving and opening files. We'll also learn more about document-based applications -- another wonderful freebie in Cocoa-as well as how to work with data.
See you in two weeks!
Michael Beam is a software engineer in the energy industry specializing in seismic application development on Linux with C++ and Qt. He lives in Houston, Texas with his wife and son.
Read more Programming With Cocoa columns.
Return to the Mac DevCenter.
Copyright © 2009 O'Reilly Media, Inc.