Section 2.11. Application Environments


2.11. Application Environments

Most of the typical application development occurs in the Application Environments layer. Mac OS X has multiple application environments, each providing features that may appeal to certain types of developers. For example, those interested in programming using "plain old" Unix APIs are equally well served on Mac OS X as those who wish to use visual tools for rapid prototyping, creation of complex graphical user interfaces, and object-oriented development. Of the vast number of portable programming language implementations in existence, many are readily accessible on Mac OS X, and some are bundled by Apple. In particular, Apple's own programming environment offers rich APIs for Mac OS Xspecific development. Although it would be impractical to enumerate all types of applications that can run on or be developed on Mac OS X, let us consider the following examples:

  • Unix-style command-line tools and X Window applications written entirely using portable interfaces such as POSIX

  • Carbon-based GUI and command-line applications written in C

  • Cocoa-based GUI and command-line applications written in Objective-C, Java, or AppleScript

  • AWT-based and Swing-based applications[46] written in Java

    [46] Java's Abstract Windowing Toolkit (AWT) provides facilities for creating GUIs and for drawing graphics. Swing is a relatively more modern GUI toolkit that evolved from AWT.

  • Generic command-line applicationsor toolswritten in C++ or C that may link with one or more frameworks such as Core Foundation, Core Services, Foundation, and I/O Kit

We saw earlier that the Mac OS X kernel understands only the Mach-O binary executable format. Although Mach-O is the preferred runtime architecture, it is possible to run certain legacy format binaries on Mac OS X.

The Mac OS X kernel could be seen as an application environment for specialized applicationsdynamically loadable kernel extensionsthat execute in the kernel's address space.


2.11.1. BSD

The BSD application environment in Mac OS X is similar to, but not the same as, a traditional user-level environment on a BSD-based Unix system. It provides POSIX APIs, BSD-specific APIs, and some Unix-flavored APIs that export Mac OS Xspecific functionality. You can use the BSD environment for writing Unix tools, daemons, and shell scripts. In many cases, programs targeted for the Mac OS X BSD environment would be readily portable to other Unix systems and vice versa. The standard libraries and headers for the BSD environment reside in their traditional Unix locations: /usr/lib/ and /usr/include/, respectively.

Technically, many header files in /usr/include/ are part of the System framework. However, the System.framework directory neither contains nor links to these headers since the C compiler searches in /usr/include/ by default.


2.11.2. The X Window System

The X Window System could be seen as a graphical extension to the BSD environment. Mac OS X includes an optimized X Window server (/usr/X11R6/bin/Xquartz) along with a modern X Window environment. The X server is integrated with the Mac OS X Quartz subsystem. It conceptually sits atop the native Core Graphics APIs, tying into the native Mac OS X event system. Through this architecture, the X server enjoys hardware acceleration.

The environment includes quartz-wman X Window manager with the native Mac OS X look-and-feel that allows X applications to run alongside native Mac OS X programs. quartz-wm provides Aqua window controls, drop shadows, integration with the Dock, and so on. Although the X server's default operating mode is rootless, it can also be run in full-screen mode.

Even though the Mac OS X user interface does not use focus-follows-mouse mode, it is possible to configure quartz-wm to enable this mode for X Window applications. With this mode, X application windows can be focused by simply moving the mouse pointer over them. To enable this mode, the wm_ffm Boolean property must be set to true in the com.apple.x11.plist file.


Because of the availability of the BSD and X Window environments, it is usually straightforward to port existing Unix applications to Mac OS X simply by recompiling them, with little or no source modification.

2.11.3. Carbon

The Carbon application environment contains APIs based on the original Mac OS 9 APIs. In fact, some of Carbon's constituent interfaces date back to Mac OS 8.1. The Carbon interfaces are procedural in nature and are implemented in the C programming language. Carbon was originally designed to provide an easy development migration path from Mac OS 8 and Mac OS 9 to newer systems. It allows a compliant application, one that uses only features supported on both Mac OS 9 and Mac OS X, to run natively on both systems. It is implemented as a framework (Carbon.framework) on Mac OS X, whereas it is implemented as a system extension (CarbonLib) on Mac OS 9.

