Kyle Neath wrote an excellent piece about the design process of GitHub for Mac. What’s more interesting is his concern about the Mac OS X/Cocoa framework as a whole, it’s the best criticize of Cocoa that I’ve seen for a while, I sincerely recommend any developer interested in Cocoa to read.
According to Kyle, a first-time Mac OS X designer/developer, Cocoa is dying for a framework. This argument feels a bit ironic since I came from the age when a bunch of Cocoa fanboys were labeled as the “Delicious Generation” who only wrote fancy good looking apps with no actual functionalities, while the good ‘ol Carbon guys looked so damn unattractive. Has it now come to the downfall of us Cocoa developers?1
Kyle’s main reasons for not liking Cocoa are as follows:
- Drawing in code is slow and painful. Images are easier to work with and result in more performant code.
- There is no layout engine for Cocoa. If you want two elements to rest side to side, you’ll need to calculate the pixel size of the text, padding, borders, margins — then manually position the next element.
- There is no styling engine in Cocoa. (To change the background color of a button for instance will require significant changes)
- Learning the differences between layer-backed views, layer-hosted views — understanding that you have to subclass everything — balancing delegates, weak connections, strong connections, KVC, view controllers, and notifications — understanding little intricacies like how AppKit flips
.xibs when it load them up or how hard it is to make one word in a sentence bold.
I will try to share some of my opinions about them, one by one.
Is draw in code slow and painful?
Being a low level graphics developer for so long, I know my opinion must be biased. But still, I’ve never felt drawing in Cocoa (or Cocoa Touch) to be slow, working with Core Graphics, Cocoa Drawing API and APIs like Core Text is quite pleasant actually. Drawing operations are always blazingly fast. I honestly couldn’t see a better way to solve these problems without resorting to low level. Yes, they are imperative APIs rather than declarative, yes, you have to do your
-drawRect: code cautiously. But low level drawing itself has never been a bottleneck for my programs. The real problems are scheduling what to draw and finding out when stuff is drawn.
So in my opinion, it’s not the drawing itself that’s slow and painful, but you need to have a thorough understanding of the graphics stack to be able to write efficient low level imperative drawing code. That’s a damn steep learning curve. That’s why very few people can write efficient yet complex drawing code even veterans like Loren Brichter recommend to “do your own drawing”.
However, there is no silver bullet. Cocoa Touch makes life a little bit easier by simplifying the view hierarchy and build with Core Animation from ground up. But to have butter smooth scrolling, you still need to do your own drawing cautiously. Apple did provide layer-based and layer-hosted views in Cocoa, but they are too conservative to re-architect the entire Cocoa view stack with Core Animation, that’s a pity but luckily you can always roll your own (as we always did).
Anyway, the best framework I can imagine is the one using a declarative API to construct most of the UI and leverage the full power of GPU, with flexibility to do custom drawing with an imperative API.
No layout engine for Cocoa?
Apparently, Apple is solving this with Cocoa Autolayout. Can’t say much about this (it’s in NDA) but it does look promising.
No styling engine in Cocoa?
Well well, this is controversial. On one hand people are complaining that UI in Mac OS X apps are not consistent anymore, on the other hand people detest Aqua and dream for change from the bottom of their heart. I can understand Kyle since he is more of a designer than a developer. With no doubt I think that’s a fair judgement, but it’s hard to justify whether the styling difficulty contributes to HIG consistency or drives people to the opposite side of it. As a user of Mac OS X I felt that UIs should be “semi-consistent”, or as John Gruber puts it eloquently: uniformity has been replaced by conformity.
Apple is acting slow and they can definitely improve on this. The solution doesn’t have to be very innovative, adding styling flexibilities here and there is no groundbreaking change. Cocoa Touch is not far superior either, there is still a lot of work to do if you don’t like the standard controls from UIKit. In contrast, my biased opinion would say that QML/Qt Quick appears to be a much more flexible solution, it’s XUL/Air/JavaFX/WPF done right. Though I am biased, who knows me well should know that I’m hard to convince as a low level graphics engineer.
Cocoa has complicated intricacies?
Yes, any framework survived more than 20 years will have some intricacies, that’s inevitable. Actually I’m surprised by the fact that so many of the NeXTSTEP APIs are still in good use. Come on, it’s a fast changing industry and you really need to be a genius to predict the trend in more than 10 years.
However, most of Kyle’s concerns came from his expectations: he expects to fit UIKit model as is into Cocoa but it didn’t work. It probably never will, as I said previously, Apple is conservative in that sense, for stable platform like Mac OS X, they tend to provide new options other than forcing everyone to adapt to the new model. That inherently complicates the framework, of course. Changes that us Cocoa developers applauded for can be seen as too cautious by iOS developers.
Anyway, I think it’s fair to say that Cocoa isn’t the best API for modern, dynamic UI, alternatives like Chameleon may eventually surpass it. Nevertheless, there is no easy path between both worlds, you either port the code to the new model (UIKit like) or adapt to the hybrid model (Cocoa like). For iOS developers, the former is definitely easier, but for us the latter seems to be a better option.
That’s it. I’m surprised that you can read my ramblings to this far 🙂
I’ve never labeled myself as part of the “Delicious Generation”, I will rather do something useful if it can’t be good looking at the same time. But still, it’s sad. ↩