Learning Cocoa with Objective-C/Cocoa Overview and Foundation/Cocoa Development Tools

From WikiContent

Jump to: navigation, search
Learning Cocoa with Objective-C

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.

Contents

Installing the Developer Tools

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.

Figure 2-1. Apple's development tools in the filesystem

Apple's development tools in the filesystem

Installing from the Developer Tools CD

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.

Figure 2-2. The Developer Tools installation file

The Developer Tools installation file

Installing from the ADC Site

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.

Tip

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.

Upgrading Your Tools

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.

Note

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

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.

Figure 2-3. Project Builder's main window

Project Builder's main window

Say "Hello, World"

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.

Open Project Builder

Before you can start building applications with Project Builder, you will need to launch the application.

  1. Find Project Builder in /Developer/Applications.
  2. 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.

  1. Click Next on the Assistant's welcome page.
  2. 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.
  3. 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.

    Figure 2-4. Window Environment configuration

    Window Environment configuration

    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.

  4. 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.

Creating a new project

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.

Figure 2-5. Project Builder's New Project Assistant

Project Builder's    New Project Assistant

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:

Application
Starting points for creating Cocoa applications (Objective-C- and Java-based), as well as Carbon- and AppleScript-based applications
Bundle
Starting points for creating bundles that link against the Cocoa, Carbon, or Core Foundation frameworks
Framework
Starting points for creating frameworks that link against either Cocoa or Carbon
Java
Starting points for developing Java applets or applications using either the AWT or Swing APIs
Kernel Extension
Starting points for developing both generic kernel extensions and IOKit drivers
Standard Apple Plug-ins
Starting points for developing palettes for Interface Builder, preference panes for the System Preferences application, and screen savers
Tool
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:

  1. Scroll down to the list of Tool choices, and select Foundation Tool from the list, as shown in Figure 2-5, and click Next.
  2. 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.
  3. 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.
  4. Click Finish.

Figure 2-6. Naming a Project Builder project

Naming a Project Builder project

When you finish creating the project, the main project window opens, as shown in Figure 2-7.

Figure 2-7. Project Builder's main window

Project Builder's main window

Notice that Project Builder uses hierarchical groups to organize the various parts of a project. In this project, these groups are the following:

Source
This group contains main.m, the file that contains the main function that is the entry point for your application.
Documentation
This group contains a prototype Unix manpage for the program.[1]
External frameworks and libraries
This group contains references to the frameworks that the application imports to gain access to system services.
Products
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:

  1. In the Groups & Files list of Project Builder's main window, click the disclosure triangle to the left of the Source group.
  2. Click on the icon for the main.m file. You will see the contents of the file in the code editor.

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:

  1. Imports the Foundation framework. This directive is similar to #include, except that it won't include the same file more than once.
  2. Declares the standard C main function for a program. This function is where execution starts when the program is started.
  3. The NSAutoreleasePool is one of Cocoa's memory-management tools. We'll cover more about how memory management works in Chapter 4.
  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.
  5. This line contains another part of Cocoa's memory housekeeping that we will explain in depth later.
  6. A return from the main function indicating a normal program exit.

Tip

Why does NSLog have the NS prefix? Simple: NS stands for NeXTSTEP. All of the classes and functions in the Cocoa frameworks start with NS to help protect the namespace in which all functions and classes exist from collisions. The continued use of NS is a vestige that shows Cocoa's heritage.

Building the project

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.

Figure 2-8. Project Builder after successfully building the project

Project Builder after successfully building the project

Tip

If you don't want Project Builder to question you to save files each time you try to buid a project, you can change this option in Project Builder's Preferences. Select Project Builder → Preferences → Building, and then select Always Save from the pul-down menu next to Unsaved files.

Solving build problems

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.

Figure 2-9. Build failed

Build failed

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.

Running the application

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.

Tip

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."

Figure 2-10. Project Builder's main window after running Hello World

Project Builder's main window after running Hello World

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.

  1. Open up a Terminal window, found in the /Applications/Utilities folder.

    Tip

    As with Project Builder, you may want to add the Terminal application to your Dock for easy access, if you haven't already done so.

  2. The hello executable is built into a subdirectory of your project. To run it, enter the following into the Terminal window:
    [localhost:~] duncan% LearningCocoa/hello/build/hello
                            
    

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.