2.11.3.1. Support for CFM Binaries

The Code Fragment Manager (CFM) was a part of older Mac OS versions. It loaded fragments of PowerPC code from Preferred Executable Format (PEF) files into memory and prepared them for execution. A fragment is an arbitrarily sized basic unit of executable code and its associated data. It has certain well-defined properties and a method of addressing its contents. The following are examples of fragments:

  • An application

  • A system extension

  • A shared library, which could be an import library or a plug-in

  • Any other block of code and associated data

Besides mapping fragments into memory, the CFM's responsibilities included releasing fragments when they were no longer needed, resolving references to symbols imported from other fragments, and providing support for special initialization and termination routines.

The Mac OS X native runtime architecture (dyld/Mach-O) is not the same as that on Mac OS 9 (CFM/PEF). All Mac OS X libraries, including those that are part of Carbon, use the Mach-O format. However, Carbon supports the CFM on Mac OS X for Mac OS 9 compatibilityit is possible to create and run CFM applications on Mac OS X. In fact, an application that must run on both systems either must be compiled separately for the two systems or must be a CFM application. Carbon uses the LaunchCFMApp helper application[47] to run programs created for the CFM. LaunchCFMApp can run only native PowerPC code. It does not support resource-based fragments. Moreover, Carbon provides a one-way bridge to CFM applications to link to Mach-O code. Using this bridge, a CFM application can call a Mach-O library, but not vice versa.

[47] LaunchCFMApp resides in the Support subdirectory of the Carbon framework.

2.11.3.2. Carbon APIs

Carbon does not include all of the old APIs, but it contains a subset (about 70%) that covers most of the functionality used by typical applications. APIs that are not critical, or are no longer applicable due to radical differences between Mac OS X and earlier systems, have been dropped in Carbon. These include APIs that were specific to the 68K architecture, those that accessed the hardware directly, and those that were replaced by improved APIs. The following are noteworthy features of Carbon.

  • Some of the APIs included in Carbon have been modified or extended to benefit from the more modern nature of Mac OS X, which uses preemptive multitasking and protected memory as fundamental features. In contrast, such features were retrofittedwith limited applicabilityin Mac OS 9.

  • Some new APIs were added to Carbon and made available on Mac OS 9. Several new APIs in Carbon are available only on Mac OS X.

  • Carbon applications running on Mac OS X have the system's native look-and-feel.

The New "Old" API

Although Carbon is best understood as an overhaul of several older APIs that were pruned, extended, modified, and supplemented with new APIs to run in the modern Mac OS X environment, it does not represent an obsolete set of interfaces. Not only does Carbon support standard Aqua user-interface elements, but Carbon user interfaces can even be designed using the Interface Buildersimilar to Cocoa applications. Carbon functionality is widely used in Mac OS X and is critical for C-based development. Some parts of Carbon are complementary to object-oriented APIs such as Cocoa.


The following are examples of Carbon's subframeworks.

  • CarbonSound provides Carbon Sound Manager interfaces.

  • CommonPanels provides interfaces for displaying commonly used GUI panels,[48] such as the Color window and the Font window.

    [48] A panel is a special kind of window that usually serves an auxiliary function in an application.

  • Help provides interfaces for using Apple Help in applications.

  • HIToolbox[49] provides interfaces for the HIToolbox object, the Carbon Event Manager, and others. This framework provides various objects (such as HIObject and HIView) for organizing windows, controls, and menus in Carbon applications. The "view" objects provided by the HIToolbox framework benefit from native Quartz rendering (with automatic layering), the ability to be hidden, and the ability to be attached or detached from windows.

    [49] HIToolbox stands for Human Interface Toolbox.

  • HTMLRendering provides interfaces for rendering HTML content. However, the Web Kit framework has superseded it.

  • ImageCapture provides interfaces for capturing images from digital cameras.

  • Ink provides interfaces for handwriting recognition based on input from pen-based devices. Features provided by this framework include programmatic enabling or disabling of handwriting recognition, direct access to Ink data, the ability to toggle between deferred and on-demand recognition, and the ability to manipulate text directly through gestures. Moreover, a programmer can incorporate custom correction models that allow incoming handwriting data to be interpreted in alternative ways.

  • NavigationServices provides interfaces for file navigation.

  • OpenScripting contains AppleScript and Open Scripting Architecture (OSA) interfaces.

  • Print provides print dialog interfaces.

  • SecurityHI provides security dialog interfaces.

  • SpeechRecognition provides Speech Recognition Manager interfaces.

