To say that Cocoa has its own development environment wouldn’t quite be an accurate statement. For one thing, programmers can use Apple’s major development applications, Xcode and Interface Builder, to develop software for other Mac OS X application environments, such as Carbon. Moreover, it is possible to develop Cocoa applications without using Xcode and Interface Builder at all. For example, you could write code using a text editor such as Emacs, build the application from the command line using make files, and debug the application from the command line using the gdb debugger.
But Xcode and Interface Builder are the preferred applications to use for developing Cocoa software. Their origins coincide with the origins of Cocoa itself, and consequently there is a high degree of compatibility between tools and frameworks. Together, Xcode and Interface Builder make it extraordinarily easy to design, manage, build, and debug Cocoa software projects. There is also AppleScript Studio, which extends those capabilities to allow you to create both scriptable Cocoa applications and applications that use AppleScript to control other applications.
When you install the development tools and documentation, you may select the installation location. Traditionally that location has been /Developer, but it can be anywhere in the file system you wish. As a shorthand for designating this installation location, the documentation uses <Xcode>. Thus, the development applications are installed in <Xcode>/Applications.
Xcode
Interface Builder
AppleScript Studio
Instruments
Other Development Tools
Xcode is the engine that powers Apple’s integrated development environment (IDE) for Mac OS X. It is also an application that takes care of most project details from inception to deployment. It allows you to
Create and manage projects, including specifying target requirements, dependencies, and build configurations.
Write source code in editors with features such as syntax coloring and automatic indenting.
Navigate and search through the components of a project, including header files and documentation.
Build the project.
Debug the project in a graphical source-level debugger.
Xcode builds projects from source code written in C, C++, Objective-C, Objective-C++, and Java. It generates executables of all supported types on Mac OS X, including command-line tools, frameworks, plug-ins, kernel extensions, bundles, and applications. Xcode permits almost unlimited customization of build and debugging tools, executable packaging (including information property lists and localized bundles), build processes (including copy-file, script-file, and other build phases), and the user interface (including detached and multi-view code editors). It also supports several source-code management systems—namely CVS, Subversion and Perforce—allowing you to add files to a repository, commit changes, get updated versions, and compare versions.
Figure 1-4 shows an example of a project in Xcode.
Xcode is especially suited for Cocoa development. When you create a project, Xcode sets up your initial development environment using project templates corresponding to Cocoa project types: application, document-based application, Core Data application, tool, bundle, framework, and others. For compiling Cocoa software, Xcode uses the GNU C compiler (gcc), and for debugging that software, it uses the GNU source-level debugger (gdb). Both gcc and gdb have been used in Cocoa development since Cocoa was NeXTSTEP (see “A Bit of History”), and over the years have been refined, extended, and tuned to support the compilation and debugging of Cocoa binaries.
Xcode has many advanced features that make the work of programming much easier. It has a class-browsing feature that lets you view the classes of all imported Cocoa frameworks plus any of your custom classes in their inheritance relationships; from the class browser you can request documentation on any class. It also includes design tools, including one for designing the attributes and relationships of entities used in Core Data applications. Some notable features introduced in Xcode 3.0 are the following:
The Research Assistant is a utility window that displays abstracts, declarations, and other information about selected API symbols; it also contains links to related documentation and sample code.
Refactoring involves transformations that make code easier to understand and maintain without changing the behavior of the software. The Xcode refactoring transformations, which are accessed through a menu, make comprehensive project changes such as renaming methods, creating new superclasses, modernizing loops, and converting accessor methods to support properties (a feature of Objective-C 2.0—see “Declared Properties” for more information).
Snapshots are copies of your entire project saved on your filesystem, so that you can undo changes across several files in a project. You can take snapshots of your projects at appropriate times, such as when completing a successful build or refactoring your code. If after subsequently working on the project you decide against the changes you made, you can revert the project to the latest snapshot version.
The Binder is a convenient place to drop project files, non-project text files, or entire folders of frequently accessed information for quick reference and navigation.You can add, move, rename, and delete files and directories using the Binder, and you can double-click files in the Binder to edit them. You can also attach arbitrary shell commands to items in the Binder and have then run at specific times.
Debugging has been streamlined—now in Xcode there is no significant difference between running a program and debugging it. Build your executable and run it, and if you have breakpoints set, the program stops at that point in the code and displays the Debugger window. Also new are datatips, consolidation of logs into the Console log, and various user-interface enhancements.
The Documentation window now makes it easier than ever to find the API or conceptual information you require, at the right level of detail. It has been redesigned for improved searching and browsing, filtering results by language, document title as well as content, and technological area. It also supports multiple documentation sets that can be installed, browsed, and searched independently.
The text editor has been enhanced with new features, among them:
Inline code annotations for errors and warnings, with controllable visibility
Code folding, a feature that enables to hide and show methods and functions
Improvements to Code Sense completion
Improved syntax coloring
Xcode is well integrated with the other major development application, Interface Builder. See “Xcode Integration” for an overview.
Note: Briefly, an outlet is an archived connection between one object and another object (and is specified as an instance variable of one object). An action is a method invoked in an object (usually a custom object) called the target when another object such as a button or slider is manipulated; Interface Builder also archives the connection between the target and the other object (called a control). For more on outlets, targets, and actions, see “Outlets” and “The Target-Action Mechanism.”
Further Reading: The Xcode Quick Tour Guide gives an overview of Xcode and provides links to additional development-tools documentation.
The second major development application for Cocoa projects is Interface Builder. As its name suggests, Interface Builder is a graphical tool for creating user interfaces. Interface Builder has been around almost since the inception of Cocoa as NeXTSTEP. Since then, it has received widespread recognition as being one of the best applications of its kind. Not surprisingly, its integration with Cocoa is airtight. Moreover, you can also use it to create user interfaces for Carbon applications.
Interface Builder (version 3.0) is centered around four main design elements:
Nib files. A nib file is actually a file wrapper (an opaque directory) that contains the objects appearing on a user interface in an archived form. Essentially, this archive is an object graph that contains information on each object, including its size and location on the screen (if a window) or within a window. Nib files in Cocoa applications also include proxy references for custom classes and information on the connections between objects, including those made using the Cocoa bindings technology. When you create and save a user interface in Interface Builder, all information necessary to re-create the interface is stored in the nib file. A nib file can include image and sound files used in the interface.
Interface Builder stores a nib file in a localized directory inside a Cocoa project; when that project is built, the nib file is copied to a corresponding localized directory in the created bundle. (Thus nib files offer a way to easily localize user interfaces.) A Cocoa application by default—that is, as created by Xcode—has a main nib file, which it automatically loads and displays when it is launched. The main nib file contains the application’s main menu and perhaps one or more windows. Your application can load, upon demand, secondary nib files such as ones containing document and preference windows.
Interface Builder presents the contents of a nib file in a nib document window (also called a nib file window). The nib document window gives you access to the important objects in a nib file, especially top-level objects such as windows, menus, and controllers that have no parent in their object graph. It gives you three modes with which to view objects: icon mode, outline mode, and browser mode. Icon mode shows the top-level objects, and the other modes let you explore the view hierarchy behind top-level objects such as windows.
Figure 1-5 shows a nib file opened in Interface Builder and displayed in a nib document window, along with supporting windows.
Object library. The Library window of Interface Builder contains objects that you can place on a user interface. They range from typical UI objects—for example, windows, controls, menus, text views, and outline views—to controller objects, custom view objects, and framework-specific objects, such as the Image Kit browser view. The Library groups the objects by categories and lets you browse through them and search for specific objects. You create a user interface by dragging objects from the Library’s item pane onto appropriate surfaces, whether those surfaces be the screen, a window, a view of some sort, or the main menu. (Library objects don’t have to be visible themselves, but they should affect the interface in some way.) When an object is dragged from the Library, Interface Builder instantiates a default instance of that object; it is a real Cocoa object, and not some proxy object standing in for an instance that will be created at runtime. You can resize, configure, and connect the object to other objects using the Inspector window (or, simply, the inspector). If you wish, you can put your own custom objects in the Library by creating an Interface Builder plug-in (see Interface Builder Plug-In Programming Guide for details).
The Library window also includes a mode that displays the images and sounds that the nib file can use as resources; click the Media button to switch to this mode.
Inspector. Interface Builder has an Inspector window (or simply, the inspector) for objects on a user interface. The inspector has a number of selectable panes for setting the initial runtime configuration of objects (although size and some attributes can be set by direct manipulation). The inspector in Figure 1-5 shows the primary attributes for a text field; note that different collapsable slices of the pane reveal attributes at various levels of the inheritance hierarchy (text field, control, and view). In addition to primary attributes and size, the inspector features the following panes:
A pane for applying transparency, shadow effects, animations and other types of Core Image and Core Animation effects and filters
A pane for establishing bindings between objects
A pane for viewing outlet and action connections between objects and removing those connections
A pane for displaying and setting information about an object, including the assignment of a custom subclass
A pane for specifying information used by AppleScript Studio
You can select multiple objects in the user interface, view them in the inspector as an integrated whole, and modify common attributes at one go.
Connections panel . The connections panel is a context-sensitive display that shows the current outlet and action connections for a selected object and lets you manage those connections. To get the connections panel to appear, right-click on the target object (Control-click on single-button mice).
The presentation of connection information in the connections panel is multidimensional. It organizes the different kinds of connections that can be made for an object into one or more slices, including accessibility, outlets, received action messages, and sent action messages. If an outlet or action is currently connected, the connections panel displays the general type and title (if applicable) of the connected user-interface object and fills the circle next to this information. To break a connection, click the “x” just before the object type. To make a connection, click in a circle and drag a connection line until the object you want for that connection is outlined in the user interface.
For objects with ancestors up the class hierarchy, you can click a control in the upper-right corner of the connections panel to display a list of those ancestor objects. By selecting one of these related objects, you can display and manage its applicable connections. For example, if the connections panel is showing the connections for a text field, you could click the related-objects control and choose an ancestor to show connections for controls (NSControl objects) and connections for views (NSView objects).
Interface Builder uses momentary blue lines to show the compliance of each positioned object, when moved or resized, to the Aqua human interface guidelines. This compliance includes recommended size, alignment, and position relative to other objects on the user interface and to the boundaries of the window.
Further Reading: For further information on this user-interface development tool, see Interface Builder User Guide. In addition, “Nib Files” gives more information about nib files and their use in an application. Also refer to “Communicating With Objects” for overviews of outlets, the target-action mechanism, and the Cocoa bindings technology.
Because Interface Builder includes plug-ins for many Cocoa objects, it “knows” about the attributes of these framework objects and their possible bindings and outlet and action connections. However, by itself it cannot know about your custom classes. For that information, it must rely upon Xcode.
Most development projects for Mac OS X start in Xcode, specifically via the File > New Project menu command. When Xcode creates a project with a user interface, such as a Cocoa-application project, it includes at least one nib file. When you first open this nib file, Interface Builder makes a note of its relationship to your Xcode project in a local cache of project information. If you create a custom class in Xcode and then associate that class with an object in a nib file, Interface Builder automatically gets information about the class from Xcode and stores it in its cache. It thus knows about any outlets, actions, and bindable properties of your class. When you add, remove, or modify any outlets, actions, and properties of your class, Interface Builder detects those changes and updates its local cache accordingly.
An important aspect of Interface Builder–Xcode integration is that both an Xcode project and that project’s nib file must be opened at the same time for current changes to a custom class’s interface to be propagated to Interface Builder. In this case you don’t have to tell Interface Builder about your custom classes because it finds them automatically. However, if you edit a nib file without its corresponding Xcode project open, Interface Builder falls back on its local cache of information from the last time it communicated with your Xcode project.
The general sequence for creating a user interface in Interface Builder is straightforward.
Drag a window or panel object onto the screen (a panel is the same thing as a dialog or secondary window).
Where you drop the window or panel sets its initial runtime location. After that you can change the initial runtime location only through the Size pane of the inspector.You can drag the window or panel around the screen at any time to position it for connections or to get it out of the way.
Set the window’s initial runtime size and attributes.
Drag objects such as text fields, buttons, table views, and pop-up lists onto the window, or onto previously placed views.
Set the initial (or permanent) location, size, and attributes of these objects.
Define your application’s custom classes.
Create a header file in Xcode, add it to your project, and write an @interface block that defines a custom class, including its outlets, properties, and action methods. Then import the header file into Interface Builder by typing the name of your class in the Class field of the inspector’s Identity pane. From this point on, as long as the Xcode project and the nib file are both open, Interface Builder is informed of changes you make to the class definition. Otherwise, it gets the latest information about the class from its local cache.
Establish bindings or connections between objects. This can take one of two forms:
Save and test the interface.
Interface Builder has a feature that lets you test an interface (excluding custom behavior) at each stage of design.
For thorough descriptions of the steps of this procedure, see Interface Builder User Guide.
A defining feature of the Mac OS for years has been the capability for users to control applications with scripts written in the AppleScript language. Many users find this feature indispensable, for it allows them to string together complicated series of related operations involving multiple applications. AppleScript capabilities have been carried forward into Mac OS X. AppleScript Studio is a development technology for creating Cocoa applications that use AppleScript scripts to control complex user interfaces.
AppleScript Studio combines elements from AppleScript, Xcode, Interface Builder, and Cocoa to provide a sophisticated environment for creating AppleScript solutions. It allows you to build applications that can do the following:
Execute AppleScript scripts.
Control the user interface of the application.
Control scriptable applications or scriptable parts of the operating system.
Because AppleScript Studio integrates AppleScript with Xcode, Interface Builder, and Cocoa, scripters can take advantage of their particular strengths and capabilities. They can drag a rich set of user-interface objects off Interface Builder palettes and customize them to their liking. They get built-in support for the Aqua human interface guidelines. And they are able to build and maintain complex projects with multiple targets and build steps.
The development environment makes possible scripting capabilities that go well beyond those available in the Script Editor application traditionally used for creating AppleScript scripts. These include:
creation of arbitrarily large scripts
search and replace in scripts
single-step script debugging with variable execution
easy access to handlers and properties in scripts
a flexible dictionary viewer for working with application scripting terminologies
Further Reading: For more information, see the AppleScript Studio Programming Guide.
Instruments is an application introduced in Xcode 3.0 that lets you run multiple performance-testing tools simultaneously and view the results in a timeline-based graphical presentation. With an interface similar to those of video- and music-editing applications, Instruments lets you select just the instrumentation that you need to examine your application. It can show you CPU usage, disk reads and writes, memory statistics, thread activity, garbage collection, network statistics, directory and file usage, and other measurements—individually or in different combinations—in the form of graphs tied to time. This simultaneous presentation of instrumentation data helps you to discover the relationships between what is being measured. It also displays the specific data behind the graphs. With Instruments, you can scan back and forth through the data collected during a period of your application’s execution and see exactly what occurred, and when. And you can record user interactions in Instruments and replay them later. Instruments can also collect statistics on background processes as well as applications.
For some of its features, Instruments uses DTrace, an open-source monitoring utility that can probe almost any aspect of system performance. Dtrace comes with a large set of tools that cover most aspects of system performance, including both kernel and user code, with near-zero overhead.
Further Reading: See the Instruments User Guide for complete information about the Instruments application.
Although Xcode and Interface Builder are the major tools you use to develop Cocoa applications, there are dozens of other tools at your disposal. You might find many of these secondary applications and command-line tools helpful during some phase of application development.
This section reviews the secondary development applications and briefly discusses some of the command-line tools. However, the latter are so numerous that even a condensed summary of them is outside the scope of this document. Your best bet is to consult the manual pages (man pages) for the tools located in /usr/bin and /usr/sbin. To do this, either choose Help > Open man page in Xcode or type man followed by the name of the tool in a Terminal shell. There are also some Apple-developed command-line tools in <Xcode>/Tools.
Many applications are used in measuring and analyzing aspects of a program’s performance. They are located in <Xcode>/Applications/Performance Tools.
Shark is a performance-analysis application that creates a time-based profile of your program’s execution; over a given period it traces function calls and graphs memory allocations. You can use Shark to track information for a single program or for the entire system, including kernel components such as drivers and kernel extensions. Shark also monitors file-system calls, traces system calls and memory allocations, performs static analyses of your code, and gathers information about cache misses, page faults, and other system metrics. Shark supports the analysis of code written in C, Objective-C, C++, Java, and other languages.
Thread Viewer displays activity among a process’s threads. It shows time lines of activity on each thread, which is color-coded with the action. By clicking a time line, you can get a sample backtrace of activity at that point.
BigTop graphs performance trends over time, providing a real-time display of memory usage, page faults, CPU usage, and other data.
Spin Control automatically samples unresponsive applications. You leave Spin Control running in the background while you launch and test your applications. If applications become unresponsive to the point where the spinning cursor appears, Spin Control automatically samples your application to gather information about what your application was doing during that time.
MallocDebug shows all currently allocated blocks of memory in your program, organized by the call stack at the time of allocation. At a glance you can see how much allocated memory your application consumes, where that memory was allocated from, and which functions allocated large amounts of memory. MallocDebug can also find allocated memory that is not referenced elsewhere in the program, thus helping you find leaks and track down exactly where the memory was allocated.
QuartzDebug is a tool to help you debug how your application displays itself. It is especially useful for applications that do significant amounts of drawing and imaging. QuartzDebug has several debugging options, including the following:
Auto-flush drawing, which flushes the contents of graphics contexts after each drawing operation)
A mode that paints regions of the screen in yellow just before they’re updated
An option that takes a static snapshot of the system-wide window list, giving the owner of each window and how much memory each window consumes.
For performance analysis, you can also use command-line tools such as:
top, which shows a periodically sampled set of statistics on currently running processes
gprof, which produces an execution profile of a program
fs_usage, which displays file-system access statistics
Many other command-line tools for performance analysis are available.
Further Reading: For more on the performance tools and applications you can use in Cocoa application development, as well as information on concepts, techniques, guidelines, and strategy related to performance, see Performance Overview. Cocoa Performance Guidelines covers the performance guidelines for Cocoa.
You might find the following applications (also located in <Xcode>/Applications/Utilities) useful in Cocoa application development, testing, and deployment:
FileMerge visually “diffs” text files (such as source files, header files, and property lists) and offers selective merging capabilities.
Package Maker packages applications (and other types of software) for installation by the Installer application.
Property List Editor is an editor for creating and editing XML and old-style property lists.
Last updated: 2007-10-31