Getting started with Cocoa requires that quite a few concepts be presented at once. Since a book is a linear construction, we have had to make some choices as to what pieces to present first. In order to get your hands dirty using the tools, we chose to introduce Apple’s Development Tools first as a way to get you started in building your first Cocoa application. You’ll see some concepts here that will be glossed over. Don’t worry; we will revisit them as we go. For now, though, just go along for the ride and try not to pay too much attention to the details we’re saving for later.
When Apple released Mac OS X, they made a really great decision. They decided to provide their development tools to every Mac user for free. These tools allow development of Carbon- and Cocoa-based applications, system libraries, BSD command-line utilities, hardware device drivers, and even kernel extensions. We’ll be focusing on two of these tools to develop Cocoa-based applications throughout the book: Project Builder for editing, compiling, and debugging source code, and Interface Builder for laying out the graphical user interface (GUI) components for the application.
By default, the tools aren’t installed, as most users won’t use them and probably want the almost 500 MB of disk space for something else. But developers can easily find them and install them from a variety of sources. And, since they are free, any user who wants to try developing software can do so by investing only the time it takes to learn.
You can quickly check to see if you have the Developer Tools installed. If you have a /Developer/Applications folder on your hard drive, as shown in Figure 2-1, you are ready to go. If not, you’ll need to install the tools from either the Developer Tools CD that came with your copy of Mac OS X or from a disk image you can download from the Apple Developer Connection (ADC) site.
A CD containing the Developer Tools comes with every boxed set of Mac OS X (including Mac OS X Server). To install the tools, simply find the CD (it’s the gray one), put it into your CD-ROM drive, and double-click the Developer.mpkg file that appears in a Finder window, as shown in Figure 2-2.
If you can’t find your Developer Tools CD, or if you received a Mac OS X upgrade package that didn’t include it, you will need to go to the ADC member web site at http://connect.apple.com and download a disk image.
To download the tools, log in to the ADC Member web site, click on Download Software in the navigation bar, then click on the Mac OS X subcategory link that appears. From this page you can download the Developer Tools either in segments or in one big chunk. If you download the Tools in segments, simply double-click on the first segment. Stuff-It will launch and put all the segments together into one file.
Membership in the Apple Developer Connection has its privileges. There are many levels of membership available. The free online membership gets you a good range of benefits, including access to the latest version of the Developer Tools and the ability to track bugs that you submit. You can register, free of charge, for online membership at http://connect.apple.com.
Apple provides regular updates to the Developer Tools through the ADC Member web site. These updates, which have been appearing at a rate of two to three times a year, introduce new features, fix bugs, and improve the available documentation. The only downside is that updates can be rather large. For example, the Developer Tools release that came with Jaguar weighed in at 285 MB. Despite the size, you should budget some time to download and use the latest versions from the ADC web site.
Because of the large size, updates to the Developer Tools are not available through Mac OS X’s Software Update tool (part of the System Preferences pane). You should be aware of this if you’re thinking that you can use Software Update as a way to ensure that you have the latest set of Tools.
If you don’t have a high-speed connection, you can get Apple to send you the latest copy of the Developer Tools CD at a nominal charge. Log in to the ADC member web site, and go to the Purchase section.
Project Builder is the hub application of Apple’s Developer Tools. It manages software-development projects and orchestrates and streamlines the development process. Project Builder’s key features include the following:
A project browser that manages all the resources of a project, allowing you to view, edit, and organize your source files.
The ability to invoke the build system to build your projects and run the resulting program.
A graphical source-level debugger that allows you to walk through the code, set breakpoints, and examine call stacks.
A code editor that supports language-aware keyword highlighting, delimiter checking, and automatic indentation for many languages, including C, Objective-C, C++, Java, and AppleScript.
Project search capabilities that allow you to find strings anywhere in a project.
Source control management integration using the Concurrent Version System (CVS). CVS enables development teams (local or distributed) to work together easily on the same source code base.
Project Builder’s main window is shown in Figure 2-3.
To introduce you to Project Builder and to tip our hat to almost every introductory tutorial ever written on programming, we are going to build a very simple working program that prints “Hello, World!” Building and running this program will also verify that you have a working development environment.
Before you can start building applications with Project Builder, you will need to launch the application.
Find Project Builder in /Developer/Applications.
Double-click the icon.
If this is the first time that you have started Project Builder, you will be presented with an Assistant to set up your application preferences.
Click Next on the Assistant’s welcome page.
Choose where the components of your programs will be placed when they are built. We recommend that you go with the default, although you can change this at any time via Project Builder’s preferences. Click Next to move on.
Next, you’ll be presented with a Window Environment configuration option, as shown in Figure 2-4. This configuration sets how Project Builder’s interface is presented to you. Choose between having everything in one window and having everything occupy its own window.
The figures in this book use the Single Window environment, because this is the environment that we personally use. If you have used another IDE, such as CodeWarrior, that uses many windows and are comfortable with that approach, you may want to select one of the other two options.
When you have finished the first-time configuration, Project Builder displays the Release Notes for the particular version you are using. Important information often shows up in these release notes. After the first time you run Project Builder, you can access this information using the Help → Show Release Notes menu.
To create the “Hello, World” project, select File → New Project. Project Builder then displays the New Project Assistant, shown in Figure 2-5, which takes you through a few simple steps to create a new project.
The New Project Assistant lets you choose a project type. Based on the type of project you select, your Project will be created with files that serve as a useful starting point. When you select a type of application here, Project Builder creates it for you with a skeleton of the files that you will need for that particular application type. The application types are as follows:
Starting points for creating Cocoa applications (Objective-C- and Java-based), as well as Carbon- and AppleScript-based applications
Starting points for creating bundles that link against the Cocoa, Carbon, or Core Foundation frameworks
Starting points for creating frameworks that link against either Cocoa or Carbon
Starting points for developing Java applets or applications using either the AWT or Swing APIs
Starting points for developing both generic kernel extensions and IOKit drivers
Starting points for developing palettes for Interface Builder, preference panes for the System Preferences application, and screen savers
Starting points for creating command-line applications that link against the Core Foundation, Cocoa Foundation, or Core Services frameworks
Throughout this book, we focus almost exclusively on two categories of applications: simple tools with no GUI (called Foundation Tools) and applications with GUI windows. For this example, we will build a simple tool that doesn’t have a graphical interface. Proceed as follows:
Scroll down to the list of Tool choices, and select Foundation Tool from the list, as shown in Figure 2-5, and click Next.
The Assistant gives you an opportunity to name your new project and choose a location in the filesystem in which to save it. Type hello in the Project Name field, as shown in Figure 2-6.
If you Tab to the location field, you will see that Project Builder gives you the option of saving the project in ~/hello. This will create a new directory in your home directory named “hello”. However, for the purpose of working through the examples in this book, we recommend that you change this to ~/LearningCocoa /hello. That way, all of the projects you create with this book can be saved in the ~/LearningCocoa directory.
Click Finish.
When you finish creating the project, the main project window opens, as shown in Figure 2-7.
Notice that Project Builder uses hierarchical groups to organize the various parts of a project. In this project, these groups are the following:
This group
contains main.m, the file that contains the
main
function that is the entry point for your
application.
This group contains a prototype Unix manpage for the program.[7]
This group contains references to the frameworks that the application imports to gain access to system services.
This group contains the results of project builds and is automatically populated with references to the products created by each target in the project.
These groups are very flexible in that they do not necessarily reflect either the on-disk layout of the project or the manner in which the build system handles the files. Their sole purpose is to help you organize the files in your project. The default groups created for you by the templates can be used as they are or rearranged however you like.
To see the source code for the application’s entry point as shown in Figure 2-7:
The main.m file contains the entry point for the application. The Foundation Tool project template provides a standard main function that prints “Hello, World!”, so we don’t even need to add any code.
import <Foundation/Foundation.h> // 1 int main (int argc, const char * argv) { // 2 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // 3 // insert code here... NSLog(@"Hello, World!"); // 4 [pool release]; // 5 return 0; // 6 }
Now let’s walk through the code, line-by-line, so you can get a feeling for what’s going on here:
Imports the Foundation framework. This directive is similar to
#include
, except that it won’t
include the same file more than once.
Declares the standard C main
function for a
program. This function is where execution starts when the program is
started.
The NSAutoreleasePool
is one of
Cocoa’s memory-management tools.
We’ll cover more about how memory management works
in Chapter 4.
The NSLog
function works very much like
printf
in the C language. The difference is
that NSLog
takes an NSString
object instead of a C string. The @" . . . "
construct is a compiler directive that creates an
NSString
object using the characters between the
quotation marks.
This line contains another part of Cocoa’s memory housekeeping that we will explain in depth later.
A return from the main
function indicating a
normal program exit.
To build the project, click the Build button in the main window. It’s the one that looks like a hammer on the far left side of the toolbar. A dialog box will appear, asking you to “Save before building?” Click Save All, or hit Return, to save and build the project. As the project builds, Project Builder’s build pane opens to reveal detailed information about the build as it progresses. When Project Builder is finished—and encounters no errors along the way—it displays “Build succeeded” in the lower-left corner of the project window, as shown in Figure 2-8.
The code for this program should compile without a
problem,
since Project Builder generated it. However, when you write code
yourself, you won’t always be so lucky. To see how
Project Builder notifies you of build problems,
let’s create one. Remove the semicolon right after
the NSLog(@"Hello, World!")
statement; then try
building the project. You’ll see a build failure
notice, as shown in Figure 2-9.
Project Builder tells you that there was a syntax and parse error. To see where the error is, click on the syntax error message, and Project Builder highlights the line about which the compiler is complaining. Unfortunately, the compiler is not smart enough to figure out that we don’t have a semicolon in the right place; it just notices that it has run across some syntax that it did not expect. This is typical with syntax errors. If you don’t see the problem at first, look at the line of code above the reported line.
Add the missing semicolon back in after the NSLog
function, and recompile by clicking the Build button to get a
working program again.
Congratulations!
You’ve just created your first Cocoa application and
didn’t even have to type in any code. All that is
left to do is click the Build and Run button, as shown
in Figure 2-10. When the application launches, the
Run pane of Project Builder’s main window will
enlarge to display the output of the
NSLog
function.
Since building and running is a straightforward process, in future chapters we don’t tell you how to “build and run” your application—we just say “build and run your application.”
In addition to the string, the NSLog
function
prints the current
date and time, the
program name, and the
process ID number (PID) of the program.
Since this is a tool application with no GUI, you might want to see
the behavior of this program on the command line.
When the program is run, you should see something similar to the following output:
2002-06-08 23:23:29.919 hello[490] Hello, World!
The
timestamp and
process ID information come in handy
when you are looking for the output from a program that was launched
from the Finder, but not from inside of Project Builder or from the
command line. In those cases, the output from
NSLog
will show up in the
system’s message log. You can easily view these
messages using the Console application, also found in the
/Applications/Utilities folder.
If you have spaces in the folder in which you saved your program, the Terminal shell will complain. The reason is that spaces are used to separate the arguments in a shell command and must be escaped. If you saved your project into a ~/Learning Cocoa directory (notice the space), your command would need to look like this:
[localhost:~] duncan% Learning Cocoa/hello/build/hello
The backslash in front of the space tells the shell that the space is part of the path of the program.
Project Builder provides an easy-to-use interface to the system’s debugger that lets you step through code line-by-line, set breakpoints (places to pause the execution of the program), and view variables and threads. The following steps allow you explore the debugger.
Set a breakpoint in your code by clicking into the left margin of the
code editor near the main
method declaration, as
shown in Figure 2-11. Notice that where you click, a
marker appears.
Now click the Build and Debug button. This will
start the debugger and then load the hello
program
into it. Execution will stop at the first statement after the
breakpoint. In this case, it will stop at the first line of our main
method, as shown in Figure 2-12.
Notice that Project Builder shows both a thread stack viewer and
a variable viewer. The thread stack
viewer shows execution stack. The main method is at the top of the
stack, indicating that this is the method within which execution is
stopped. The variable viewer gives the values of all the arguments
and variables that are applicable in the function. Notice the value
of the pool
variable.
Click once on the Step over Function button (called out
in Figure 2-12). Note that the current execution
highlighter moves to the next valid line of code. Also notice that
the value of the pool
variable is highlighted in
red. This means that the pool
variable was just
set. The value is actually a pointer to the contents of the object in
memory.
Click the Step over Function button once again.
The NSLog
function was called. To see the output,
click the Console tab above the variable
viewer, as shown in Figure 2-13. Also notice tht the
value of the pool
variable is no longer red. This
highlighting lasts only one step after the contents of a variable
change.
Click the Continue execution button to let the program execute as normal. You can click the Restart button (called out in Figure 2-12) to restart the program at the beginning of execution.
Click the Stop button in the toolbar to exit the debugger.
Now that we have explored how to say “Hello, World!” to the console, let’s take a look at building a GUI application that says hello in a much different way.
Interface Builder is where you create the graphical user interfaces (GUIs) for your applications. Instead of typing code by hand to lay out the interface components, you drag objects from palettes and drop them onto the GUI you are creating. Objects can be connected to one another and with instances of classes that you provide as part of your application.
Interface Builder generates nib [8] files that are an archive of object instances and are packaged up with your built application. Unlike the product of many user interface-building systems, nib files are not generated code—they are true archived (also known as “freeze-dried”) objects consisting of related user interface objects and supporting resources, along with information about how the objects are related. The objects in the nib file are created and manipulated using Interface Builder’s graphical tools.
Interface Builder’s standard palettes hold an assortment of AppKit components. Other palettes can include Cocoa objects from other frameworks, third-party objects, and custom-compiled objects.
To introduce you to Interface Builder, we are going to create a program that says “Hello, World” in a window on the screen instead of as a text message in a Terminal window. To begin, we need to make a new project of a type different than our previous Hello World application. Choose New Project from the File menu. Project Builder then displays the New Project Assistant. This time, create a project of type Cocoa Application, as shown in Figure 2-14.
This will create a project that is set up as a simple Cocoa application. Go ahead and create the project, giving it the name Hello World and saving into your ~/LearningCocoa folder. When you have created the project, you will see a window similar to that shown in Figure 2-15.
The Cocoa Application project type uses a different set of groups to organize projects than those used in the Foundation Tool example. The groups in this project type are as follows:
This group is empty at first, but is used to hold the implementation (.m ) and header (.h) files for your project’s classes.
This group contains main.m , the file containing the main function that loads the initial set of resources and runs the application. In Cocoa applications with graphical interfaces, you typically don’t have to modify this file.
This group contains the nib files and other resources that specify the application’s GUI.
This group contains references to the Frameworks (Foundation and AppKit) that the application imports to gain access to system services.
To see what Project Builder provides for you by default, go ahead and build and run the project. A blank window should appear once Project Builder is done compiling everything. Play with this window a little bit, and you’ll notice that you can resize, minimize, and maximize it.
Now, to finish our application, we should make it say “Hello, World” to us!
To begin constructing a user interface using Interface Builder, the first step is to open the application’s main nib file. Double-click MainMenu.nib in the Resources group of the Groups & Files list of Project Builder’s main window. This will launch Interface Builder (if it is not already running) and open the nib file, as shown in Figure 2-16. A lot of windows will appear. You might want to hide your other running applications so that you can concentrate on just the windows that belong to Interface Builder. You can do this by using the Interface Builder → Hide Others menu.
These are the various parts of Interface Builder (called out in Figure 2-16):
This window is where the various objects that are part of your nib file are defined and manipulated. We’ll explain more about the various parts of this window in Chapter 5.
This window contains all the controls that you can add to an interface. We’ll explore many of these controls throughout the book.
The menu-bar window contains the menu bar that will be active when your application is running.
This is the window that will be displayed when your application is run. Notice that it is the same size and in the same location on screen as when you Built and Ran the application.
Interface Builder stores all kinds of information about user-interface objects in an application’s nib files. For example, you can set both the size and initial location of an application’s main window by simply resizing and moving the window in Interface Builder.
Move the window near the upper-left corner of the screen by dragging the titlebar.
Make the window smaller by using the resize control at the bottom-right corner of the window.
To create our application, we need to add a text label to the window.
Select the Cocoa-Views by clicking the second button from the left top of the Cocoa objects palette window, as shown in Figure 2-17. If you don’t see the Cocoa palette window for some reason, select Palettes from the Tools menu to bring it forward.
Drag a System Font Text label from the palette onto the window.
Double-click on the new label and change the text to “Hello World”.
Resize the interface window to a smaller size, and move the text label to the center of the window. You should have something that looks similar to Figure 2-18.
Next, save your interface, as we are now done with Interface Builder. Some people refer to saving the interface as “freeze-drying” it. All the various parts of the interface—definitions about how they are related and connected—are saved in a form that can be quickly built up at runtime. This process is also called " archiving” or "serialization.”
To see the application in action:
Return to Project Builder.
Click the Build and Run button.
When the application runs, it opens up a window containing the Hello World text. Note that you can resize the window (although the text doesn’t stay centered, we’ll learn how to do that in later chapters), minimize it, maximize it, and close it. You can even quit the application using the menu or the standard
-Qkeyboard shortcut. All of this functionality is simply “built-in” to Cocoa, allowing you to spend more time writing your applications and less time taking care of details you shouldn’t have to.
In addition to Project Builder and Interface Builder, there are other applications that you can use in the Cocoa development process. Development tools that feature a GUI are listed in Table 2-1. Except where noted, these applications are installed in the /Developer/Applications folder.
Name |
Description |
FileMerge |
Visually compares the contents of two files or two directories. You can use FileMerge to determine the differences between versions of the same source-code file or between two project directories. You can also use it to merge changes. |
icns Browser |
Displays the entire contents of Mac OS X icon files. |
IconComposer |
Creates Mac OS X icons from source art. |
IORegistryExplorer |
Provides a hierarchical display of the system I/O registry. |
MallocDebug |
Measures the dynamic-memory usage of applications, finds memory leaks, analyzes all allocated memory in an application, and measures the memory allocated since a given time. |
ObjectAlloc |
Tracks and displays all Cocoa and Core Foundation object allocations for a running application. ObjectAlloc allows you to view the list of objects, as well as the call stack that resulted in each allocation. |
PackageMaker |
Creates Mac OS X installer packages. |
Pixie |
Magnifies the screen area under the cursor, allowing you to see the exact pixels comprising any onscreen object. Magnification is adjustable from 1 to 12 times normal. |
Property List Editor |
Opens, displays, and/or modifies the contents of a property list (.plist) file. |
Quartz Debug |
Displays a list of all windows known to the system. This program allows you to turn on a Quartz debugging mode that flashes yellow over areas of the screen as the window server updates them. |
Sampler |
Analyzes performance characteristics of your application by sampling the call stack of your program over a user-specified period of time. |
Thread Viewer |
Allows you to browse the high-level thread behavior of an application. |
There are several command-line tools for compilation, debugging, performance analysis, and so on, installed as part of the Developer Tools package. Many of these tools are ports of standard Unix applications with which you may have prior experience. These tools, listed in Table 2-2, can be found in the /usr/bin directory.
Although the Mac OS X development environment contains many tools, the tutorials in this book focus almost exclusively on the use of Project Builder and Interface Builder. Some tools, such as the compiler, debugger, and linker, are usually invoked indirectly through Project Builder when building a project. Others, such as ObjectAlloc, Quartz Debug, and Sampler, are extremely useful to gain a deeper understanding of an application’s inner workings. Feel free to experiment with them at any point while working through the tutorials in this book.
Locate the Project Builder and Interface Builder applications, and put them into the Dock.
Locate the developer documentation, and place a shortcut to it in your Dock or in your browser.
Watch the “Accessing API Documentation in Project Builder” movie at http://developer.apple.com/techpubs/macosx/DeveloperTools/ProjectBuilderAccess/index.html.
[7] Manpages are the standard form of Unix
documentation for command line utilities and are written as plain
text files with nroff macros. See
http://www.opensource.apple.com/projects/documentation/howto/html/man_page_HOWTO.html for more information.
[8] The name “nib” is an acronym for "NeXT Interface Builder,” yet another vestige of Mac OS X’s heritage.