Arise Aqua
Volume Number: 16
Issue Number: 5
Column Tag: Programming
Arise Aqua!
By Andrew Stone Contributing Editor, Raven Zachary
A Programmer's Introduction to Developing for Mac
OS X
Introduction
The release of Mac OS X Developer Preview 3 in late February has ushered in a brave
new world for both traditional Macintosh and veteran Cocoa OpenStep programmers.
The new Aqua interface demoed by Steve Jobs at MacWorld San Francisco is now in the
hands of the Mac vanguard. This release represents a convergence of the best ideas
from the Carbon (Mac OS) and the Cocoa (aka Rhapsody/OpenStep) worlds, and has
everything you need to produce first class applications for the forthcoming Mac OS X
release late this summer.
Without a doubt, the most immediately striking part of DP3 is the Aqua Interface - a
truly liquid and almost candy-like user interface that is a pleasure to behold.
The use of subtle, fuzzy shadows on windows, semi-transparent title bars, animated
effects and "gum drop" controls represent a breakthrough in UI design and an entirely
new look and feel for Mac OS X. Revolutionary interface concepts such as the "drawer",
pop-up and self-magnifying dock, drop-down sheets and single window mode address
the desktop clutter that is the bane of modern operating systems. The drawer is a
sub-window which is attached to a parent window and can be pulled out as need arises.
The right-most top button on windows switches the interface into single window mode
Figure 1. The single window mode selection button, located in the upper-right
corner of a window.
The singly focused window is a boon for neatness freaks - you select the window you
want activated and all other windows will "genie" away.
The new Mac OS X Finder sports the Dock, which is a user-defined set of application
and document icons along the bottom of the screen. Features include "auto-hide" and a
magnification mode to help the fading eyesight of the baby boomer generation. As your
cursor passes over the miniaturized windows and application tiles, the icons
underneath magnify so you can better see what's being represented. And true to the
Macintosh Way, the Finder has preferences which allow you to adjust and turn off
these features if they don't suit you.
Figure 2. The Dock, located at the bottom of the Desktop. As the mouse rolls over the
icons in the Dock, they are magnified.
Your icons should have multiple resolutions (16 by 16, 32 by 32, 48 by 48 and 128
by 128) to take advantage of Finder's magnified dock and inspector, otherwise, they'll
look rather jagged. Apple has provided tools to make these .icns resources. Later in the
article, you'll learn how.
Figure 3. The icon for TextEdit.app.
Of great importance to the existing Mac community is "Classic.app". Classic is
basically the old Mac OS Finder. When launched, Classic will let you double-click and
run all of your old Mac OS applications, without the annoying separate world of the
"Blue Box", also known as MacOS.app. These applications' windows appear in the same
desktop as new Mac OS X applications.
However, one thing becomes perfectly clear when you run an old Mac OS application: it
really looks out of place and kind of "cheesy". There is no window depth or shadows and
you can only drag the outline of the window. When placed side by side with a new
application, it appears rather pale. If your application is to compete on Mac OS X, it
had better take advantage of the Aqua interface and memory management features of the
new operating system.
So there are two approaches to building Mac OS X applications and your choice will
depend on a number of factors. For traditional Macintosh developers who have large
code bases, using the Carbon software development kit is the fastest way to go. With
just a little pruning of no longer supported API, you can give your classic Mac apps a
face lift and gain much new functionality for very little expended effort. If you are
writing a new application, or willing to gut and rewrite an old one (something which
really does need to be done every ten years!), then I strongly recommend using Apple's
high level, "Five Story" Application Programmer's Interface named Cocoa.
The Object Satori
When I first encountered the core ideas at the heart of Cocoa over twelve years ago, and
realized the elegance and power at my fingertips - I had a major realization that I call
"Object Satori". This article aspires to be the cyber-equivalent of being given your
first "cup of koolaid" and is geared towards Classic Mac programmers, refugees from
the Windows World and of course, the Cocoa Choir. The focus of this article is to
explain the rationale behind object oriented frameworks and provide you with the
motivation and inspiration for going beyond Carbon into the gleaming skyscraper of
Cocoa.
I started my programming life as a HyperTalk scripter, and had run into a brick wall
trying to learn the Mac toolbox programming XFCN's. When I heard about the NeXT on
the comp.sys.mac USENET newsgroup, I was totally intrigued and given the hope of a
much easier development environment.
Six weeks after a four day crash course at "NeXT Camp" in the spring of 1989, I had
finished my first Cocoa app. TextArt was a type styling program which used Display
PostScript to let you do cool things to type by taking advantage of the built-in
functionality of the AppKit, Cocoa's user interface framework. This app allowed you to
do things that were impossible on other platforms, and yet I had to write very little of
the code that did all these effects!
Today, I have seven applications that run on Mac OS X Server and are
ready for release on Mac OS X. Cocoa has empowered a single programmer to produce
applications that have taken teams of programmers on other platforms. The advantages
of Cocoa can be summed up by saying it makes programming easy and fun.
A Rose By Any Other Name
What is Cocoa? A delicious beverage that induces a neuro-chemical rush similar to
your first kiss, that is better than Java for your health. What a comforting and
evocative name that makes you want to curl up by the fire! Cocoa began life in the late
'80s as the AppKit when a frustrated Mac programmer had a vision that the "NeXT
Mac should be easier to program than it currently was. Here we had the easiest
computer to use on the planet, and it only required that you understand assembly
language and A-traps to program it! You might remember that AppKit founder William
Parkhurst had written a plugin for MacPaint that allowed you to rotate and flip the
selected bits, which was really cool in '85!
The AppKit evolved into NeXTStep, which split into the Application and Foundation
frameworks of OpenStep, an open object oriented API that was renamed "Rhapsody
when Apple acquired NeXT in 1997. I think the failure of Lotus "Jazz" should have
been a sufficient sign that musical monikers are to be avoided. You really want a name
that simply tastes good, thus we have Cocoa.
Apple is fortunate to have many of the old NeXT engineers, including one of the four
original AppKit programmers, Ali Ozer who leads the AppKit group. Much has been
learned about object oriented programming in these intervening years, and new
functionality is continually being added. What this means to us programmers living in
the trenches is that we have less code to write and maintain, and can focus solely on
what makes our programs different.
A Short History of Object Oriented Programming
Before we delve into the frameworks that make up Cocoa, it's worth stepping back 35
years to two concepts that underlie OO programming: abstract data types and data
hiding. An object is a collection of data and the operations (what we call methods) upon
that data. It's like a black box - we know the inputs and the outputs, but the
implementation does not concern us. What this means is that we are free from knowing
the intricacies of complex code, and yet we are free to take advantage of it.
This is a radically different programming metaphor than the "functional
programming of C, Pascal, Fortran and Basic. In a functional programming language,
you are telling data what to do, and a deep understanding of the involved data structures
is required. If a data structure changes, your code will break. However in the Object
Oriented paradigm, should the implementation of an object change to a more efficient
one, our code will continue to work, and in fact, gain all the benefits of the enhanced
object. Data is hidden from view, and instead of giving an object detailed instructions
to do something, it knows how to do it by itself.
There is a certain cyber machismo in being able to write btrees in Fortran or Lisp
interpretors in C, but shouldn't the goal be to make our lives easier, not harder? What
makes it possible to manage the complexity of large software is the boundaries between
modules, that is, the Application Programmer's Interface (API). With regard to
intellectual discovery, I believe in cognitive dissidence, but when it comes to
programming, I believe in being a model citizen, and sticking strictly to the API. This
adherence keeps your code running when there are new system releases, and puts the
burden of correct operation onto Apple, where their programmers can maintain and
enhance your code! Moreover, when features are added to Cocoa, your application
automatically gains the new features, even without recompilation.
Where Do I Start?
Learning a new programming environment can seem like an imposing task. Luckily,
everything you already know will make it easier to learn Cocoa. In fact, most of what
you have to do is quit doing things the hard way! For example, you'll never have to
clone another event loop if you don't want to. Often you'll find that if a task is difficult,
then you are approaching the problem in the wrong manner.
You can program Cocoa in any combination of the big three object oriented languages:
C++, Objective-C and the highly hyped Java. Objective-C is the choice of long-time
Cocoa programmers and is the actual language used "under the hood" in the major
frameworks of Cocoa. Its dynamic runtime binding allows terse, elegant and reusable
code.
Although the total Cocoa API is large, it's very accessible for two reasons: you can
learn it as you use it and the methods you call have a consistent and natural language
naming pattern. For example, to allow a text object to accept dragged and dropped
graphics, you'd write:
[myTextView setImportGraphics:YES];
// myTextView.setImportGraphics(true);
An even easier way is to create the textView in Interface Builder - Cocoa's visual user
interface design application. Simply click the switch in the NSTextView Inspector that
says "Allow Graphics":
Figure 4. Modifying a text object's properties using Interface Builder.
To bring up a save panel and save your text, replete with graphics, you simply write:
// Grab an instance of the global Save Panel:
NSSavePanel *savePanel = [NSSavePanel savePanel];
// save the text in an rtfd file wrapper
[savePanel setTypes:[NSArray arrayWithObject:@"rtfd"]];
// run the save panel modally to get the filename
if ([savePanel runModalForDirectory:nil file:nil
relativeToWindow:[myTextView window]])
// the text object knows how to save itself:
[myTextView writeRTFDToFile:[savePanel filename]
atomically:YES];
Under the Sheets
A powerful new interface concept in Aqua is the notion of document modal windows or
"sheets". Do you hate modal windows as much as I do? Sometimes, you need them.
However, this will freeze up your application until the user deals with the modal
panel. Apple has taken a fresh look at modality and came up with this realization: there
is no need to stop user interaction except in the window that requires modal attention.
A sheet is a drop down window that appears as if it is coming out of the title bar of the
document window:
Figure 5. The simplicity and elegance of sheets.
The rest of your application remains available for user interaction. In Developer
Preview 3, these "sheets" are only available in the Cocoa frameworks, but Carbon
support will hopefully be forthcoming. Implementing sheets is quite easy - you simply
add the new parameter relativeToWindow:(NSWindow *)aWindow to your old favorite
modal invoking methods such as runModal and NSRunAlertPanel family.
Supporting Mac OS X Sever and Mac OS X
Since many developers have wanted to be able to ship applications for both Mac OS X
Server and Mac OS X, and it's tricky to maintain multiple source code trees in synch,