Code by Kevin

Code by Kevin, Programming, code, business, and other pursuits

Your Host
Kevin Walzer, software developer.


Subscribe to RSS Feed
Get a syndicated feed of my weblog.



Privacy Policy

Site design: Skeleton


Tue, 10 Jun 2008

Porting a Carbon toolkit to Cocoa: the example of Qt

Today I was playing with an alpha release of Qt, the cross-platform GUI toolkit, that is built on top of Apple's Cocoa development framework. Trolltech, Qt's developer, has been porting Qt to run on Cocoa instead of Carbon in order to allow its customers to compile high-performance 64-bit applications on the Mac; last year Apple announced that Cocoa would support 64-bit, but not Carbon.

A lot of people (myself included) have complained about Apple's decisions on Carbon. It seemed to us that pushing Cocoa development so strongly would require Carbon developers to do substantial rewrites of their programs as Cocoa applications, but this wouldn't necessarily yield any user-visible benefits. It would amount to a lateral move to the platform favored by Apple, with a better chance of keeping up with the direction of the OS X platform--and nothing else.

Trolltech, to its credit, listened to its Mac customers--they want 64-bit capability. So the company has plunged ahead with its port of Qt to Cocoa: it is the first cross-platform toolkit to outline a definite roadmap to a Cocoa port, and to release working code as the fruits of that effort.

So the alpha release of Cocoa Qt has 64-bit capability. Good. What else has improved, or even changed? The answer is what I suspected: Nothing. The applications look and behave the same as before. When the Cocoa port hits release-quality, end users won't notice anything different at all.

Here's an example of a Trolltech application running on top of Carbon:

And here's an example of a Trolltech application running on top of Cocoa:

If you look closely at these screen shots, they look pretty much the same. The main difference is that the Cocoa application (Qt Assistant) uses the Mac-style unified toolbar, rather than Trolltech's own cross-platform toolbar. But that can't be attributed to Cocoa--the unified toolbar is available to both Carbon and Cocoa applications, and the Carbon version of Qt Assistant also used the unified toolbar.

What Trolltech is doing is re-implmenting its own cross-platform Qt codebase with Cocoa as its foundation, rather than Carbon. When developers use Qt, they use Qt code to build their programs and don't call the underlying, platform-specific code (on the Mac, "QWindow" will presumably call "NSWindow"; I'm not sure what the corresponding calls on Windows and Unix/Linux would be)--that's the purpose of using a cross-platform toolkit. To end users, the fact that Qt's windows are being drawn to the screen by the Cocoa frameworks rather than the Carbon frameworks means nothing.

Of course, to developers and Trolltech itself, there is now one large distinction between Cocoa and Carbon: the former is a better hedge against obsolescence on the Mac. That means the Mac remains a viable platform for them. That is the only reason to move to Cocoa.

[/general] permanent link

OS X and Unix: Unix as a development framework

One of the most prevalent arguments that Apple makes for its Cocoa development frameworks is how easy Cocoa makes things for developers:

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

In short, while it may take some time to learn the Cocoa frameworks, that effort is richly rewarded down the road by easier and faster application development, and more elegant products.

I have no doubt that this is true. Many of the Mac applications I use daily--such as Safari, Mail, Vienna, and others--are written in Cocoa. They are clean, responsive, well-designed, and a pleasure to use.

Despite the undeniable value of the Cocoa frameworks, however--and despite Apple's promotion of those development frameworks as the preferred method of development on OS X--I'd like to suggest they are not the only route to powerful and even elegant Mac programs. There's a hidden jewel within OS X that provides a different, yet equally empowering, development environment: OS X's Unix underpininings.

Beneath the shiny Cocoa/Aqua surface, OS X is a certified Unix product--which means it has to pass a large battery of tests to be compliant with the rigorous standards of the Open Group, the organization that holds the actual Unix trademark. Apple has continually upgraded and updated the Unix layer of OS X over the years, and passed the tests for Unix certification with the release of Leopard.

What difference does this make for developers? Isn't Unix the ugly, geeky, command-line-oriented, user-unfriendly operating system that is the antithesis of Mac ease-of-use?

Well, yes and no. It is true that many, even most, Mac users have no interest in typing in Unix commands in Terminal. To a user accustomed to pointing-and-clicking a mouse and getting visual feedback, such commands are hard to remember, hard to understand, and hard to follow. As Eric Raymond, a prominent Unix developer and writer about software development practices, notes in his book The Art of Unix Programming:

The CLI style of early Unix has retained its utility long after the demise of teletypes for two reasons. One is that command-line and command-language interfaces are more expressive than visual interfaces, especially for complex tasks. The other is that CLI interfaces are highly scriptable--they readily support the combining of programs....Usually (though not always) CLIs have an advantage in concision as well. The disadvantage of the CLI style, of course, is that it almost always has high mnemonic load (low ease) and usually has low transparency. Most people (especially nontechnical end users) find such interfaces relatively cryptic and difficult to learn.

Despite this difficulty, these small, cryptic, narrowly-focused command-line programs still offer an incredibly powerful resource for developers. In Unix, it is trivially easy to link disparate programs into a larger whole, either via shell scripts, a GUI, or simply calling such programs from another command-line program. If the Mac development philosophy, as embodied in Cocoa, means mastering a complex but powerful framework, using the framework to provide the building blocks of your application, and then authoring the code and functionality that is unique to your application, the Unix development philosophy focuses on understanding how to link together the small, focused command-line tools of Unix into larger wholes, and authoring the code and functionality that is unique to your application.