There are several frameworks that, although usable from other environments, are primarily for use by Carbon applications and are considered part of the Carbon environment. These include the Application Services, Core Foundation, and Core Services frameworks. Thus, Carbon provides procedural interfaces both for GUI development and for lower-level development involving manipulation of system resources, event handling, and data management.

From a programmer's standpoint, it is generally easier to create an application from scratch using Cocoa (see Section 2.11.4) rather than Carbon, since Cocoa automatically provides several features that would require explicit coding in Carbon. For example, Cocoa objects by default provide many aspects of a well-behaved Mac OS X application: document management, window management, opening and saving of documents, pasteboard behavior, and so on. Similarly, the Core Data framework (see Section 2.11.4.2), which allows modeling and lifecycle management of data, is accessible only to Cocoa programs.

2.11.4. Cocoa

The Cocoa environment provides object-oriented APIs for rapid application development in the Objective-C and Java programming languages.[50] Cocoa is both a collection of APIs and a set of visual tools that are particularly useful for rapid prototyping, data modeling, and overall reduction in design and development efforts. Examples of such tools include the Interface Builder and Xcode's class- and data-modeling tools. Interface Builder allows a programmer to create most (and often all) of an application's user interface graphically rather than programmatically. The class-modeling tool allows the programmer to visualize, browse, and annotate classes in terms of class relationships and the protocols they implement. The data-modeling tool allows the programmer to visually design a schema for application data in terms of entities that constitute the data and the relationships between them.

[50] It is possible for other programming or scripting languages to have bindings to Cocoa. For example, it is possible to use Cocoa interfaces from AppleScript.

Apple recommends Cocoa as the preferred way to develop typical applications on Mac OS X. Between Cocoa and Carbon, you should use Cocoa unless your desired functionality is available only through Carbon, you must have legacy compatibility, or you must use C-based procedural interfaces.

A Cocoa application can call Carbon APIs. It is possible, and common, for an application to be linked against both the Carbon and Cocoa frameworks. iDVD, iMovie, and Safari are examples of such applications.


Cocoa is an important inheritance from NeXT, as indicated by the various names with the "NS" prefix in Cocoa APIs. Many of the Cocoa APIs are largely based on OpenStep frameworks. Cocoa primarily consists of two object-oriented frameworks: Foundation (Foundation.framework) and Application Kit (AppKit.framework). Several other frameworks add specific functionality to Cocoa, such as Core Data, PDF Kit, and QuickTime Kit.

The Foundation framework provides fundamental classes and methods for bundle access, data management, file access, interprocess communication, memory management, network communication, process notification, and various low-level features.

The Application Kit provides classes that implement user-interface elements such as windows, dialogs, controls, menus, and event handling.

Core Data makes object lifecycle management easier by providing classes and methods for data management.

Cocoa is effectively an umbrella framework consisting of the Foundation, Application Kit, and Core Data subframeworks. The dynamic library inside Cocoa.framework is a wrapper that links to these frameworks. Consequently, linking with Cocoa.framework links in these (effective) subframeworks. However, in this particular case, the subframeworks are also available for individual linking. This is not the case with most umbrella frameworks, where it is illegal to attempt to link to a specific subframework.


2.11.4.1. Nib Files

When creating user interfaces with the Interface Builder, you will often come across nib files. As we saw earlier, the term stands for NeXT Interface Builder. A nib file contains descriptions of some or all of an application's user interface along with references to any resources (e.g., images and audio) that the interface may use. It is essentially an archive. Usually there is a "main" nib file that contains an application's main menu and other user-interface elements intended to appear when the application starts. During an application's execution, its nib files are opened and user-interface objects are unarchived. From the standpoint of the Model-View-Controller (MVC) design pattern, nib files define the view part of an application, while also defining connections into controller instances.