Warning

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.

Using the Debugger

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.

  1. 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.

    Figure 2-11. Setting a breakpoint

    Setting a breakpoint

  2. 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.

    Figure 2-12. The debugger in action

    The debugger in action

    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.

  3. 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.
  4. 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.

    Figure 2-13. Console output in the debugger

    Console output in the debugger

  5. 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.
  6. 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

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 [2] 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 nibfile 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.

Graphical "Hello, World"

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.

Figure 2-14. Creating a Cocoa application

Creating a Cocoa application

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 Worldand saving into your~/LearningCocoa folder. When you have created the project, you will see a window similar to that shown in Figure 2-15.

Figure 2-15. Hello World application in Project Builder

Hello World application in Project Builder

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:

Classes
This group is empty at first, but is used to hold the implementation (.m ) and header (.h) files for your project's classes.
Other Sources
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.
Resources
This group contains the nib files and other resources that specify the application's GUI.
Frameworks
This group contains references to the Frameworks (Foundation and AppKit) that the application imports to gain access to system services.
Products
This group contains the results of project builds.

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!

Open the main nib file

To begin constructing a user interface using Interface Builder, the first step is to open the application's main nibfile. Double-click MainMenu.nibin 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 nibfile, 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):

Figure 2-16. Interface Builder

Interface Builder

Nib file window
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.
Control palette window
This window contains all the controls that you can add to an interface. We'll explore many of these controls throughout the book.
Menu bar
The menu-bar window contains the menu bar that will be active when your application is running.
Empty interface window
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.

  1. Move the window near the upper-left corner of the screen by dragging the titlebar.
  2. 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.

  1. 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.

    Figure 2-17. The Cocoa-Views palette

    The Cocoa-Views palette

  2. Drag a System Font Text label from the palette onto the window.
  3. Double-click on the new label and change the text to "Hello World".
  4. 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.

Figure 2-18. Our finished Hello World interface

Our finished Hello World interface

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:

  1. Return to Project Builder.
  2. 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 [[Image:Learning Cocoa with Objective-C_I_2_tt34.png|]]-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.

Other Tools

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.

Table 2-1. Other development tools

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.

Command-Line Tools

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/bindirectory.

Table 2-2. Command-line development tools

Name/command Description
cc, gcc
The GNU C compiler (gcc). Compiles C, Objective-C, C++, and Objective-C++ source-code files.
gdb
A source-level symbolic debugger for C extended to support Objective-C, C++, and Objective-C++.
as
Assembles; translates assembly code into object code.
defaults
Reads, writes, searches, and deletes user defaults. The defaults system records user preferences that persist when the application isn't running.
nibtool
Reads the contents of an Interface Builder nib file. The nibtool prints classes, the object hierarchy, objects, connections, and localizable strings.
libtool
Creates static or dynamic libraries from specified object binary files.
otool
Displays specified parts of object files or libraries.
nm
Displays the symbol table, in whole or part, of the specified object files.
pbxbuild
Allows Project Builder projects to be built from the command line
fixPrecomps
Creates or refreshes a precompiled header file for each of the major frameworks.
strip
Removes or modifies the symbol table that is attached to assembled and linked output.
cvs
CVS allows teams composed of multiple members to coordinate their work on a common codebase.
sample
Gathers the running behavior of a process and produces a report showing what functions were executed during the run of an application.
leaks
Examines a process for malloc-allocated buffers that are not referenced by the program.


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.

Exercises

  1. Locate the Project Builder and Interface Builder applications, and put them into the Dock.
  2. Locate the developer documentation, and place a shortcut to it in your Dock or in your browser.
  3. Watch the "Accessing API Documentation in Project Builder" movie at http://developer.apple.com/techpubs/macosx/DeveloperTools/ProjectBuilderAccess/index.html.

Notes

  1. 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.
  2. The name "nib" is an acronym for "NeXT Interface Builder," yet another vestige of Mac OS X's heritage.
Personal tools