And on the iPhone there is this nifty object called UIWebView. Otherwise known as WebKit. Otherwise known as an embedded browser in your iPhone app.
And if you want a sexily awesome looking UI view, like the Today view of the Surf Report app (see right or free on AppStore) that was released on the AppStore recently, then the WebKit is just the best thing since the electric bread slicer for speed of development.
Holy grail of iPhone development?
Well, that’s what we thought. When I chatted with Dan Grigsby last week I mentioned there were good and bad things about the WebKit within an iPhone app.
This article is about good and bad things. The pros and cons. How we managed the integration of the two code-bases. And the answer to the big question: Would we do it again?
Radio is where ugly people go. Podcasts is where ugly, niche people go. It doesn’t get much uglier and nicher than talking about iPhone dev; and the tale of one desperate man X on a desperate journey Y with his desperate sidekick Z, where:
Dan Grigsby is the interviewer and post-production guy for the interview, and so it is entirely his handy work that it seems like I’m the only one talking for 15 minutes. The original interview took 4 hours and it was mostly him talking. He’s quite a chatterbox. I barely got a word in edgewise. 
Dan also created this list of “things we talked about”:
0:00: Migrations for SQLite
5:18: Getting Ruby onto an iPhone
5:59: Nu – Lisp-based language that sits atop Obj-C and would work on the iPhone
Everything to love about Ruby: the concise, powerful language; the sexy testing frameworks; and finally, the people.
Everything to love about Objective-C: hmmm; well…; and finally, its the only high-level language you can use to write iPhone apps.
On iPhone 2.0, to arrive on the 11th of July, you cannot run RubyCocoa. But you can run it on your Mac, so let’s use it to unit test your Objective-C classes. This tutorial shows you how to get started using a new project rbiphonetest [GitHub | Lighthouse | Google Group]
If you followed some of my recent tweets, this project was previously called “iphoneruby”. And alas, the screencast also calls it “iphoneruby” but that was a crap name. People thought it was a way to run Ruby on the iphone. I can’t do that yet. So, a far better name is ‘rbiphonetest’. [track on summize]
Even if you’ve never touched Objective-C, Cocoa, the iPhone SDK, nor RubyCocoa I recommend watching the video anyway. It should give you hope that if you make the transition to iPhone development you don’t have to go alone without Ruby: your trusty swiss army knife of language/libraries/tools.
To summarize the video, but change ‘iphoneruby’ to ‘rbiphonetest’, you install the framework via RubyGems:
sudo gem install rbiphonetest
Then change to your project’s folder and install the test framework:
Finally, for each generic, non-UIKit-framework-using class you want to test:
script/generate model WidgetModel
Then write your tests in test/test_widget_model.rb
Supported Cocoa & iPhone frameworks
The mysterious, magical premise upon which rbiphonetest depends is possibly erroneous: that your Objective-C class can be compiled and tested against your OS X/Intel frameworks, and if your tests pass you assume you can then compile and include your class with the the iPhone/ARM frameworks.
I’m willing to go with this assumption until its proven dangerously flawed by some angry 20-year veteran of NextStep/Cocoa/iPhone. But really, how different could NSString be on the iPhone versus your Mac?
Fortunately there is one way to check for significant differences between your available Mac-based frameworks, such as Cocoa, and the iPhone-based frameworks, such as UIKit. We need to compare the framework names, header files and method signatures.
So for example, you cannot currently unit test any class that depends on/includes the UIKit framework. Why? It doesn’t exist on your Mac, so the Mac/Intel compiler cannot link it in. We’re compiling and running our tests with RubyCocoa, which itself is built against the Mac/Intel frameworks, not the iPhone frameworks. Hell, Laurent doesn’t even own an iPhone [Laurent is the Apple-employee maintainer of RubyCocoa and the newer MacRuby]
Similarly, its no use including/linking the Cocoa framework into your Objective-C class. Why? It doesn’t exist on the iPhone. It has its own UI frameworks, collectively called ‘UIKit’.
So for the moment we cannot test UI-related, iPhone-API-specific code. But we can test generic Objective-C. That’s better than a kick in the teeth. Surely. I mean, in the teeth… that’d friggin’ hurt.
“Fair enough Dr Nic, so which frameworks can my code use and yet still unit test it with your oh-so-special test library thingy?” Keep your pants on, I’m getting there. [ref]
To the best of my ability, I’ve compared the two sets of frameworks and listed the available Frameworks that are available on both the iPhone and your Mac. There are about a dozen. The most important is called ‘Foundation’. It holds gold nuggets like ‘NSString’.
Note, this list doesn’t guarantee that any two framework classes – the iPhone and matching Mac framework – will behave the same. This list is compiled by finding the set of Frameworks with the same name on both platforms, e.g. Foundation.
Then it compares the set of public header files (Foundation.framework/Headers/*.h files) This comparison is by method signature. It pulls all lines from each header that start with + or – (+ is a class method and – is an instance method in Objective-C) and compares the two lists. If there is a single difference in the method signatures of the header files in the two platforms it is marked on the wiki page. You’ll need to look at the two header files yourself to see the differences. Some header files are ugly. C-based anything starts ugly and goes down from there, I think.
Python testing of iPhone Objective-C?
In the Python world there is PyObjC, a bridge-based twin to RubyCocoa. If you are a Python developer you could easily port this project to use PyObjC I would think. Ping me if you are attempting this and need any help.
I think this project can give Ruby developers a happy place to work from as they write their Objective-C/iPhone code. You still need to wire up your UI views and controller classes manually, but if you push all the “oooh that code really needs some tests” classes away from the UI-dependent frameworks then you can hook it up to rbiphonetest and write your tests in Ruby.
Currently the generator creates test/unit test stubs. I personally then add the Shoulda gem into my test_helper.rb for my apps. If an rspec and/or test/spec developer can help with adding support to the generators I’m certain the large rspec user-base would be happy campers.
Similarly, someone might like to investigate using MacRuby to run the tests instead of RubyCocoa. Fast tests vs slow tests. You choose.
Sometimes I re-read what I’ve written and notice things that don’t seem to make sense, but are in my vocabulary nonetheless. Yep, the things you learn living in Australia.
“Keep your pants on” – this seems to imply that until I mentioned otherwise you were about to take your pants off. Hardly relevant at any stage during this article, we’d both agree. Most code-based blog articles are “pants on”. This phrase means “don’t get upset”. You can try to figure out how you go from “don’t get upset” to “keep your pants on”. I have no idea.