Raymond quotes Doug McIlroy, who pioneered the concept of Unix pipes (a mechanism for communication between programs that allows the output of one program to be used as the input for another program), on the basics of the Unix approach to development: This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.

In short, just as Cocoa provides a framework, so too does the entire system of Unix provide a framework for Mac application development--rapid, powerful, Mac-native application development.

Raymond's The Art of Unix Programming has been a big influence on my thinking about Mac development. The idea that one can build large programs by chaining together many smaller ones, either with a GUI or another command-line program, is very cool--just as cool, in its way, as seeing what is possible with the Cocoa frameworks. I got my first exposure to the command-line five years ago, when I was trying to set up an iMac running OS X Server and had to edit a number of configuration files: all the documentation said to fire up Terminal and type in "sudo pico filename.txt." Huh? I had no idea what I was doing, but followed the instructions--and as I did more and more of this, I began playing around with the different command-line tools. In at least one instance, learning these command-line tools saved my server from being hacked.

But even as I saw the power of these tools, I also encountered frustration. They were hard to use, and required too much typing. It was in that observation that I saw a commercial opportunity: provide elegant Mac GUI's for these command-line tools. In doing this, I'm not the first: there's a long tradition of developers on Unix doing just this with GUI toolkits such as Tk, a powerful but lightweight GUI toolkit that first developed on Unix. (One of the most comman names for GUI applications on Unix is TkFoo, in recognition that a Tk GUI is driving a command-line tool named "foo.") A number of Cocoa developers on the Mac have done this with various command-line tools as well: it's not uncommon to see Cocoa GUI's, written in Objective-C or AppleScript Studio, for simple command-line tasks. (I've lost count of how many free tools there are for packing and unpacking zip file archives, for instance.)

Although I also use Tk as my toolkit because of its combination of simplicity and power, I'm trying to do more than assemble the latest iteration of "TkFoo." As Cocoa developers do with their framework, I'm trying to leverage the power of Unix to build elegant, sophisticated Mac programs. For example, my program PortAuthority provides a GUI for the MacPorts Unix software system on the Mac--but it's not a simple wrapper for the MacPorts command-line "port" tool. It begins by driving "port" and parsing its text output, but adds value by making it simple to browse MacPorts programs by category, something the MacPorts command-line program doesn't do; it also, via different command-line tools, the next version of PortAuthority will hook into such Mac-specific technologies as Growl for user notifications.

Another example: I am currently developing a file search tool with Growl, Quick Look, and Core Image integration, as well as other features, all achieved with command-line tools. The GUI provides the high-level view of the data and drives the various command-line utilities under the hood to get the requested data.

It's important to understand that although I'm using a GUI toolkit that originated on Unix, and using a design philosophy that differs from Cocoa programmers, I'm still striving as much as possible to meet Mac user expectations, something I've written about before. Using a toolkit other than Apple's featured one does not relieve me of my obligation to make my programs meet Mac user expectations, adhere to the platform's recommended UI guidelines, and so on. I do this, to the outmost extent permitted by the toolkit and by my own skill. Based on the sales my programs are achieving, I think I'm doing a decent job on that front.

To a large degree, my perspective on Mac development is a hybrid one, joining both the Unix and the traditional Mac approach. Raymond summarizes these two perspectives well:

Macintosh programmers are all about the user experience. They're architects and decorators. They design from the outside in, asking first "What kind of interaction do we want to support" and then building the application logic behind it to meet the demands of the user-interface design....By contrast, Unix people are all about infrastructure. We design from the inside out, building mighty engines to solve abstractly defined problems...We then wrap thin and often profoundly ugly interfaces around the engines.

I want to leverage the powerful engines, but I still want my applications to be all about the user experience.

I am troubled by Apple's promotion of Cocoa to the denigration of other GUI frameworks; in particular, Apple's relegation of Carbon to second-class status presents difficulties for developers using toolkits built on top of Carbon, which includes Tk. (Fortunately, Jason Slack's plan to port Tk to run on top of Cocoa mitigates this concern. Once Jason has released a stable port of Tk-Cocoa, I will even be able to claim, if only technically, that my programs are Cocoa applications.)

Despite my misgivings about the privileging of Cocoa, however, I must give Apple full credit for the investments and improvements it has made in the Unix components of OS X. This includes providing command-line, Unix-style access to many Mac-specific technologies, such as Core Image and Quick Look. Without the power of Unix under the hood of Mac OS X, my own work as a developer wouldn't be possible.

Not only does Unix provide a powerful framework for Mac development--it also provides a powerful platform for Unix developers to pursue commercial development opportunities. On other Unix platforms, most users don't pay for the software they use--the culture expects free software, both in the sense of free to tinker with the source code, and free as in "no-cost." The Mac culture, however, is one where users support independent commercial developers. On another Unix platform, it's unlikely that I'd earn any income at all from my software work.

It would be nice if Apple promoted Unix as heavily as they promote Cocoa. But the fact that they make Unix a first-class development platform on OS X (unlike, for instance, Carbon) is good enough for me.

[/general] permanent link