SproutCore on iPhone: Cocoa-in-JavaScript Comes of Age

Apple’s other iOS app vector, the Open Web, is finally catching up.

There’s a reason that Cocoa, Apple’s flagship set of application development frameworks, is written, essentially, in C.

Cocoa, like any world-class framework, is a beast of abstraction: it exists to make the complex simple. Take Key Value Observing (KVO). This mainstay of MVC and related patterns allows you to bind two properties on two different, disparate objects, together. If one of them changes, the other one updates. This lets you do trivial things like change the background color when the user updates the setting, or crucial things like display data as it loads from a server.

It’s pretty hard to overstate the impact that KVO can have on your code. When values automatically stay synced, different parts of your application don’t need to know about each other. Separation of concerns, code sharing between applications, all kinds of Best Practices become Easy Practices. And, once you’ve set up your binding, triggering that cascade of updates is as simple as this:

[obj setValue:newValue forKey:@"propertyName"];

It’s like magic!

Of course it’s not actually magic, it’s abstraction at work, and it comes with a cost. That one easy line of code wraps dozens or hundreds of internal commands and complex data structures. All of the bound properties that need syncing, all of the observing methods that need calling, they all need to be tracked, updated, and properly disposed of when the time comes. So suddenly one simple command – a basic KVO setter – is triggering an invisible avalanche. Good abstractions come with the danger of allowing developers to run tons of code without the bother of having to write tons of code.

When you’ve got layers of abstraction serving as code multipliers like that, the underlying code needs to be fast. And it needs to be even faster to run on the iPhone, with its memory restrictions and puny CPU. So, with its eyes firmly on speed, Apple has bullheadedly refused to follow industry trends towards heavily interpreted languages. Even its experiment with garbage collection was canceled just a generation after it began. Cocoa remains Objective-C: a speedy superset of C, and as uninterpreted a language as you’ll find. And it needs to be, in order to stay fast when there’s so much abstraction in the air.

Pan over to JavaScript. It’s loosely-typed. It’s garbage-collected. It’s not even shipped around in semi-digested intermediate representations: it’s literally fed to the browser as raw text. For all of its vaunted flexibility, and for all of the billions of dollars that Google et al. have sunk into speeding it up, all of that comes with a healthy performance penalty. And it always will, no matter what the true believers say. But being slower than a speeding bullet doesn’t necessarily make you slow.

SproutCore, the granddaddy of JavaScript MVC frameworks, is Cocoa for the web. KVO and bindings are baked in at the lowest levels, and the SproutCore equivalent of our Cocoa setter from above – obj.set('propertyName', newValue); – triggers its own invisible, sophisticated, expensive avalanche.

That abstraction is extraordinarily powerful: SproutCore uses it to bring sophisticated application development strategies and sensibilities to the web application arena, a space which is often sorely lacking in them. A SproutCore application will have well-organized, well-segregated models, views and controllers, managed by a powerful state machine and tied together with the magic of KVO. In short, a SproutCore application will be an application. It just happens to run in the browser.

The reasons to choose the web for your applications, if you can, are myriad, and well-established: cross-platform compatibility, simple deployment, et cetera.  But note the caveat – “if you can”, and performance was one longstanding barrier. Eight years ago, JavaScript was too slow a language to allow for the valuable abstractions that a Cocoa-inspired framework needs. But Google marched its famous march towards faster JavaScript engines, and we’ve entered a golden era on the desktop.

The mobile space took a bit longer. When the iPhone debuted, its JavaScript engine was pathetic. Keep in mind that the web was Steve Jobs’ first choice for third-party apps, and is the company’s answer to anyone upset by App Store policies. For years, it was a laughably half-kept promise: Mobile Safari wasn’t fast enough to run the New York Times smoothly, much less handle deep layers of valuable, application-y abstractions.

Then came the iPhone 4S and we were almost there, and then came the iPhone 5, and finally Steve’s promise that we would have a non-curated, non-closed, cross-platform avenue to publish our apps on the iPhone came true. Applications, real ones with grownup application architectures, ones that just happen to be written in JavaScript and happen to run in a web browser, can finally run on your phone. And every generation’s CPU bump brings another JavaScript speed bump, handily meeting the performance needs for another swath of application classes.

C is faster than JavaScript, by a lot, and it always will be. But the goal isn’t supercomputer speeds. Most applications are not doing realtime video editing, breaking encryptions, or mining Bitcoin on the side. The raw speed of a line of code, or of a mathematical operation, isn’t now and wasn’t ever the point. The goalpost for most applications – the light word processing, light photo editing, local storage, and animations between screens – is set at the line on the field where performance begets headroom. Real applications need real application frameworks like SproutCore, and real application frameworks need enough performance to abstract, to hide deep complexity behind delightfully simple commands.

It’s 2014, and the iPhone can deliver. Time to start creating.