Rss

Archives for : javascript

Show & Tell @ CocoaHeads Ann Arbor

Tomorrow (Thursday) night at CocoaHeads Ann Arbor, Dave Koziol of Arbormoon Software, Dan Hibbitts, and I will be showing off the iPad project we’ve been working on for the last few months.

And then you’ll understand why I’ve been complaining so much about JavaScript on Twitter recently.

Questions welcomed.

It’s like “Glee” with coding instead of singing

Like a lot of old programmers — “when I was your age, we used teletypes, and line numbers, and couldn’t rely on the backspace key” and so on — I sometimes wonder how different it is growing up as a young computer programmer today. Back in the 80’s we had BBSs, but no public internet… a smattering of computer books, but no O’Reilly… and computer science as an academic discipline, but further removed from what you’d actually do with what you’d learned.

Developers my age grew up on some kind of included programming environment. Prior to the Mac, every computer came with some kind of BASIC, none of which had much to do with each other beyond PRINT, GOTO, and maybe GOSUB. After about the mid-80’s, programming became more specialized, and “real” developers would get software development kits to write “real” applications, usually in some variant of C or another curly-brace language (C++, C#, Java, etc.).

But it’s not like most people start with the formal tools and the hard stuff, right? In the 80’s and 90’s, there were clearly a lot of young people who picked up programming by way of HyperCard and other scripting environments. But those have largely disappeared too.

So what do young people use? When I was editing for O’Reilly’s ONJava website, our annual poll of readers revealed that our under-18 readership was effectively zero, which meant that young people either weren’t reading our site, or weren’t programming in Java. There has to be some Java programming going on at that age — it is the language for the Advanced Placement curriculum in American high schools, after all — but there’s not a lot of other evidence of widespread Java coding by the pre-collegiate set.

I’ve long assumed that where young people really get their start today is in the most interesting and most complete programming environment provided on every desktop computer: the web browser. I don’t want to come off like a JavaScript fanboy — my feelings about it are deeply mixed — but the fact remains that it is freely and widely available, and delivers interesting results quickly. Whereas 80’s kids would write little graphics programs in Applesoft BASIC or the obligatory 10 PRINT "CHRIS IS GREAT" 20 GOTO 10, these same kinds of early programming experiences are probably now being performed with the <canvas> tag and Document.write(), respectively. In fact, the formal division of DOM, CSS, and JavaScript may lead the young programmer to a model-view-controller mindset a lot sooner than was practical in your local flavor of BASIC.

The other difference today is that developers are much better connected, thanks to the internet. We didn’t used to have that, so the programmers you knew were generally the ones you went to school with. I was lucky in this respect in that the guys in the class above me were a) super smart, and b) very willing to share. So, 25 years later, this will have to do as a belated thank you to Jeff Dauber, Dean Drako, Drew Shell, Ed Anderson, Jeff Sorenson, and the rest of the team.

Did I say “team”? Yeah, this is the other thing we used to do. We had a formal computer club as an activity, and we participated in two forms of programming contests. The first is the American Computer Science League — which I’m releived to see still exists — which coordinated a nation-wide high school computer science discovery and competition program, based on written exams and proctored programming contests. The cirriculum has surely changed, but at least in the 80’s, it was heavily math-based, and required us to learn non-obvious topics like LISP programming and hexadecimal arithmetic, both of which served me well later on.

Our school also participated in a monthly series of programming contests with other schools in the suburban Detroit area. Basically it worked like this: each team would bring one Apple II and four team members and be assigned to a classroom. At the start of the competition, each team would be given 2-4 programming assignments, with some sample data and correct output. We’d then be on the clock to figure out the problems and write up programs, which would then be submitted on floppy to the teachers running the contest. Each finished program scored 100 points, minus 10 points for every submission that failed with the secret test data, and minus 1 point for every 10 minutes that elapsed.

I have no idea if young people still do this kind of thing, but it was awesome. It was social, it was practical, it was competitive… and it ended with pizza from Hungry Howie’s, so that’s always a win.

Maybe we don’t need these kinds of experiences for young programmers today. Maybe a contrived contest is irrelevant when a young person can compete with the rest of the world by writing an app and putting it on the App Store, or by putting up a web page with all manner of JavaScript trickery and bling. Still, it’s a danger to get too tied to the concretes of today, the specifics of CSS animations and App Store code-signing misery. Early academic exercises like earning to count in hex, even if it’s to score points on a quiz, will likely pay off later.