The nibtool command-line program can be used to print, update, and verify the contents of a nib file. Figure 226 shows an example.

Figure 226. Using nibtool to view the contents of a nib file

$ nibtool -a /Applications/Utilities/Terminal.app/Contents/\ Resources/English.lproj/Terminal.nib /* Objects */ Objects = {     "Object 1" = {         Class = "NSCustomObject";         CustomClass = "TerminalApp";         Name = "File's Owner";         className = "TerminalApp";     };     ... }; /* End Objects */ /* Object Hierarchy */ Hierarchy = {     "Object 1 <NSCustomObject> (File's Owner)" = {         "Object -1 <IBFirstResponder> (First Responder)";         "Object 37 <NSMenu> (MainMenu)" = {             "Object 12 <NSMenuItem> (Windows)" = { ... }; /* End Hierarchy */ /* Connections */ Connections = {     "Connection 89" = {         Action = "cut:";         Class = "NSNibControlConnector";         Source = "3";     }; ... }; /* End Connections */ /* Classes */ Classes = {     IBClasses = (         {             ACTIONS = {enterSelection = id; findNext = id; findPanel = id;                        findPrevious = id; };             CLASS = FindPanel;             LANGUAGE = ObjC;             OUTLETS = {findPanel = id; };             SUPERCLASS = NSObject;         }, ...

2.11.4.2. Core Data

Core Data is a Cocoa framework that facilitates data-model-driven application development through fine-grained management of data objects.

Core Data's primary benefits are for applications that have a highly structured data model to begin with.[51] In such cases, the data model can be represented by a schema, which in turn can be built using graphical tools in Xcode. Therefore, instead of defining data structures programmatically, developers can create visual descriptionsor modelsof data objects.[52] The application accesses the data through the Core Data framework, which is responsible for creating and managing instances of the data model.

[51] Core Data is ideally suited for managing the data model of an MVC application.

[52] It is still possible to create models programmatically.

Examples of applications that are good candidates for Core Data include Mail, iTunes, and Xcode. Each of these applications uses highly structured data: mailbox files, music libraries, and project files, respectively.


Core Data offers several benefits to the developer, such as those listed here.

  • It manages data objects in memory and on disk. It can automatically serialize data to disk, while supporting multiple formats for persistent storage of data, namely, Binary, SQLite, and XML.

  • It supports validation of property values. For example, properties in a data model can be validated for minimum values, maximum values, string lengths, and so on.

  • It supports automatic undo and redo of data manipulations by tracking changes in the application's object graph,[53] relieving the developer of this responsibility.[54]

    [53] In this context, an object graph is a collection of data objects (entities) with references to one another (relationships).

    [54] Even without Core Data, Cocoa applications can use the NSUndoManager class to record operations for undo and redo. However, doing so requires additional work from the developer.

  • It supports synchronizing data changes with user-interface elements. It uses integration with Cocoa Bindings for this purpose. Moreover, it can group and filter in-memory changes.

  • It enhances scalability by efficiently managing object lifecyclesdata objects that are not currently needed by the application do not reside in memory. For objects that are not memory-resident, placeholder objects are maintained with appropriate reference counting. Accessing a placeholder object results in Core Data fetching the actual object. This is similar to page-faulting in a virtual memory implementation.

The file formats supported by Core Data vary in several properties: atomic access, human readability, performance, and scalability. For example, SQLite offers the best performance and is the most scalable. However, it is not human readable. XML is slower but is human readable.


Since Core Data's essence is model-driven development, the most critical abstraction from the developer's standpoint in Core Data is the model, which is akin to an entity-relationship (ER) diagram. A model contains the following key elements.

  • Entities are roughly equivalent to classes in that they represent types of objects. The developer may specify a class name to represent an entity at runtime. Like classes, entities support inheritance.[55] Each entity can have certain properties: attributes, relationships, and fetched properties. An attribute is similar to class data. Attributes can have associated validation rules and default values. They can be optional or even transient.[56] Relationships are references from one entity to another. A relationship can be one-to-one or one-to-many. A fetched property is a reference from an entity to a query.

    [55] Entity inheritance in Core Data is independent of class inheritance.

    [56] A transient attribute is maintained in memory for convenience or performance reasons.

  • Predefined queries are essentially query templates that can be instantiated at runtime.

  • Configurations allow for advanced file management by mapping entities to persistent stores. A single entity can exist in multiple configurations.

Core Data applications typically use Core Data APIs to load models from storage into memory. The generic data object in Core Data is an instance of the NSManagedObject class. It is also a required superclass for any custom data object classes. As shown in Figure 227, the following primary components of the Core Data architecture interact in a logical "stack"[57] at runtime.

[57] Each document in a document-based application has its own Core Data stack.

Figure 227. A Core Data stack


  • A Bindings Controller is responsible for transferring in-memory data changes to the user interface through Cocoa Bindings.

  • A Managed Object Context sits atop the Persistent Store Coordinator. It provides in-memory scratch space for loading data objects from disk, making changes to the objects, and either rejecting or saving those changes. It tracks all such changes and provides undo/redo support.

  • A Persistent Store Coordinator exists for each Managed Object Context and, in turn, for each Core Data stack. It presents a unified view of one or more underlying persistent stores. For example, it can merge the contents of multiple data files to present them as a single store to its Managed Object Context.

If Core Data is used judiciously, it can significantly reduce the amount of code that a developer would have to otherwise write.

2.11.5. WebObjects

WebObjects is an independent Apple productit is not a part of Mac OS X. It provides an application environment for developing and deploying Java server applications and Web Services. Using WebObjects frameworks and tools, developers can also create user interfaces for various types of web content, including database-driven and dynamically generated content. As we noted in Chapter 1, several Apple web sites are implemented using WebObjects.

2.11.6. Java

The Java environment is a core component of Mac OS X. It includes the Java runtime and the Java Development Kit (JDK), which are accessible both through the command line and through Xcode. The Java runtime includes the HotSpot Java virtual machine (JVM) with just-in-time (JIT) bytecode compilation. It can also treat Java archivesor jar filesas shared libraries. The Java Virtual Machine framework (JavaVM.framework) contains Java classes in jar files, command-line programs such as java and javac,[58] headers, documentation, Java Native Interface (JNI) libraries, and support libraries.

[58] Besides javac, Mac OS X includes the Jikes open source Java compiler from IBM.

Cocoa includes Java packages corresponding to the Foundation and the Application Kit frameworks. Therefore, Cocoa applications can be created using Java as the programming language instead of Objective-C. Moreover, Java programs can call Carbon and other frameworks via JNIa standard programming interface for writing Java native methods and embedding the Java virtual machine into native applications. In particular, Java applications can use Mac OS X native technologies such as QuickTime and Carbon. Since the Swing implementation on Mac OS X generates native Mac OS X user-interface elements, Swing-based Java applications have the same look-and-feel as Cocoa applications written using Objective-C.

The Cocoa-Java programming interface is deprecated in Mac OS X versions later than 10.4. Apple announced in mid-2005 that Cocoa features introduced in newer versions of Mac OS X will not be added to the Cocoa-Java API, requiring the Objective-C Cocoa API to employ the new features.


Although Java is considered an application environment, the Java subsystem can itself be represented as different layers, as depicted in Figure 21. For example, the JVM along with the core JDK packages are analogous to the Core Services layer. In fact, the JVM conceptually provides the combined functionality of a computer system's hardware and the operating system kernel.

2.11.7. QuickTime

QuickTime's functionality is available to applications through various APIs such as those listed here.

  • The Carbon QuickTime API provides an extensive procedural C-based interface.

  • Higher-level Cocoa classes such as NSMovie and NSMovieView provide a limited subset of QuickTime's functionality.

  • The QuickTime Kit (QTKit.framework) Cocoa framework was introduced in Mac OS X 10.4 to provide more comprehensive native access to QuickTime from Cocoa programs.

2.11.8. Classic

Classic is a binary compatibility environment for running unmodified Mac OS 9 applications on the PowerPC version of Mac OS X. Classic functionality is provided through a combination of the following components.

  • A core service resides as the Classic Startup.app application bundle in /System/Library/CoreServices/. The bundle contains a virtualizer program called truBlueEnvironment.

  • A Mac OS 9 installation resides in /System Folder/ by default.

  • Special support exists in the Mac OS X kernel for the Classic environment.

Classic Startup is a Mach-O application that runs Mac OS 9 within its address space. It provides a hardware abstraction layer between Mac OS 9 and Mac OS X by virtualizing traps, system calls, and interrupts. It runs in a protected memory environment, with multiple Mac OS 9 processes within it layered on top of a single Mac OS X BSD process. Each Carbon application in Mac OS 9 has its own Carbon Process Manager process. In this sense, Classic support in Mac OS X is essentially "Mac OS 9 in a process." However, note that the Classic Startup application itself is multithreaded.

In certain ways, Classic is "more" than Mac OS 9, since its integration with Mac OS X allows sharing of resources, as illustrated by the following examples.

  • Fonts stored in the Classic system folder's Fonts subdirectory are shared with Mac OS X, but Mac OS X fonts are not available to Classic.

  • AppleScript running within Classic can communicate with Mac OS X applications.

  • Classic support is fully integrated with the Finder and other Mac OS X application environments. In particular, you can copy and paste as well as drag and drop between Classic and Mac OS X. However, Mac OS 9 applications retain their original look-and-feeltheir user-interface elements do not look like Mac OS X's.

  • Classic can use volumes of any file system type that is supported by Mac OS X, since it shares files through the host operating system.

  • Classic networking is largely integrated with Mac OS X networking, allowing various types of networking devices, IP addresses, and IP ports to be shared between Mac OS X and Classic. Whereas Carbon provides a limited Open Transport implementation built atop BSD sockets, Classic provides a complete Open Transport protocol stack implementation.

Classic Startup is not an emulatorit is a virtualizer. Nevertheless, it allows both 68K-based Mac OS 9 applications and PowerPC-based CFM applications[59] to run under Mac OS X. There is emulation involved in running 68K code, but that emulation was part of Mac OS 9 and remains unchanged.

[59] Classic does not support CFM-68Kthe 68K version of CFM.


As we saw in Section 2.11.3.1, another legacy runtime environment is provided by the CFM, which uses PEF binaries.

Many APIs

Depending on the particular application environment you program in, you may often have to use different, environment-specific APIs for performing similar tasks. In some cases, it may also be possible to use some APIs from multiple environments in a single application. Let us consider the example of launching an application.

At the lowest level, a process is tied to a Mach task, which should not be directly created by user programs. At the Unix system-call level, a fork() and exec() sequence is normally used to run an application in a new process. However, typical Mac OS X applications do not use fork() and exec() directly but use the Launch Services framework to launch applications or to "open" documents. In particular, the Finder uses Launch Services to map document types to applications that can handle those types. Launch Services itself calls fork() and exec() to run applications. Cocoa applications can launch applications using the NSWorkSpace class, which in turn calls Launch Services.


2.11.9. Rosetta

The x86 version of Mac OS X uses a binary translation process called Rosetta that allows PowerPC executablesboth CFM and Mach-Oto run on x86-based Macintosh computers.

Like Classic, Rosetta is meant as a technology devised to help transition from one platform to another. It is limited in the type of executables it supports. Examples of PowerPC executables it does not support include the following:

  • G5-specific executables

  • Kernel extensions

  • Programs that communicate with one or more kernel extensions that are available only on PowerPC systems

  • Java applications that use the JNI

  • The Classic virtualizer and the applications that run within it

  • PowerPC-specific screensavers

For an application to run successfully under Rosetta, all components of the application, including loadable plug-ins, must be PowerPC-based.

Rosetta is launched by the kernel to handle a file that is one of the supported PowerPC executable types. Rosetta code resides in the same Mach task as the "guest" executable. It dynamically translateswith optimizationsblocks of PowerPC code to x86 code, while alternating between code translation and code execution. To improve translation performance, Rosetta caches blocks of translated code.




Mac OS X Internals. A Systems Approach
Mac OS X Internals: A Systems Approach
ISBN: 0321278542
EAN: 2147483647
Year: 2006
Pages: 161
Authors: Amit Singh

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net