Cocoa is an application environment for both the Mac OS X operating system and iPhone OS, the operating system used on multi-touch devices such as iPhone and iPod touch. It consists of a suite of object-oriented software libraries, a runtime, and an integrated development environment.
This chapter expands on this definition, describing the purpose, capabilities, and components of Cocoa on both platforms. Reading this functional description of Cocoa is an essential first step toward understanding Cocoa as a developer.
The Cocoa Environment
Features of a Cocoa Application
The Development Environment
The Cocoa Frameworks
A Bit of History
Cocoa is a set of object-oriented frameworks that provides a runtime environment for applications running on Mac OS X and iPhone OS. It is also part of a development environment that helps you efficiently bring these applications from design stage to deployment. Cocoa is the preeminent application environment for Mac OS X and the only application environment for iPhone OS. (Carbon is an alternative environment on Mac OS X, but it is a compatibility framework with procedural programmatic interface intended to support existing Mac OS X code bases.) Most of the applications you see on Mac OS X and iPhone OS, including Mail and Safari, are Cocoa applications. An integrated development environment called Xcode supports application development for both platforms. The combination of this development environment and Cocoa makes it easy to create a well-factored, full-featured application.
As with all application environments, Cocoa presents two faces; it has a runtime aspect and a development aspect. In its runtime aspect, Cocoa applications present the user interface and are tightly integrated with the other visible portions of the operating system; on Mac OS X, these include the Finder, the Dock, and other applications from all environments.
But it is the development aspect that is the more interesting one to programmers. Cocoa is an integrated suite of object-oriented software components—classes—that enables you to rapidly create robust, full-featured Mac OS X applications. These classes are reusable and adaptable software building blocks; you can use them as-is or extend them for your specific requirements. Cocoa classes exist for just about every conceivable development necessity, from user-interface objects to data formatting, and where a need hasn’t been anticipated, you can easily create a subclass of an existing class that answers that need.
Cocoa has one of the most distinguished pedigrees of any object-oriented development environment. From its introduction as NeXTSTEP in 1989 to the present day, it has been continually refined and tested (see “A Bit of History”). Its elegant and powerful design is ideally suited for the rapid development of software of all kinds, not only applications but command-line tools, plug-ins, and various types of bundles. Cocoa gives your application much of its behavior and appearance “for free,” freeing up more of your time to work on those features that are distinctive. (For details on what Cocoa offers, see “Features of a Cocoa Application.”)
iPhone OS Note: Cocoa for iPhone OS supports only application development and not any other kind of executable.
You may use several programming languages when developing Cocoa software, but the essential, required language is Objective-C. Objective-C is a superset of ANSI C that has been extended with certain syntactical and semantic features (derived from Smalltalk) to support object-oriented programming. The few added conventions are simple and easy to learn and use. Because Objective-C rests on a foundation of ANSI C, you can freely intermix straight C code with Objective-C code. Moreover, your code can call functions defined in non-Cocoa programmatic interfaces, such as the BSD library interfaces in /usr/include
. You can even mix C++ code with your Cocoa code and link them into the same executable.
Mac OS X Note: On Mac OS X, you can also program in Cocoa using scripting bridges such as PyObjC (the Python–Objective-C bridge) and RubyCocoa (the Ruby–Cocoa bridge). Both bridged languages let you write Cocoa applications in the respective scripting languages, Python and Ruby. Both of these are interpreted, interactive, and object-oriented programming languages that make it possible for Python or Ruby objects to message Objective-C objects as if they're Python or Ruby objects, and also for Objective-C objects to message Python or Ruby objects. For more information, see Ruby and Python Programming Topics for Mac OS X.
The core Cocoa class libraries come packaged in two core frameworks for each platform: Foundation and Application Kit for Mac OS X and Foundation and UIKit for iPhone OS. As with all frameworks, these contain not only a dynamically sharable library (or sometimes several compatibility versions of libraries), but header files, API documentation, and related resources. The duo of both Application Kit and Foundation and UIKit and Foundation reflect the division of the Cocoa programmatic interfaces into those classes that have some bearing on a graphical user interface and those that don’t. For each platform, its two core frameworks are essential to any Cocoa project whose end product is an application.
Mac OS X also ships with several other frameworks that publish Cocoa programmatic interfaces, such as the Core Data framework, the Screen Saver and Address Book frameworks; more Cocoa frameworks will be added to the operating system over time. See “The Cocoa Frameworks” for further information.
Figure 1-1 shows a simplified diagram of the Mac OS X system architecture.
This diagram is simple for a purpose: to depict unambiguously to those unfamiliar with Mac OS X some of its major components and dependencies. But in its simplicity it omits important details and blurs others. These details fill in an important part of the picture showing how Cocoa fits into the rest of Mac OS X.
Figure 1-2 situates Cocoa more accurately in an architectural setting. This diagram shows Mac OS X as a series of software layers going from the foundation of Darwin to the various application environments; the intervening layers represent the system software contained in the two major umbrella frameworks, Core Services and Application Services. The diagram suggests that a component at one layer generally has dependencies on the layer beneath it.
In some ways, this diagram is similar to the previous diagram. For example, the system component that is largely responsible for rendering the Aqua user interface, Quartz (implemented in the Core Graphics framework), is part of the Application Services layer. And at the base of the architectural stack is Darwin; everything in Mac OS X, including Cocoa, ultimately depends on Darwin to function.
But if you look closer, at individual or groups of Cocoa classes and at the particular subframeworks of the umbrella frameworks, you begin to see where Cocoa either has specific dependencies on other parts of Mac OS X or where it exposes underlying technology with its interfaces. Figure 1-3 charts a few of these dependencies or exposures.
Apple has carefully designed Cocoa so that some of its programmatic interfaces give access to the capabilities of underlying technologies that applications typically need. But if you require some capability that is not exposed through the programmatic interfaces of Cocoa, or if you need some finer control of what happens in your application, you may be able to use an underlying framework directly. (A prime example is Core Graphics; by calling its functions or those of OpenGL, your code can draw more complex and nuanced images than is possible with the Cocoa drawing methods.) Fortunately, using these lower-level frameworks is not a problem because the programmatic interfaces of most dependent frameworks are written in standard ANSI C, of which Objective-C language is a superset.
Note: The intent of this architectural overview is not to itemize every particular dependency or interface that Cocoa has on or to other parts of Mac OS X. Instead, it surveys the more interesting ones in order to give you a general idea of the architectural context of the framework.
The major underlying frameworks on which Cocoa depends or which it exposes through its classes and methods are Core Foundation, Carbon, Core Graphics (Quartz), Launch Services, and Print Core (the printing subsystem):
Core Foundation. Many classes of the Foundation framework are based on equivalent Core Foundation opaque types. This close relationship is what makes “toll-free bridging”—cast-conversion between compatible Core Foundation and Foundation types—possible. Some of the implementation of Core Foundation, in turn, is based on the BSD part of the Darwin layer.
Carbon. Cocoa taps into Carbon for some of the services it provides. This is because various Carbon frameworks are situated as system-wide services in the Core Services and Application Services layer. Carbon Core is a particularly important one of these frameworks; for example, it has the File Manager, which Cocoa uses for conversions between various file-system representations.
Core Graphics. The Cocoa drawing and imaging classes are (quite naturally) closely based on the Core Graphics framework, which implements Quartz and the window server.
Launch Services. The NSWorkspace class exposes the underlying capabilities of Launch Services. Cocoa also uses the application-registration feature of Launch Services to get the icons associated with applications and documents.
Print Core. The Cocoa printing classes present an object-oriented interface to the printing subsystem.
Further Reading: Mac OS X Technology Overview gives an overview of the frameworks, services, technologies, and other components of Mac OS X. Apple Human Interface Guidelines specifies how the Aqua human interface should appear and behave.
Although the iPhone OS infrastructure on which Cocoa depends is similar to that for Mac OS X, there are some significant differences. Compare Figure 1-4, which depicts the architectural setting of iPhone OS, to the diagram in Figure 1-2. The iPhone OS diagram also shows the software supporting its platform as a series of layers going from a Core OS foundation to a set of application frameworks, the most critical (for applications) being the UIKit framework. As in the Mac OS X diagram, the iPhone OS diagram has middle layers consisting of core-services frameworks and graphics and audio frameworks and libraries. Here also, a component at one layer often has dependencies on the layer beneath it.
Generally, the system libraries and frameworks of iPhone OS that ultimately support UIKit are a subset of the libraries and frameworks on Mac OS X. For example, there is no Carbon application environment on iPhone OS, there is no command-line access (the BSD environment), there are no printing frameworks and services, and QuickTime is absent from the platform. However, because of the nature of the devices supported by iPhone OS, there are some frameworks, both public and private, that are specific to iPhone OS.
The following summarizes some of the frameworks found at each layer of the iPhone OS stack, starting from the foundation layer.
Core OS—This level contains the kernel, the file system, networking infrastructure, security, power management, and a number of device drivers. It also has the libSystem library, which supports the POSIX/BSD 4.4/C99 API specifications and includes system-level APIs for many services.
Core Services—The frameworks in this layer provide core services, such as string manipulation, collection management, networking, URL utilities, contact management, and preferences.
This layer includes Core Foundation, a framework that provides abstractions for common data types (such as strings and collections); they allow a large degree of integration between object-oriented and procedural code.
Media—The frameworks and services in this layer depend on the Core Services layer and provide graphical and multimedia services to the Cocoa Touch layer. They include Core Graphics, OpenGL ES, Core Animation, Core Audio, and video playback.
Cocoa Touch—The frameworks in this layer directly support applications based on iPhone OS. They include two Objective-C frameworks that are particularly important for developing applications for iPhone OS:
The UIKit framework provides the objects an application displays in its user interface and defines the structure for application behavior, including event handling and drawing. For a description of UIKit, see “UIKit (iPhone OS).”
The Foundation framework defines the basic behavior of objects, establishes mechanisms for their management, and provides objects for primitive data types, collections, and operating-system services. Foundation is essentially an object-oriented cover to the Core Foundation framework; see “Foundation” for a discussion of the Foundation framework.
Note: For detailed descriptions of the components in the layers of iPhone OS, see iPhone OS Technology Overview.
As with Cocoa on Mac OS X, the programmatic interfaces of Cocoa on iPhone OS give your applications access to the capabilities of underlying technologies. Usually there will be a Foundation or UIKit method or function that can tap into a lower-level framework to do what you want. But, as with Cocoa on Mac OS X, if you require some capability that is not exposed through API, or if you need some finer control of what happens in your application, you may choose to use an underlying framework directly. For example, UIKit uses the Web Kit to draw text; however, you may decide to use Core Graphics to draw text because that gives you the control you need for a particular task. Again, using these lower-level frameworks is not a problem because the programmatic interfaces of most dependent frameworks are written in standard ANSI C, of which Objective-C language is a superset.
Further Reading: To learn more about the frameworks, services, and other aspects of the iPhone OS platform, see iPhone OS Technology Overview.
On Mac OS X it is possible to create a Cocoa application without adding a single line of code. Make a new Cocoa application project using Xcode and then build the project. That’s it. Of course, this application won’t do much, or at least much that’s interesting. But this extremely simple application still launches when double-clicked, displays its icon in the Dock, displays its main menu and window (entitled “Window”), hides itself on command, behaves nicely with other running applications, and quits on command. You can move, resize, minimize, and close the window. You can even print the emptiness contained by the window.
Imagine what you could do with a little code.
iPhone OS Note: The features and behavior of an application running on iPhone OS are considerably different from a Mac OS X application, largely because it runs in a more constrained environment. For discussions of application capabilities and constraints on iPhone OS, see iPhone Application Programming Guide.
In terms of programming effort, Cocoa gives you, the developer, much that is free and much that is low-cost. Of course, to become a productive Cocoa developer means becoming familiar with possibly new concepts, design patterns, programming interfaces, and development tools, and this effort is not negligible. But familiarity yields greater productivity. Programming becomes largely an exercise in assembling the programmatic components that Cocoa provides along with the custom objects and code that define your program’s particular logic, then fitting the whole assemblage together.
What follows is a short list of how Cocoa adds value to an application with only a little (and sometimes no) effort on your part:
Basic application framework—Cocoa provides the infrastructure for event-driven behavior and for application-, window-, and (in the case of Mac OS X) workspace-management. In most cases, you won’t have to handle events directly or send any drawing commands to a rendering library.
User-interface objects—Cocoa offers a rich collection of ready-made objects for your application’s user interface. Most of these objects are available on palettes of Interface Builder, a development application for creating user interfaces; you simply drag an object from a palette onto the surface of your interface, configure its attributes, and connect it to other objects. (And, of course, you can always instantiate, configure, and connect these objects programmatically.) Here is a sampling of Cocoa user-interface objects:
windows | text fields | image views | date pickers |
sheets and dialogs | segmented controls | table views | progress indicators |
buttons | sliders | radio buttons (Mac OS X) | color wells (Mac OS X) |
drawers (Mac OS X) | page controls (iPhone OS) | navigation bars (iPhone OS) | switch controls (iPhone OS) |
Cocoa on Mac OS X also features technologies that support user interfaces, including those that promote accessibility, perform validation, and facilitate the connections between objects in the user interface and custom objects.
Drawing and imaging—Cocoa enables efficient drawing of custom views with a framework for locking graphical focus and marking views (or portions of views) as “dirty.” On Mac OS X, it includes programmatic tools for drawing Bezier paths, performing affine transforms, compositing images, and creating various representations of images.
System interaction—On Mac OS X, Cocoa gives your application ways to interact with (and use the services of) the file system, the workspace, and other applications. On iPhone OS, you can pass system applications URLs to have them handle the referenced resource (for example, email or websites).
Performance—To enhance the performance of your application, Cocoa provides programmatic support for multithreading, idle-time processing, lazy loading of resources, memory management, and run-loop manipulation.
Internationalization—Cocoa provides a rich architecture for internationalizing applications, making it possible for you to support localized resources such as text, images, and even user interfaces. The Cocoa approach is based on users’ lists of preferred languages and puts localized resources in bundles of the application. Based on the settings it finds, Cocoa automatically selects the localized resource that best matches the user’s preferences. It also provides tools and programmatic interfaces for generating and accessing localized strings. Moreover, text manipulation in Cocoa is based on Unicode by default, and is thus an asset for internationalization.
Text—On Mac OS X, Cocoa provides a sophisticated text system that allows you to do things with text ranging from the simple (for example, displaying a text view with editable text) to the more complex, such as control of kerning and ligatures, spell checking, and embedding images. On iPhone OS, Cocoa has no native text system (it uses Web Kit for string drawing) and text capabilities are more limited.
Preferences—The user defaults system is based on a system-wide database in which you can store global and application-specific preferences. The procedure for specifying application preferences is different on the two platforms.
Networking—Cocoa also offers programmatic interfaces for communicating with servers using standard Internet protocols, communicating via sockets, and incorporating Bonjour capabilities in your application.
On Mac OS X, Cocoa includes a distributed objects architecture that allows one Cocoa process to communicate with another process on the same computer or on a different one.
Cocoa on Mac OS X has several other additional features:
Data exchange—Cocoa simplifies the exchange of data within an application and between applications using the copy-paste and drag-and-drop models and through the Services menu.
Document-based applications—Cocoa specifies an architecture for applications composed of a potentially unlimited number of documents, with each contained in its own window (a word processor, for example). Indeed, if you choose the “Document-based application” project type, many of the components of this sort of application are created for you.
Scripting— Through application scriptability information and a suite of supporting Cocoa classes, you can make your application scriptable; that is, it can respond to commands emitted by AppleScript scripts. Applications can also execute scripts or use individual Apple events to send commands to, and receive data from, other applications. As a result, every scriptable application can supply services to both users and other applications.
Undo management—You can register user actions that occur with an undo manager, and it will take care of undoing them (and redoing them) when users choose the appropriate menu items. The manager maintains undo and redo operations on separate stacks.
Printing—In a fashion similar to the text system, the printing architecture lets you print documents and other application content along a range of control and sophistication. At the simplest level, you can print the contents of any view by default. At a more complicated level, you can define the content and format of printed content, control how a print job is performed, and add an accessory view to the print panel.
Multimedia—On Mac OS X, Cocoa provides support for QuickTime video and basic audio capabilities.
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 Mac OS X applications based on 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.
Note: "Xcode” is sometimes used to refer to the complete suite of development tools and frameworks, and other times specifically to the IDE application that allows you to manage projects and build executable code.
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.
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
.
Beginning with Xcode 3.1 and the introduction of iPhone OS, when you create a software project you must choose a platform SDK. The SDK enables you to build an executable that is targeted for a particular release of a particular operating system, or platform: Mac OS X or iPhone OS.
The platform SDK contains everything that is required for developing software for a given platform and operating-system release. A Mac OS X SDK consists of frameworks, libraries, header files, and system tools. The SDK for iPhone OS has the same components, but includes a platform-specific compiler and other tools. There is also a separate SDK for the Simulator environment for iPhone OS (see “The iPhone OS Simulator”). All SDKs include build settings and project templates appropriate to their platform.
Further reading: For more on platform SDKs, see Xcode Overview.
Application development differs for Mac OS X and iPhone OS, not only the tools used but in the development workflow. On Mac OS X, the typical development workflow is the following:
In Xcode, create a project using a template from the Mac OS X SDK.
Write code and, using Interface Builder, construct your application’s user interface.
Define the targets and executable environment for your project.
Test and debug the application using the Xcode debugging facilities.
As part of debugging, you can check the system logs in the Console window.
Measure application performance using one or more of the available performance tools.
For iPhone OS development, the workflow when developing an application is a bit more complex. Before you can develop for iPhone OS, you must register as a developer for the platform. Thereafter, building an application that’s ready to deploy should go through the following steps:
Configure the remote device. This results in the required tools, frameworks, and other components being installed on the device.
In Xcode, create a project using a template from the iPhone OS SDK.
Write code, and construct your application’s user interface.
Define the targets and executable environment for the project.
Build the application (locally).
Test and debug the application, either in the iPhone OS Simulator or remotely in the device. (If remotely, your debug executable is downloaded to the device.)
As you debug, you can check the system logs for the device in the Console window.
Measure application performance using one or more of the available performance tools.
Xcode is the engine that powers Apple’s integrated development environment (IDE) for Mac OS X and iPhone OS. 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 platforms, 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 locally, in the iPhone OS simulator, or remotely, in a graphical source-level debugger.
Xcode builds projects from source code written in C, C++, Objective-C, and Objective-C++. It generates executables of all supported types on Mac OS X, including command-line tools, frameworks, plug-ins, kernel extensions, bundles, and applications. (For iPhone OS, only application executables are possible.) 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-5 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 for Mac OS X, 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 is well integrated with the other major development application, Interface Builder. See “Interface Builder” (below) for details.
Further Reading: Xcode Overview 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. Not surprisingly, its integration with Cocoa is airtight. Moreover, you can also use it to create user interfaces for Carbon applications running on Mac OS X.
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 connections between objects, and on proxy references for custom classes. 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.
Nib files offer a way to easily localize user interfaces. 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.
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 controller objects that have no parent in their object graph. (Controller objects mediate between user-interface objects and the model objects that represent application data; they also provide overall management for an application.)
Figure 1-6 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. When an object is dragged from the Library onto an interface, Interface Builder instantiates a default instance of that object; You can resize, configure, and connect the object to other objects using the Inspector window (or, simply, the inspector).
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-6 shows the primary attributes for a text field; note that different collapsible 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 panes for animation effects, AppleScript event handlers, and bindings and target-action connections between objects
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). Figure 1-7 shows what the connections panel looks like.
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.
Interface Builder is tightly integrated with Xcode. It “knows” about the outlets, actions, and bindable properties of your custom classes. When you add, remove, or modify any of these things, Interface Builder detects those changes and updates its presentation of them.
Further Reading: For further information on Interface Builder, 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.
For iPhone OS projects, you can select the iPhone OS Simulator as the platform SDK for the project. When you build and run the project, Xcode runs the Simulator, which presents your application as it would appear on the device and allows you to manipulate parts of the user interface. You can use the Simulator to help you debug the application prior to loading it onto the device.
You should always perform the final phase of debugging on the device. The Simulator does not perfectly simulate the device. For example, you must use the mouse pointer instead of finger touches, and so manipulations of the interface required multiple fingers are not possible. In addition, the Simulator does not use versions of the OpenGL framework that are specific to iPhone OS, and it uses the Mac OS X versions of the Foundation, Core Foundation, and CFNetwork frameworks, as well as the Mac OS X version of libSystem.
More importantly, you should not assume that the performance of your application on the Simulator is the same as it would be on the device. The Simulator is essentially running your iPhone application as a "guest” Mac OS X application. As such, it has a 4GB memory partition and swap space available to it as it runs on a processor that is more powerful than the one on the device.
Although Xcode and Interface Builder are the major tools you use to develop Cocoa applications, there are dozens of other applications at your disposal. Many of these tools are performance applications.
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. 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.
Further Reading: See the Instruments User Guide for complete information about the Instruments application.
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, which on Mac OS X includes 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++, and other languages.
Many applications are used in measuring and analyzing aspects of a Mac OS X program’s performance. They are located in <Xcode>/Applications/Performance Tools
.
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 and other development tasks are available. Some are located in /usr/bin
and /usr/sbin
, and some Apple-developed command-line tools are installed in <Xcode>/Tools
. For many of these tools you can consult their manual page for usage information. (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.)
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.
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.
What makes a program a Cocoa program? It’s not really the language, because you can use a variety of languages in Cocoa development. It’s not the development tools, because you could create a Cocoa application from the command line (although that would be a complex, time-consuming task). No, what all Cocoa programs have in common—what makes them distinctive—is that they are composed of objects that inherit ultimately from the root class, NSObject
, and that are ultimately based upon the Objective-C runtime. This statement is also true of all Cocoa frameworks.
Note: That statement also needs to be qualified a bit. First, the Foundation framework supplies another root class, NSProxy
; however, NSProxy
is rarely used in Cocoa programming. Second, you could create your own root class, but this would be a lot of work (entailing the writing of code that interacts with the Objective-C runtime) and probably not worth your time.
On any system there are many Cocoa frameworks, and Apple and third-party vendors are releasing more frameworks all the time. Despite this abundance of Cocoa frameworks, two of them stand out on each platform as core frameworks:
On Mac OS X: Foundation and Application Kit
On iPhone OS: Foundation and UIKit
The Foundation, Application Kit, and UIKit frameworks are essential to Cocoa application development, and all other frameworks are secondary and elective. You cannot develop a Cocoa application for Mac OS X unless you link against (and use the classes of) the Application Kit, and you cannot develop a Cocoa application for iPhone OS unless you link against (and use the classes of) UIKit. Moreover, you cannot develop Cocoa software of any kind unless you link against and use the classes of the Foundation framework. (Linking against the right frameworks on Mac OS X happens automatically when you link against the Cocoa umbrella framework.) Classes, functions, data types, and constants in Foundation and the Application Kit have a prefix of “NS”; classes, functions, data types, and constants in UIKit have a prefix of “UI”.
Note: In Mac OS X version 10.5 the Cocoa frameworks have been ported to support 64-bit addressing. iPhone OS also supports 64-bit addressing. As part of this effort, various general changes have been made to the Cocoa API, most significantly the introduction of the NSInteger
and NSUInteger
types (replacing int
and unsigned int
where appropriate) and the CGFloat
type (replacing most instances of float
). Most Cocoa applications have no immediate need to make the transition to 64-bit, but for those that do, porting tools and guidelines are available. 64-Bit Transition Guide for Cocoa discusses these matters in detail.
The Cocoa frameworks handle many low-level tasks for you. For example, classes that store and manipulate integer and floating-point values automatically handle the endianness of those values for you.
The following sections survey the features and classes of the three core Cocoa frameworks and briefly describe some of the secondary frameworks. To make these large frameworks more approachable, the introductions to the Foundation, Application Kit, and UIKit frameworks break down the dozens of classes in each hierarchy into functional groupings. Although these groupings have a strong logical basis, one can plausibly group classes in other ways.
The Foundation framework defines a base layer of classes that can be used for any type of Cocoa program. The criterion separating the classes in Foundation from those in the Application Kit is the user interface. If an object doesn’t either appear in a user interface or isn’t exclusively used to support a user interface, then its class belongs in Foundation. You can create Cocoa programs that use Foundation and no other framework; examples of these are command-line tools and Internet servers.
The Foundation framework was designed with certain goals in mind:
Define basic object behavior and introduce consistent conventions for such things as memory management, object mutability, and notifications.
Support internationalization and localization with (among other things) bundle technology and Unicode strings.
Support object persistence.
Support object distribution.
Provide some measure of operating-system independence to support portability.
Provide object wrappers or equivalents for programmatic primitives, such as numeric values, strings, and collections. Also include utility classes for accessing underlying system entities and services, such as ports, threads, and file systems.
Cocoa applications, which by definition link either against the Application Kit or the UIKit frameworks, invariably must link against the Foundation framework as well. The class hierarchies share the same root class, NSObject
, and many if not most of the Application Kit and UIKit methods and functions have Foundation objects as parameters or return values. Some Foundation classes may seem designed for applications—NSUndoManager
and NSUserDefaults
, to name two—but they are included in Foundation because there can be uses for them that do not involve a user interface.
Foundation introduces several paradigms and policies to Cocoa programming to ensure consistent behavior and expectations among the objects of a program in certain situations. These include:
Object retention and object disposal. The Objective-C runtime and Foundation give Cocoa programs two ways to ensure that objects persist when they’re needed and are freed when they are no longer needed. Garbage collection, which was introduced in Objective-C 2.0, automatically tracks and disposes of objects that your program no longer needs, thus freeing up memory. Foundation also still offers the traditional approach of memory management. It institutes a policy of object ownership that specifies that objects are responsible for releasing other objects that they have created, copied, or explicitly retained. NSObject
(class and protocol) defines methods for retaining and releasing objects. Autorelease pools (defined in the NSAutoreleasePool
class) implement a delayed-release mechanism and enable Cocoa programs to have a consistent convention for returning objects for which the caller is not responsible. For more about garbage collection and explicit memory management, see “Object Retention and Disposal.”
Mutable class variants. Many value and container classes in Foundation have a mutable variant of an immutable class, with the mutable class always being a subclass of the immutable one. If you need to dynamically change the encapsulated value or membership of such an object, you create an instance of the mutable class. Because it inherits from the immutable class, you can pass the mutable instance in methods that take the immutable type. For more on object mutability, see “Object Mutability.”
Class clusters. A class cluster is an abstract class and a set of private concrete subclasses for which the abstract class acts as an umbrella interface. Depending on the context (particularly the method you use to create an object), an instance of the appropriate optimized class is returned to you. NSString
and NSMutableString
, for example, act as brokers for instances of various private subclasses optimized for different kinds of storage needs. Over the years the set of concrete classes has changed several times without breaking applications. For more on class clusters, see “Class Clusters.”
Notifications. Notification is a major design pattern in Cocoa. It is based on a broadcast mechanism that allows objects (called observers) to be kept informed of what another object is doing or is encountering in the way of user or system events. The object originating the notification can be unaware of the existence or identity of the observers of the notification. There are several types of notifications: synchronous, asynchronous, and distributed. The Foundation notification mechanism is implemented by the NSNotification
, NSNotificationCenter
, NSNotificationQueue
, and NSDistributedNotificationCenter
classes. For more on notifications, see “Notifications.”
The Foundation class hierarchy is rooted in the NSObject
class, which (along with the NSObject
and NSCopying
protocols) define basic object attributes and behavior. For further information on NSObject
and basic object behavior, see “The Root Class.”
The remainder of the Foundation framework consists of several related groups of classes as well as a few individual classes. There are classes representing basic data types such as strings and byte arrays, collection classes for storing other objects, classes representing system information such as dates, and classes representing system entities such as ports, threads, and processes. The class hierarchy charts in Figure 1-9 (for printing purposes, in three parts) depict the logical groups these classes form as well as their inheritance relationships. Classes in blue-shaded areas are present in both the Mac OS X and iPhone OS versions of Foundation; classes in gray-shaded areas are present only in the Mac OS X version.
These diagrams logically group the classes of the Foundation framework in the following categories (with other associations pointed out):
Value objects. Value objects encapsulate data of various types, giving access to the data and offering various manipulations of it. Because they are objects, they (and their contained values) can be archived and distributed. NSData
provides object-oriented storage for streams of bytes whereas NSValue
and NSNumber
provide object-oriented storage for arrays of simple scalar values. The NSDate
, NSCalendarDate
, NSTimeZone
, NSCalendar
, NSDateComponents
, and NSLocale
classes provide objects that represent times, dates, calendar, and locales. They offer methods for calculating date and time differences, for displaying dates and times in many formats, and for adjusting times and dates based on location in the world.
Strings. NSString
is another type of value object that provides object-oriented storage for a null-terminated array of bytes in a particular encoding. It includes support for converting string encodings among UTF-16, UTF-8, and many other encodings. NSString
also offers methods for searching, combining, and comparing strings and for manipulating file-system paths. You can use an NSScanner
object to parse numbers and words from an NSString
object. NSCharacterSet
(shown as a collection class in the diagram) represents a set of characters that are used by various NSString
and NSScanner
methods.
Collections. Collections are objects that store and vend other (usually value) objects in a particular ordering scheme. NSArray
uses zero-based indexing, NSDictionary
uses key-value pairs, and NSSet
provides unordered storage of objects (NSCountedSet
“uniques” the collection). With an NSEnumerator
object, you can access in sequence the elements of a collection. Collection objects are essential components of property lists and, like all objects, can be archived and distributed.
Operating-system services. Many Foundation classes facilitate access of various lower-level services of the operating system and, at the same time, insulate you from operating-system idiosyncrasies. For example, NSProcessInfo
lets you query the environment in which an application runs and NSHost
yields the names and addresses of host systems on a network. You can use an NSTimer
object to send a message to another object at specific intervals, and NSRunLoop
lets you manage the input sources of an application or other type of program. NSUserDefaults
provides a programmatic interface to a system database of global (per-host) and per-user default values (preferences).
File system and URL. NSFileManager
provides a consistent interface for file operations such as creating, renaming, deleting, and moving files. NSFileHandle
permits file operations at a lower level (for example, seeking within a file). NSBundle
finds resources stored in bundles and can dynamically load some of them (for example, nib files and code). You use NSURL
and related NSURL...
classes to represent, access, and manage URL sources of data.
Multithreading, operations, and subtasks. NSThread
lets you create multithreaded programs, and various lock classes offer mechanisms for controlling access to process resources by competing threads. You can use NSOperation
and NSOperationQueue
to perform multiple operations (concurrent or non-concurrent) in priority and dependence order. With NSTask
, your program can fork off a child process to perform work and monitor its progress.
Interprocess communication. Most of the classes in this category represent various kinds of system ports, sockets, and name servers and are useful in implementing low-level IPC. NSPipe
represents a BSD pipe, a unidirectional communications channel between processes.
Networking. The NSNetService
and NSNetServiceBrowser
classes support the zero-configuration networking architecture called Bonjour. Bonjour is a powerful system for publishing and browsing for services on an IP network.
Notifications. See the summary of the notification classes in “Foundation Paradigms and Policies.”
Archiving and serialization. The classes in this category make object distribution and persistence possible. NSCoder
and its subclasses, along with the NSCoding
protocol, represent the data an object contains in an architecture-independent way by allowing class information to be stored along with the data. NSKeyedArchiver
and NSKeyedUnarchiver
offer methods for encoding objects and scalar values and decoding them in a way that is not dependent on the ordering of encoding messages.
Objective-C language services. NSException
and NSAssertionHandler
provide an object-oriented way of making assertions and handling exceptions in code. An NSInvocation
object is a static representation of an Objective-C message that your program can store and later use to invoke a message in another object; it is used by the undo manager (NSUndoManager
) and by the Distributed Objects system. An NSMethodSignature
object records the type information of a method and is used in message forwarding. NSClassDescription
is an abstract class for defining and querying the relationships and properties of a class.
The Foundation framework for iPhone OS has a subset of the classes for Mac OS X. The following categories of classes are present only in the Mac OS X version of Foundation:
XML processing. The NSXML classes of Foundation process XML data efficiently, either in an event-driven way or by representing an XML document as a hierarchical tree structure. The latter approach lets you to query this structure and manipulate its nodes. The NSXML classes support several XML-related technologies and standards, such as XQuery, XPath, XInclude, XSLT, DTD, and XHTML.
Expressions and predicates. The predicate classes—NSPredicate
, NSCompoundPredicate
, and NSComparisonPredicate
—encapsulate the logical conditions to constrain a fetch or filter object. NSExpression
objects represent expressions in a predicate.
Spotlight queries. The NSMetadataItem
, NSMetadataQuery
and related query classes encapsulate file-system metadata and make it possible to query that metadata.
Scripting. The classes in this category help to make your program responsive to AppleScript scripts and Apple event commands.
Distributed objects. You use the distributed object classes for communication between processes on the same computer or on different computers on a network. Two of these classes, NSDistantObject
and NSProtocolChecker
, have a root class (NSProxy
) different from the root class of the rest of Cocoa.
The Application Kit (which is sometimes referred to as the AppKit) is a framework containing all the objects you need to implement your graphical, event-driven user interface on Mac OS X: windows, dialogs, buttons, menus, scrollers, text fields—the list goes on. The Application Kit handles all the details for you as it efficiently draws on the screen, communicates with hardware devices and screen buffers, clears areas of the screen before drawing, and clips views. The number of classes in the Application Kit may seem daunting at first. However, most Application Kit classes are support classes that you use indirectly. You also have the choice at which level you use the Application Kit:
Use Interface Builder to create connections from user-interface objects to your application’s controller objects, which manage the user interface and coordinate the flow of data between the user interface and internal data structures. For this, you might use off-the-shelf controller objects (for Cocoa bindings) or you may need to implement one or more custom controller classes—particularly the action and delegate methods of those classes. For example, you would need to implement a method that is invoked when the user chooses a menu item (unless it has a default implementation that is acceptable).
Control the user interface programmatically, which requires more familiarity with Application Kit classes and protocols. For example, allowing the user to drag an icon from one window to another requires some programming and familiarity with the NSDragging...
protocols.
Implement your own objects by subclassing NSView
or other classes. When subclassing NSView
, you write your own drawing methods using graphics functions. Subclassing requires a deeper understanding of how the Application Kit works.
The Application Kit consists of more than 125 classes and protocols. All classes ultimately inherit from the Foundation framework’s NSObject
class. The diagrams in Figure 1-10 show the inheritance relationships of the Application Kit classes.
As you can see, the hierarchy tree of the Application Kit is broad but fairly shallow; the classes deepest in the hierarchy are a mere five superclasses away from the root class and most classes are much closer than that. Some of the major branches in this hierarchy tree are particularly interesting.
At the root of the largest branch in the Application Kit is the NSResponder
class. This class defines the responder chain, an ordered list of objects that respond to user events. When the user clicks the mouse button or presses a key, an event is generated and passed up the responder chain in search of an object that can respond to it. Any object that handles events must inherit from the NSResponder
class. The core Application Kit classes—NSApplication
, NSWindow
, and NSView
—inherit from NSResponder
. You can find out more about these responder classes by reading “The Core Application Architecture on Mac OS X.”
The second largest branch of classes in the Application Kit descend from NSCell
. The noteworthy thing about this group of classes is that they roughly mirror the classes that inherit from NSControl
, which inherits from NSView
. For its user-interface objects that respond to user actions, the Application Kit uses an architecture that divides the labor between control objects and cell objects. The NSControl
and NSCell
classes, and their subclasses, define a common set of user-interface objects such as buttons, sliders, and browsers that the user can manipulate graphically to control some aspect of your application. Most control objects are associated with one or more cell objects that implement the details of drawing and handling events. For example, a button comprises both an NSButton
object and an NSButtonCell
object. See “Control and Cell Architecture” for further information
Controls and cells implement a mechanism that is based on an important design pattern of the Application Kit:. the target-action mechanism. A cell can hold information that identifies the message that should be sent to a particular object when the user clicks (or otherwise acts upon) the cell. When a user manipulates a control (by, for example, clicking the mouse pointer over it), the control extracts the required information from its cell and sends an action message to the target object. Target-action allows you to give meaning to a user action by specifying what the target object and invoked method should be. You typically use Interface Builder to set these targets and actions by Control-dragging from the control object to your application or other object. You can also set targets and actions programmatically.
Another important design-pattern based mechanism of the Application Kit (and also UIKit) is delegation. Many objects in a user interface, such as text fields and table views, define a delegate. A delegate is an object that acts on behalf of, or in coordination with, the delegating object. It is thus able to impart application-specific logic to the operation of the user interface. For more on delegation, target–action, and other paradigms and mechanisms of the Application Kit, see “Communicating With Objects.” For a discussion of the design patterns on which these paradigms and mechanisms are based, see “Cocoa Design Patterns.”
One of the general features of Mac OS X version 10.5 and later systems is resolution independence: the resolution of the screen is decoupled from the drawing done by code. The system automatically scales content for rendering on the screen. The Application Kit classes support resolution independence in its user-interface objects. However, for your own applications to take advantage of resolution independence, you might have to supply images at a higher resolution or make minor adjustments in your drawing code that take the current scaling factor into account.
Note: In Mac OS X version 10.5 resolution independence is a developer feature, and is not yet available to end users.
The following sections briefly describe some of the capabilities and architectural aspects of the Application Kit and its classes and protocols. It groups classes according to the class hierarchy diagrams shown in Figure 1-10 and “Application Kit class hierarchy—Objective-C (part two).”
For the overall functioning of a user interface, the Application Kit provides the following classes:
The global application object. Every application uses a singleton instance of NSApplication
to control the main event loop, keep track of the application’s windows and menus, distribute events to the appropriate objects (that is, itself or one of its windows), set up top-level autorelease pools, and receive notification of application-level events. An NSApplication
object has a delegate (an object that you assign) that is notified when the application starts or terminates, is hidden or activated, should open a file selected by the user, and so forth. By setting the NSApplication
object’s delegate and implementing the delegate methods, you customize the behavior of your application without having to subclass NSApplication
. “The Core Application Architecture on Mac OS X” discusses this singleton application object in detail.
Windows and views. The window and view classes, NSWindow
and NSView
, also inherit from NSResponder
, and so are designed to respond to user actions. An NSApplication
object maintains a list of NSWindow
objects—one for each window belonging to the application—and each NSWindow
object maintains a hierarchy of NSView
objects. The view hierarchy is used for drawing and handling events within a window. An NSWindow
object handles window-level events, distributes other events to its views, and provides a drawing area for its views. An NSWindow
object also has a delegate allowing you to customize its behavior.
Beginning with Mac OS X version 10.5, the window and view classes of the Application Kit support enhanced animation features.
NSView
is the superclass for all objects displayed in a window. All subclasses implement a drawing method using graphics functions; drawRect:
is the primary method you override when creating a new NSView
.
“The Core Application Architecture on Mac OS X” describes NSView
and NSWindow
objects.
Controller classes for Cocoa bindings. The abstract NSController
class and its concrete subclasses NSObjectController
, NSArrayController
, NSDictionaryController
, and NSTreeController
are part of the implementation of Cocoa bindings. This technology automatically synchronizes the application data stored in objects and the presentation of that data in a user interface. See “The Model-View-Controller Design Pattern” for a description of these types of controller objects.
Panels (dialogs). The NSPanel
class is a subclass of NSWindow
that you use to display transient, global, or pressing information. For example, you would use an instance of NSPanel
, rather than an instance of NSWindow
, to display error messages or to query the user for a response to remarkable or unusual circumstances. The Application Kit implements some common dialogs for you such as the Save, Open and Print dialogs, used to save, open, and print documents. Using these dialogs gives the user a consistent look and feel across applications for common operations.
Menus and cursors. The NSMenu
, NSMenuItem
, and NSCursor
classes define the look and behavior of the menus and cursors that your application displays to the user.
Grouping and scrolling views. The NSBox
, NSScrollView
, and NSSplitView
classes provide graphic “accessories” to other view objects or collections of views in windows. With the NSBox
class, you can group elements in windows and draw a border around the entire group. The NSSplitView
class lets you append views vertically or horizontally, apportioning to each view some amount of a common territory; a sliding control bar lets the user redistribute the territory among views. The NSScrollView
class and its helper class, NSClipView
, provide a scrolling mechanism as well as the graphic objects that let the user initiate and control a scroll. The NSRulerView
class allows you to add a ruler and markers to a scroll view.
Table views and outline views. The NSTableView
class displays data in rows and columns. NSTableView
is ideal for, but not limited to, displaying database records, where rows correspond to each record and columns contain record attributes. The user can edit individual cells and rearrange the columns. You control the behavior and content of an NSTableView
object by setting its delegate and data source objects. Outline views (instances of NSOutlineView
, a subclass of NSTableView
) offer another approach to displaying tabular data. With the NSBrowser
class you can create an object with which users can display and navigate hierarchical data.
The Cocoa text system is based on the Core Text framework, which was introduced in Mac OS X version 10.5. The Core Text framework provides a modern, low-level, high-performance technology for laying out text. If you use the Cocoa text system, you should rarely have reason to use Core Text directly.
The NSTextField
class implements a simple editable text-input field, and the NSTextView
class provides more comprehensive editing features for larger text bodies.
NSTextView
, a subclass of the abstract NSText
class, defines the interface to the extended text system. NSTextView
supports rich text, attachments (graphics, file, and other), input management and key binding, and marked text attributes. NSTextView
works with the Fonts window and Font menu, rulers and paragraph styles, the Services facility, and the pasteboard (Clipboard). NSTextView
also allows customizing through delegation and notifications—you rarely need to subclass NSTextView
. You rarely create instances of NSTextView
programmatically either, since objects on Interface Builder’s palettes, such as NSTextField
, NSForm
, and NSScrollView
, already contain NSTextView
objects.
It is also possible to do more powerful and more creative text manipulation (such as displaying text in a circle) using NSTextStorage
, NSLayoutManager
, NSTextContainer
, and related classes. The Cocoa text system also supports lists, tables, and non-contiguous selections.
The NSFont
and NSFontManager
classes encapsulate and manage font families, sizes, and variations. The NSFont
class defines a single object for each distinct font; for efficiency, these objects, which can represent a lot of data, are shared by all the objects in your application. The NSFontPanel
class defines the Fonts window that’s presented to the user.
The classes NSImage
and NSImageRep
encapsulate graphics data, allowing you to easily and efficiently access images stored in files on the disk and displayed on the screen. NSImageRep
subclasses each know how to draw an image from a particular kind of source data. The NSImage
class provides multiple representations of the same image, and also provides behaviors such as caching. The imaging and drawing capabilities of Cocoa are integrated with the Core Image framework.
Color is supported by the classes NSColor
, NSColorSpace
, NSColorPanel
, NSColorList
, NSColorPicker
, and NSColorWell
. NSColor
and NSColorSpace
support a rich set of color formats and representations, including custom ones. The other classes are mostly interface classes: They define and present panels and views that allow the user to select and apply colors. For example, the user can drag colors from the Color window to any color well.
The NSGraphicsContext
, NSBezierPath
, and NSAffineTransform
classes help you with vector drawing and support graphical transformations such as scaling, rotation, and translation.
The NSPrinter
, NSPrintPanel
, NSPageLayout
, and NSPrintInfo
classes work together to provide the means for printing and faxing the information that your application displays in its windows and views. You can also create a PDF representation of an NSView
.
Use the NSFileWrapper
class to create objects that correspond to files or directories on disk. NSFileWrapper
holds the contents of the file in memory so that it can be displayed, changed, or transmitted to another application. It also provides an icon for dragging the file or representing it as an attachment. Or use the NSFileManager
class in the Foundation framework to access and enumerate file and directory contents. The NSOpenPanel
and NSSavePanel
classes also provide a convenient and familiar user interface to the file system.
The NSDocumentController
, NSDocument
, and NSWindowController
classes define an architecture for creating document-based applications. (The NSWindowController
class is shown in the User Interface group of classes in the class hierarchy charts). Such applications can generate identically contained but uniquely composed sets of data that can be stored in files. They have built-in or easily acquired capabilities for saving, opening, reverting, closing, and managing these documents.
If an application is to be used in more than one part of the world, its resources may need to be customized, or localized, for language, country, or cultural region. For example, an application may need to have separate Japanese, English, French, and German versions of character strings, icons, nib files, or context help. Resource files specific to a particular language are grouped together in a subdirectory of the bundle directory (the directories with the .lproj
extension). Usually you set up localization resource files using Interface Builder. See “Nib Files and Other Application Resources” for more information on the Cocoa internationalization facilities.
The NSInputServer
and NSInputManager
classes, along with the NSTextInput
protocol, give your application access to the text input management system. This system interprets keystrokes generated by various international keyboards and delivers the appropriate text characters or Control-key events to text view objects. (Typically the text classes deal with these classes and you won’t have to.)
The Application Kit provides operating-system support for your application through classes that implement the following features:
Sharing data with other applications. The NSPasteboard
class defines the pasteboard, a repository for data that’s copied from your application, making this data available to any application that cares to use it. NSPasteboard
implements the familiar cut-copy-paste operation.
Dragging. With very little programming on your part, custom view objects can be dragged and dropped anywhere. Objects become part of this dragging mechanism by conforming to NSDragging...
protocols; draggable objects conform to the NSDraggingSource
protocol, and destination objects (receivers of a drop) conform to the NSDraggingDestination
protocol. The Application Kit hides all the details of tracking the cursor and displaying the dragged image.
Spell checking. The NSSpellServer
class lets you define a spell-checking service and provide it as a service to other applications. To connect your application to a spell-checking service, you use the NSSpellChecker
class. The NSIgnoreMisspelledWords
and NSChangeSpelling
protocols support the spell-checking mechanism.
The abstract NSNibConnector
class and its two concrete subclasses, NSNibControlConnector
and NSNibOutletConnector
, represent connections in Interface Builder. NSNibControlConnector
manages an action connection in Interface Builder and NSNibOutletConnector
manages an outlet connection.
The UIKit framework on iPhone OS is the sister framework of the Application Kit on Mac OS X. Its purpose is essentially the same: to provide all the classes that an application needs to construct and manage its user interface. However, there are significant differences in how the frameworks realize this purpose.
One of the greatest differences is that, on iPhone OS, the objects that appear in the user interface of a Cocoa application look and behave differently from their counterparts in a Cocoa application running on Mac OS X. Some common examples are text views, table views, and buttons. In addition, the event-handling and drawing models for Cocoa applications on the two platforms are significantly different. The following sections explain the reasons for these and other differences.
You can add UIKit objects to your application’s user interface in three ways:
Use the Interface Builder development application to drag-and-drop windows, views, and other objects from an object library.
Create, position, and configure framework objects programmatically.
Implement custom user-interface objects by subclassing UIView
or classes that inherit from UIView
.
Further Reading: To gain a thorough understanding of UIKit, read UIKit Framework Reference and iPhone Application Programming Guide.
As with the Application Kit, the classes of the UIKit framework ultimately inherit from NSObject
. Figure 1-11 presents the classes of the UIKit framework in their inheritance relationship.
As with the Application Kit a base responder class is at the root of the largest branch of UIKit classes. UIResponder
also defines the interface and default behavior (if any) for event-handling methods and for the responder chain, which is a chain of objects that are potential event handlers. When the user scrolls a table view with his or her finger or types characters in a virtual keyboard, UIKit generates an event and that event is passed up the responder chain until an object handles it. The corresponding core objects—application (UIApplication
), window (UIWindow
), and view (UIView
)—all directly or indirectly inherit from UIResponder
.
Unlike the Application Kit, UIKit does not make use of cells. Controls in UIKit—that is, all objects that inherit from UIControl
—do not require cells to carry out their primary role: sending action messages to a target object. Yet the way UIKit implements the target-action mechanism is different from the design in the Application Kit. The UIControl
class defines a set of event types for controls; if, for example, you want a button (UIButton
) to send an action message to a target object, you call UIControl
methods to associate the action and target with one or more of the control event types. When one of those events happens, the control sends the action message.
The UIKit framework makes considerable use of delegation, another design pattern of the Application Kit. Yet the UIKit implementation of delegation is different. Instead of using informal protocols, UIKit uses formal protocols with possibly some protocol methods marked optional.
Note: For a complete description of the target-action mechanism in UIKit and the Application Kit, see “The Target-Action Mechanism.” To learn more about delegation and protocols, both formal and informal, see “Delegates and Data Sources” and “Protocols.”
Each application running on iPhone OS is managed by a singleton application object, and this object has a job that is almost identical to that for the global NSApplication
object. A UIApplication
object controls the main event loop, keeps track of the applications windows and views, and dispatches incoming events to the appropriate responder objects.
The UIApplication
object also receives notification of system-level and application-level events. Many of these it passes to its delegate, allowing it to inject application-specific behavior when the application launches and terminates, and to respond to low-memory warnings and changes in time.
In Mac OS X, the mouse and keyboard generate most user events. The Application Kit uses NSEvent
objects to encapsulate these events. On iPhone OS, however, a user’s finger movements on the screen are what originate events. UIKit also has a class, UIEvent
, to represent these events. But finger touches are different in nature from mouse clicks; two or more touches occurring over a period could comprise a discrete event—a pinch gesture, for example. Thus a UIEvent
object contains one or more objects representing finger touches (UITouch
). The model for distributing and dispatching events to objects that can handle them on the two platforms is almost identical. However, to handle an event, an object must take into consideration the sequence of touches specific to that event.
The drawing models are very similar for the Application Kit and UIKit. In UIKit, however, a UIView
object has an animation layer associated with it to enable the animation of changes within views and transitions between views. That said, the programmatic support that UIKit directly provides for drawing is limited (specifically, simple line and rectangle drawing through functions declared in UIGraphics.h
). Therefore, for drawing of any sophistication, an application must use the Core Graphics or OpenGLES framework. You use UIColor
objects to set colors in the current graphics context.
Objects on an iPhone OS user interface are visibly different than objects on a Mac OS X user interface. Because of the nature of the device—specifically the smaller screen size and the use of fingers instead of the mouse and keyboard for input—user-interface objects on iPhone OS must typically be larger (to be an adequate target for touches) while at the same time make as efficient use of screen real estate as possible. These objects are sometimes based on visual and tactile analogues of an entirely different sort. As an example, consider the date picker object, which is instantiated from a class that both the UIKit and Application Kit frameworks define. On Mac OS X, the date picker looks like the following:
This style of date picker has a two tiny areas for incrementing date components, and thus is suited to manipulation by a mouse pointer. Contrast this with the date picker seen on iPhone applications:
This style of date picker is more suited for finger touches as an input source; users can swipe a month, day, or year column to spin it to a new value.
As with the Application Kit, many of UIKit classes fall into functional groups:
Controls. The subclasses of UIControl
instantiate objects that let users communicate their intent to an application. In addition to the standard button object (UIButton
) and slider object (UISlider
), there is a control that simulate off/on switches (UISwitch
), a spinning-wheel control for selecting from multidimensional sets of values (UIPickerView
), a control for paging through documents (UIPageControl
), and other controls.
Modal views. The two classes inheriting from UIModalView
are for displaying messages to users either in the form of “sheets” attached to specific views or windows (UIActionSheet
) or as unattached alert dialogs (UIAlertView
).
Scroll views. The UIScrollView
class enables instances of its subclasses to respond to touches for scrolling within large views. As users scroll, the scroll view displays transient indicators of position within the document. The subclasses of UIScrollView
implement table views, text views, and web views.
Toolbars, navigation bars, and view controllers. The UIViewController
class is a base class for managing a view. A view controller provides methods for creating and observing views, overlaying views, handling view rotation, and responding to low-memory warnings. UIKit includes concrete subclasses of UIViewController
for managing toolbars, navigation bars, and image pickers.
Applications use both toolbars and navigation bars to manage behavior related to the “main” view on the screen; typically, toolbars are placed beneath the main view and navigation bars above it. You use toolbar (UIToolbar
) object to switch between modes or views of an application; you can also use them to display a set of functions that perform some action related to the current main view. You use navigation bars (UINavigationBar
) to manage sequences of windows or views in an application and, in effect, to “drill down” a hierarchy of objects defined by the application; the Mail application for example, uses a navigation bar to navigate from accounts to mailbox folders and from there to individual email messages.
Users can enter text in an iPhone application either through a text view (UITextView
) or a text field (UITextField
). These classes adopt the UIInputTraits
protocol to specify the appearance and behavior of the virtual keyboard that is presented when users touch the text-entry object; any subclasses that enable entry of text should also conform to this protocol. Applications can draw text in views using UIStringDrawing
methods, a category on the NSString
class. And with the UIFont
class you can specify the font characteristics of text in all objects that display text, including table cells, navigation bars, and labels.
UIKit uses UIImage
objects to represent and encapsulate images.
The Application Kit and UIKit are Cocoa application frameworks that are designed for different platforms, one for Mac OS X and the other for iPhone OS. Because of this affinity, it is not surprising that many of the classes in each framework have similar names; in most cases, the prefix (“NS” versus “UI”) is the only name difference. These similarly named classes fulfill mostly similar roles, but there are differences. These differences can be a matter of scope, of inheritance, or of design. Generally, UIKit classes have fewer methods than their Application Kit counterparts.
Figure 1-12 shows UIKit classes with corresponding classes in the Application Kit. Table 1-1 describes the differences between the major classes in each framework.
Classes | Comparison |
---|---|
| The classes are strikingly similar in their primary roles. They provide a singleton object that sets up the application’s display environment and event loop, distributes events, and notifies a delegate when application-specific events occur (such as launch and termination). However, the |
| These classes also have nearly identical roles. They are abstract classes that define an interface for responding to events and managing the responder chain. The main differences is that the |
| The |
| These classes are very similar in purpose and in their basic sets of methods. They allow you to move and resize views, manage the view hierarchy, draw view content, and convert view coordinates. The design of |
| Both classes define a mechanism for objects such as buttons and sliders so that, when manipulated, the control object sends an action message to a target object. The classes implement the target-action mechanism in different ways, largely because of the difference between event models. See “The Target-Action Mechanism” for information. |
| The role of both of these classes is, as their names suggest, to manage views. How they accomplish this task is different. The management provided by an |
|
|
Among the minor classes you can find some differences too. For example, UIKit has the UITextField
and UILabel
classes, the former for editable text fields and the latter for non-editable text fields used as labels; with the NSTextField
class you can also create both kinds of objects simply by setting text-field attributes. Similarly, the NSProgressIndicator
class can create objects in styles that correspond to instances of the UIProgressIndicator
and UIProgressBar
classes.
As part of a standard installation, Apple includes, in addition to the core frameworks for both platforms, several frameworks that vend Cocoa programmatic interfaces. You can use these secondary frameworks to give your application capabilities that are desirable, if not essential. Some notable secondary frameworks include:
Core Data—(Mac OS X only) The Core Data framework helps a program to manage graphs of model objects through their life cycles, including the persistent storage of their data in relational databases or flat files. It includes features such as undo and redo management, automatic validation of values, change propagation, and integration with Cocoa bindings. See “Other Cocoa Architectures on Mac OS X” and Core Data Programming Guide for more information.
Sync Services—(Mac OS X only) Using Sync Services you can sync existing contacts, calendars and bookmarks schemas as well as your own application data. You can also extend existing schemas. See Sync Services Programming Guide for more information.
Address Book—This framework implements a centralized database for contact and other personal information. Applications that use the Address Book framework can share this contact information with other applications, including Apple’s Mail and iChat. See Address Book Programming Guide for Mac OS X for more information.
Preference Panes—(Mac OS X only) With this framework you can create plug-ins that your application can dynamically load to obtain a user interface for recording user preferences, either for the application itself or system-wide. See Preference Panes for more information.
Screen Saver—(Mac OS X only) The Screen Saver framework helps you create Screen Effects modules, which can be loaded and run via System Preferences. See Screen Saver Framework Reference for more information.
Web Kit—(not public on iPhone OS) The Web Kit framework provides a set of core classes to display web content in windows, and by default, implements features such as following links clicked by the user. See WebKit Objective-C Programming Guide for more information.
Many years ago Cocoa was known as NeXTSTEP. NeXT Computer developed and released version 1.0 of NeXTSTEP in September of 1989, and versions 2.0 and 3.0 followed not far behind (in 1990 and 1992, respectively). In this early phase, NEXTSTEP was more than an application environment; the term referred to the entire operating system, including the windowing and imaging system (which was based on Display PostScript), the Mach kernel, device drivers, and so on.
Back then, there was no Foundation framework. Indeed, there were no frameworks; instead, the software libraries (dynamically shared) were known as kits, the most prominent of them being the Application Kit. Much of the role that Foundation now occupies was taken by an assortment of functions, structures, constants, and other types. The Application Kit itself had a much smaller set of classes than it does today. Figure 1-13 shows a class hierarchy chart of NeXTSTEP 0.9 (1988).
In addition to the Application Kit, the early NeXTSTEP included the Sound Kit and the Music Kit, libraries containing a rich set of Objective-C classes that provided high-level access to the Display Postscript layer for audio and music synthesis.
In early 1993 NeXTSTEP 3.1 was ported to (and shipped on) Intel, Sparc, and Hewlett-Packard computers. NeXTSTEP 3.3 also marked a major new direction, for it included a preliminary version of Foundation. Around this time (1993), the OpenStep initiative also took form. OpenStep was a collaboration between Sun and NeXT to port the higher levels of NeXTSTEP (particularly the Application Kit and Display PostScript) to Solaris. The “Open” in the name referred to the open API specification that the companies would publish jointly. The official OpenStep API, published in September of 1994, were the first to split the API between Foundation and Application Kit and the first to use the “NS” prefix.
By June 1996 NeXT had ported and shipped versions of OpenStep 4.0 that could run Intel, Sparc, and Hewlett-Packard computers as well as an OpenStep runtime that could run on Windows systems. Sun also finished their port of OpenStep to Solaris and shipped it as part of their Network Object Computing Environment. OpenStep, however, never became a significant part of Sun’s overall strategy.
When Apple acquired NeXT Software (as it was then called) in 1997, OpenStep became the Yellow Box and was included with Mac OS X Server (also known as Rhapsody) and Windows. Then, with the evolution of the Mac OS X strategy, it was finally renamed to “Cocoa.”
© 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-11-19)