The Other iOS Programming Language

My latest contract project has me doing a bunch of custom work with a UIWebView: we have XHTML content that we want to render in our app, but with some fairly extensive changes to its presentation, such as paginating the content like a book, and intercepting taps on links. Given the option of using and customizing the built-in WebKit rendering, versus parsing the XHTML myself, laying it out, etc., the choice was a no-brainer.

The trick, then, is in how to extend and customize the functionality. As a long-time curly-brace application developer, my natural instinct is to impose control from the Cocoa side, perhaps by subclassing UIWebView to achieve custom behavior (although this is specifically discouraged by the documentation), tying in delegates where possible, perhaps even employing some render hackery (like using an offscreen UIWebView and then blitting its pixels into some visible view). But this really isn’t the right way to do it: for starters, it still gives you no access to the DOM, which is where nearly all the value of your HTML content is.

I suspect younger readers already know what the right answer is: insert your own JavaScript, and work inside the UIWebView. This is pretty straightforward to do — you can load the HTML source into a string and then munge it as necessary, such as by strategically adding references to your own CSS stylesheets or JavaScript (.js) files, and then load that modified source into the UIWebView, along with an appropriate base URL to help resolve relative paths. I say this would be a natural conclusion for younger developers because I suspect that most young developers start with either Flash or JavaScript, as these environments deliver immediate visual results and aren’t hard to get into (plus, JavaScript is free). Developers my age sometimes wish that computers still came with an introductory programming environment like a flavor of BASIC or HyperCard, overlooking the fact that today’s dominant starter language is included with every browser.

What makes JavaScript programming practical in an iOS app is the method -[UIWebView stringByEvaluatingJavaScriptFromString:], which does exactly what the wordy method name says: it tells a UIWebView to execute arbitrary JavaScript contained in an NSString parameter, and return the result as an NSString. You can easily try it out on a UIWebView in your own application like so:


	[myWebView stringByEvaluatingJavaScriptFromString:
		@"alert ("hello JavaScript");"];

With this door opened between the JavaScript and Cocoa worlds, you have two-way access to the DOM and how it is rendered. For example, you can pull out the web view’s selected text by writing a simple JavaScript function, and calling it from Cocoa. Or slurp it all in by walking the DOM, appending all the textContent, and returning one big NSString. Or collect all the links with document.elementsByTagName('a') and index them in Cocoa.

But don’t stop there. With the richness of JavaScript, you can employ all the tricks you see in rich web applications, such as rewriting the DOM on the fly, scrolling around programmatically and finding element coordinates, etc. Plus, since you’re only running against one pseudo-browser (iOS’ built-in WebKit framework), you don’t have to work around the incompatibilities and quirks of multiple browsers like regular web developers do.

As I’ve worked on this project, I’ve settled into a “Render unto Caesar…” strategy. Meaning that anytime I need to access contents of the DOM, or change how it is rendered, I know I’m writing a JavaScript function, because that’s what owns the web content and its rendering. For the rest of the app, it’s still Cocoa.

There are hard parts, not the least of which is that fact that I’m still pretty green when it comes to JavaScript and messing around with the DOM. Mozilla Dev Center is a very useful resource for this, despite some search and link breakage, far more so than Apple’s Safari Dev Center.

The other problem is that debugging JavaScript in a UIWebView is notoriously difficult. Unlike desktop browsers, there is no “developer mode” you can drop into in order to inspect elements, see the results of your actions, or even log messages efficiently. Worse, the smallest syntax error will break execution of your function (and major syntax errors can break your whole .js file), so there is often little recourse but to jam alert() calls into your code just to see how far the interpreter gets before quietly dying. That said, iOS Safari behaves very much like its desktop equivalent, so it is possible to do some amount of development and debugging in desktop Safari’s developer mode, or the WebKit nightly build, before switching back to the UIWebView. That said, I only do this for extreme cases of debugging — I wouldn’t want to develop a bunch of new code against WebKit nightly only to find it doesn’t work the same way on the production version of iOS.

Anyone with a browser knows how rich web applications can be, and so you implicitly know that anything you can do in Safari can also be done inside a UIWebView. Sometimes it makes sense to do exactly that.