<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dr Nic &#187; Iphone</title>
	<atom:link href="http://drnicwilliams.com/category/iphone/feed/" rel="self" type="application/rss+xml" />
	<link>http://drnicwilliams.com</link>
	<description>Ruby makes Rails, Javascript makes Ajax, Dr Nic makes Magic</description>
	<lastBuildDate>Tue, 01 Jun 2010 12:54:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>To WebKit or not to WebKit within your iPhone app?</title>
		<link>http://drnicwilliams.com/2008/11/10/to-webkit-or-not-to-webkit-within-your-iphone-app/</link>
		<comments>http://drnicwilliams.com/2008/11/10/to-webkit-or-not-to-webkit-within-your-iphone-app/#comments</comments>
		<pubDate>Mon, 10 Nov 2008 13:04:26 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Iphone]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Mocra]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=330</guid>
		<description><![CDATA[I know HTML. Its on my CV. Expert level. I also know CSS and a whole bunch of JavaScript. I can even do TDD with JavaScript. 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 [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2008/11/04/iphone-dev-podcast-about-fmdb-migration-manager-and-rbiphonetest/' rel='bookmark' title='Permanent Link: iPhone dev podcast about fmdb-migration-manager and rbiphonetest'>iPhone dev podcast about fmdb-migration-manager and rbiphonetest</a> <small>Radio is where ugly people go. Podcasts is where ugly,...</small></li><li><a href='http://drnicwilliams.com/2008/07/04/unit-testing-iphone-apps-with-ruby-rbiphonetest/' rel='bookmark' title='Permanent Link: Unit Testing iPhone apps with Ruby: rbiphonetest'>Unit Testing iPhone apps with Ruby: rbiphonetest</a> <small> Everything to love about Ruby: the concise, powerful language;...</small></li><li><a href='http://drnicwilliams.com/2006/09/11/prototype-call-dollar-on-string/' rel='bookmark' title='Permanent Link: Prototype: &#8220;element-id&#8221;.$() instead of $(&#8216;element-id&#8217;)'>Prototype: &#8220;element-id&#8221;.$() instead of $(&#8216;element-id&#8217;)</a> <small>The Prototype library gives us the $() operation for converting...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://mocra.com/projects/surfreport/"><img class="alignright" src="http://img.skitch.com/20081110-189ta9iaubfwxu1hke3r2rhcb.png" alt="Oakley's Surf Report"/></a></p>
<p>I know HTML. Its on my CV. Expert level. I also know CSS and a whole bunch of JavaScript. I can even do <a href="http://jsunittest.com">TDD with JavaScript</a>.</p>
<p>And on the iPhone there is this nifty object called <code>UIWebView</code>. Otherwise known as WebKit. Otherwise known as an embedded browser in your iPhone app.</p>
<p>And if you want a sexily awesome looking UI view, like the <strong>Today</strong> view of the <a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=295405621&amp;mt=8">Surf Report</a> app (see right or <a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=295405621&#038;mt=8">free on AppStore</a>) that was released on the AppStore recently, then the WebKit is just the best thing since the electric bread slicer for speed of development. </p>
<p>Holy grail of iPhone development?</p>
<p>Well, that&#8217;s what we thought. When I <a href="http://drnicwilliams.com/2008/11/04/iphone-dev-podcast-about-fmdb-migration-manager-and-rbiphonetest/">chatted with Dan Grigsby</a> last week I mentioned there were good and bad things about the WebKit within an iPhone app.</p>
<p>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?</p>
<p>Its probably wonderfully useful stuff to know.</p>
<p><span id="more-330"></span></p>
<h3 id="negatives">Negatives</h3>
<p>So first the downsides. It would be remiss of me to fill you full of unbounded promises of easy non-Objective-C victories in your iPhone dev, and not tone them down with a full bucket of wet reality.</p>
<p><strong>Its slow.</strong> When the WebKit is first loaded into memory, and we try to do this behind the scenes as soon as we get control of our app from the OS, it can take a good few seconds for your WebKit object to be available. You get notified of its readiness for action via the delegate:</p>
<pre>- (void)webViewDidFinishLoad:(UIWebView *)webView</pre>
<p><strong>Its slow.</strong> You&#8217;re running an interpreter (JavaScript runtime) on top of a device with a small CPU and small memory. Go figure.</p>
<p>This reminds me of the fabulous &#8220;two minor drawbacks&#8221; scene from the 80s British sci-fi comedy <a href="http://en.wikipedia.org/wiki/Red_Dwarf">Red Dwarf:</a></p>
<pre>CAT: Why don't we drop the defensive shields?
KRYTEN: A superlative suggestion, sir, with just two minor flaws.
  One, we don't have any defensive shields, and
  two, we don't have any defensive shields. Now I realise that,
  technically speaking, that's only one flaw but I thought
  it was such a big one it was worth mentioning twice.</pre>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/p-JfFYZHZLQ&#038;hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/p-JfFYZHZLQ&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p><strong>The JavaScript bridge does not appear to block the main thread.</strong> This is a good/bad thing. You can invoke JavaScript code within the WebKit via your native Objective-C code. </p>
<pre>[webview stringByEvaluatingJavaScriptFromString:@"loadData({some: 'data'})"];</pre>
<p>It seems to return control back to your Objective-C code before it has finished executing, so you may need to poll the JavaScript runtime with `isFinished();` calls if you need to know when its complete.</p>
<p>Annoyingly, the Apple documentation for this method suggests otherwise:</p>
<blockquote><p>JavaScript execution time is limited to 5 seconds for each top-level entry point. If your script executes for more than 5 seconds, Safari stops executing the script. This is likely to occur at a random place in your code, so unintended consequences may result. This limit is imposed because <strong>JavaScript execution may cause the main thread to block, so when scripts are running, the user is not able to interact with the webpage.</strong></p></blockquote>
<p>Quirky.</p>
<p><strong>The JavaScript bridge is one directional.</strong> From Objective-C/UIKit you can invoke JavaScript upon the WebKit and henceforth do wonderful things (as per example above).</p>
<p>From JavaScript you have no native nor nice way to invoke methods on Objective-C objects, like you can in the Cocoa implementation of embedded WebKits. What you can do is use custom HTTP protocols, such as <code>surfreport://</code>, to give the OS a way for the webkit to communicate with your app. </p>
<p>We used this for &#8216;Related Photos&#8217; buttons on some news and athlete&#8217;s pages. When you click a button in the webkit, it attempts to redirect to a <code>surfreport://</code> url. The Objective-C code (your `UIApplicationDelegate`) is notified of this, hides the webkit, and displays the related photos using native UI elements. But we could do anything. Your `UIApplicationDelegate` needs to implement the follow method to receive these requests:</p>
<pre>- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url</pre>
<p>Alternately, you could use JavaScript to invoke this url, possible, via an Ajax call. Haven&#8217;t tried it. Might work. Either way, its a dirty hack, and a very annoying situation given that in Cocoa development there is a beautiful two-way bridge. I want that.</p>
<p><strong>Multiple languages in one project.</strong> Whilst we mainly just wanted to take a static HTML file, and dynamically update various elements with application data (e.g. the surf and weather conditions in the example above), we needed to do that via JavaScript. </p>
<p>We came up with a consistent API <code>loadData(json)</code> for all pages, as discussed below; yet when something displayed incorrectly we now had an extra possible point of failure: JavaScript, Objective-C, and the original web service data source (e.g. the <a href="http://www.surfline.com/" title="Surfline">Surfline</a> data for live updates). </p>
<p>To help isolate issues, we used JavaScript unit testing and a layer of &#8220;fixtures&#8221; or samples of JSON that might be sent from Objective-C to JavaScript. The tests passed against the fixtures; so if a QA error appeared in the app, we first checked the JSON being sent against the fixtures schema to isolate whether it was a JavaScript error or a data format error. It happened sufficiently often that its worth raising here.</p>
<h3 id="webkit_for_rapid_prototyping">WebKit for rapid prototyping</h3>
<p>Nonetheless, the WebKit exists and it is awesome at rendering HTML and CSS, with access to the powerful CSS3 transformations and webkit-specific bonus features.</p>
<p>It is highly likely that your designer can make something beautiful looking in Photoshop and cut it up into HTML + CSS. Comparatively, its highly unlikely they can cut it up into native Objective-C code.</p>
<p>So in the initial phases of application development/prototyping, the WebKit is a sweet option to give the designer on your team direct, immediate access to building the app. If performance is an issue, you later replace it with native UI elements.</p>
<h3 id="code_layout_and_samples">Code layout and samples</h3>
<p>In our Xcode project, the structure we use for including HTML and associated assets into our apps is:</p>
<pre>
Classes/           - normal Objective-C .m/.h files
Html/src           - HTML, CSS, and JavaScript files including libraries like jQuery
Html/test          - JavaScript tests
Html/test/fixtures - expected JSON formats to be sent from Objective-C to loadData methods
</pre>
<p><img class="alignright" src="http://img.skitch.com/20081104-xe4b6xpegf2gx2fkm6cj878wjk.png" alt="html and assets"/></p>
<p>These aren&#8217;t Xcode Groups, rather normal filesystem folders. In the Xcode project, the <code>Html/test</code> files are not included nor bundled with the app. The files in <code>Html/src</code> are included in the &#8220;Copy Bundle Resources&#8221; of the Target (see image) and also linked into the project via a sub-group of &#8220;Resources&#8221;, so they can be easily accessed within the project.</p>
<p>But when I did the HTML/JavaScript development I worked from the command-line and TextMate, and lived entirely inside the <code>Html/</code> folder.</p>
<p>For each static HTML page, such as the &#8216;Today&#8217; view above, there will probably be the following files:</p>
<pre>
Html/src/today.html
Html/src/today.css
Html/src/today.js
Html/src/jquery.min.js
Html/test/unit/today_test.html
</pre>
<p>The WebKit will display <code>today.html</code>, which uses normal <code>&lt;link&gt;</code>/<code>&lt;script&gt;</code> to pull in the <code>.css</code> and <code>.js</code> assets. You can quickly see what the page will look like, even before integration into your app, by loading it into the iPhone Simulator (launch the simulator and drag the file in), or even Safari 3.</p>
<p>We settled on a standard API for the primary call from Objective-C into JavaScript: <code>loadData(json)</code>. Bare-bones, this method starts off looking like:</p>
<pre>// This function is called from Objective-C-land to apply
// the surf information to the HTML template
// +data+ is a hash of key -> value
function loadData(data) {
    $('.data').html('N/A');
    $('img.image_data').removeAttr('src');

    // Assume that any data key can be copied into any HTML element with the same ID
    for (var key in data) {
        var value = data[key];
        var value_exists = fieldExists(value);
        var data_value = value_exists ? value : 'N/A';
        var img_src_value = value_exists ? value : 'unknown';
        $('#' + key).
            filter('.data').html(data_value).end().
            filter('.image_data').attr('src', key + '_' + img_src_value + '.png');
    };
}
</pre>
<p>What it does is take a <code>data</code> hash like <code>{ surf_height_amount: '2-3', surf_height_unit: 'ft' }</code> and HTML like:</p>
<pre>&lt;div id="surf_size">
  &lt;span class="data" id="surf_size_amount">&lt;/span>
  &lt;span class="data" id="surf_size_unit">&lt;/span>
&lt;/div>
</pre>
<p>And the <code>loadData</code> method updates it to:</p>
<pre>&lt;div id="surf_size">
  &lt;span class="data" id="surf_size_amount">2-3&lt;/span>
  &lt;span class="data" id="surf_size_unit">ft&lt;/span>
&lt;/div>
</pre>
<p>So we can build arbitrarily complex HTML templates. By allocating meaningful element IDs (<code>surf_height_amount</code>) and tagging the template elements with <code>class="data"</code> we have a simple mechanism for Objective-C to update the HTML. As the template gets more complex, then so too does the <code>loadData</code> method.</p>
<h3 id="would_we_do_it_again">Would we do it again?</h3>
<p>Yes.</p>
<p>The WebKit isn&#8217;t the holy grail for non-Objective-C developers, but if your grand-poobar level skills are in JavaScript and HTML, and your Objective-C/iPhone skills are still catching up, then its a wonderful prototyping platform. Especially for static, complicated displays of data. Especially if that data includes HTML content from an external feed which needs to be rendered.</p>
<p>For Oakley&#8217;s Surf Report app, Anthony is toying with replacing some of the WebKit usage with native UI elements (normal <code>UITableView</code> with custom <code>UITableViewCell</code>s) so that we can get back those precious seconds and give them to the user as a Christmas present.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2008/11/04/iphone-dev-podcast-about-fmdb-migration-manager-and-rbiphonetest/' rel='bookmark' title='Permanent Link: iPhone dev podcast about fmdb-migration-manager and rbiphonetest'>iPhone dev podcast about fmdb-migration-manager and rbiphonetest</a> <small>Radio is where ugly people go. Podcasts is where ugly,...</small></li><li><a href='http://drnicwilliams.com/2008/07/04/unit-testing-iphone-apps-with-ruby-rbiphonetest/' rel='bookmark' title='Permanent Link: Unit Testing iPhone apps with Ruby: rbiphonetest'>Unit Testing iPhone apps with Ruby: rbiphonetest</a> <small> Everything to love about Ruby: the concise, powerful language;...</small></li><li><a href='http://drnicwilliams.com/2006/09/11/prototype-call-dollar-on-string/' rel='bookmark' title='Permanent Link: Prototype: &#8220;element-id&#8221;.$() instead of $(&#8216;element-id&#8217;)'>Prototype: &#8220;element-id&#8221;.$() instead of $(&#8216;element-id&#8217;)</a> <small>The Prototype library gives us the $() operation for converting...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2008/11/10/to-webkit-or-not-to-webkit-within-your-iphone-app/feed/</wfw:commentRss>
		<slash:comments>42</slash:comments>
		</item>
		<item>
		<title>iPhone dev podcast about fmdb-migration-manager and rbiphonetest</title>
		<link>http://drnicwilliams.com/2008/11/04/iphone-dev-podcast-about-fmdb-migration-manager-and-rbiphonetest/</link>
		<comments>http://drnicwilliams.com/2008/11/04/iphone-dev-podcast-about-fmdb-migration-manager-and-rbiphonetest/#comments</comments>
		<pubDate>Mon, 03 Nov 2008 23:51:18 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Interviews]]></category>
		<category><![CDATA[Iphone]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[Link]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=320</guid>
		<description><![CDATA[Radio is where ugly people go. Podcasts is where ugly, niche people go. It doesn&#8217;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: X = Dr Nic Y = iPhone development Z = Ruby [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2008/11/10/to-webkit-or-not-to-webkit-within-your-iphone-app/' rel='bookmark' title='Permanent Link: To WebKit or not to WebKit within your iPhone app?'>To WebKit or not to WebKit within your iPhone app?</a> <small> I know HTML. Its on my CV. Expert level....</small></li><li><a href='http://drnicwilliams.com/2008/07/04/unit-testing-iphone-apps-with-ruby-rbiphonetest/' rel='bookmark' title='Permanent Link: Unit Testing iPhone apps with Ruby: rbiphonetest'>Unit Testing iPhone apps with Ruby: rbiphonetest</a> <small> Everything to love about Ruby: the concise, powerful language;...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Radio is where ugly people go. Podcasts is where ugly, niche people go. It doesn&#8217;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:</p>
<ol>
<li>X = Dr Nic</li>
<li>Y = iPhone development</li>
<li>Z = Ruby</li>
</ol>
<p>From the <a href="http://www.mobileorchard.com/iphone-development-podcast-2-dr-nic-williams/">Mobile Orchard news desk</a>:</p>
<p><img height="150" width="113" class="alignleft frame" alt="drnic.png" src="http://www.mobileorchard.com/wp-content/uploads/2008/11/drnic.png"/></p>
<blockquote><p>Dr. Nic talks about his <a href="http://github.com/drnic/fmdb-migration-manager">migration manager</a> for updating SQLite iPhone databases, trying to get Ruby onto an iPhone, using <a href="http://github.com/drnic/rbiphonetest/">Ruby to unit-test Objective-C</a> iPhone code, his company <a href="http://mocra.com">Mocra</a>, and the Mobile Orchard Podcast’s lavish recording studios.</p></blockquote>
<p>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&#8217;m the only one talking for 15 minutes. The original interview took 4 hours and it was mostly him talking. He&#8217;s quite a chatterbox. I barely got a word in edgewise. [1]</p>
<p>Dan also created this list of &#8220;things we talked about&#8221;:</p>
<ol>
<li>0:00: Migrations for SQLite</li>
<li>5:18: Getting Ruby onto an iPhone</li>
<li>5:59: Nu &#8211; Lisp-based language that sits atop Obj-C and would work on the iPhone</li>
<li>7:37: Unit testing Obj-C from Ruby</li>
<li>8:12: Webkit UIs</li>
<li>12:31: Mocra / “Used my blog for evil”</li>
</ol>
<p><a href="http://www.mobileorchard.com/iphone-development-podcast-2-dr-nic-williams/"><img alt="" src="http://img.skitch.com/20081103-ft9pt2tfg8pekbj7hu2y8jijb2.png" title="Mobile Orchard" class="alignright" width="354" height="107" /></a><br />
Go to <a href="http://www.mobileorchard.com/iphone-development-podcast-2-dr-nic-williams/">Mobile Orchard</a> (or Mobile Awkward it is accidently called at the end of the interview) to <a href="http://www.mobileorchard.com/iphone-development-podcast-2-dr-nic-williams/">cop a listen</a>.</p>
<p>[1] This paragraph starts well and ends with blatant falsehoods.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2008/11/10/to-webkit-or-not-to-webkit-within-your-iphone-app/' rel='bookmark' title='Permanent Link: To WebKit or not to WebKit within your iPhone app?'>To WebKit or not to WebKit within your iPhone app?</a> <small> I know HTML. Its on my CV. Expert level....</small></li><li><a href='http://drnicwilliams.com/2008/07/04/unit-testing-iphone-apps-with-ruby-rbiphonetest/' rel='bookmark' title='Permanent Link: Unit Testing iPhone apps with Ruby: rbiphonetest'>Unit Testing iPhone apps with Ruby: rbiphonetest</a> <small> Everything to love about Ruby: the concise, powerful language;...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2008/11/04/iphone-dev-podcast-about-fmdb-migration-manager-and-rbiphonetest/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Unit Testing iPhone apps with Ruby: rbiphonetest</title>
		<link>http://drnicwilliams.com/2008/07/04/unit-testing-iphone-apps-with-ruby-rbiphonetest/</link>
		<comments>http://drnicwilliams.com/2008/07/04/unit-testing-iphone-apps-with-ruby-rbiphonetest/#comments</comments>
		<pubDate>Thu, 03 Jul 2008 19:26:02 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Gems]]></category>
		<category><![CDATA[Iphone]]></category>
		<category><![CDATA[Link]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/?p=287</guid>
		<description><![CDATA[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&#8230;; 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 [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2010/06/01/validate-and-save-your-ruby-in-textmate-with-secret-rubinus-superpowers/' rel='bookmark' title='Permanent Link: Validate and Save your Ruby in TextMate &#8211; with secret Rubinus superpowers'>Validate and Save your Ruby in TextMate &#8211; with secret Rubinus superpowers</a> <small>In some TextMate bundles, if you save a file it...</small></li><li><a href='http://drnicwilliams.com/2009/03/30/closing-in-on-the-dream-one-click-to-deploy-rails-apps/' rel='bookmark' title='Permanent Link: Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;'>Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;</a> <small> Got a simple app you want to build? Allocate...</small></li><li><a href='http://drnicwilliams.com/2008/12/11/future-proofing-your-ruby-code/' rel='bookmark' title='Permanent Link: Future proofing your Ruby code. Ruby 1.9.1 is coming.'>Future proofing your Ruby code. Ruby 1.9.1 is coming.</a> <small> Bugger. I&#8217;m a Ruby monogamist. I use the Ruby...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img src="http://img.skitch.com/20080703-mqpqqhdk4e49x3yhhb8t2g9rjg.jpg" alt="rbiphonetest logo" style="float: right" /></p>
<p>Everything to love about <strong>Ruby</strong>: the concise, powerful language; the sexy testing frameworks; and finally, the people.</p>
<p>Everything to love about <strong>Objective-C</strong>: hmmm; well&#8230;; and finally, its the only high-level language you can use to write iPhone apps.</p>
<p>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&#8217;s use it to unit test your Objective-C classes. This tutorial shows you how to get started using a new project <a href="http://github.com/drnic/rbiphonetest/">rbiphonetest</a> [<a href="http://github.com/drnic/rbiphonetest">GitHub</a> | <a href="http://drnic.lighthouseapp.com/projects/13763-rbiphonetest">Lighthouse</a> | <a href="http://groups.google.com/group/rbiphonetest">Google Group</a>]</p>
<p>If you followed some of my <a href="http://summize.com/search?q=iphoneruby">recent tweets</a>, this project was previously called &#8220;iphoneruby&#8221;. And alas, the screencast also calls it &#8220;iphoneruby&#8221; but that was a crap name. People thought it was a way to run Ruby on the iphone. I can&#8217;t do that yet. So, a far better name is &#8216;rbiphonetest&#8217;. [track on <a href="http://summize.com/search?q=rbiphonetest">summize</a>]</p>
<p>Even if you&#8217;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&#8217;t have to go alone without Ruby: your trusty swiss army knife of language/libraries/tools.</p>
<p>The screencast is also available in <a href="http://drnicwilliams.com/wp-content/uploads/2008/06/rbiphonetest-introduction.mov">high-def video</a> (55Mb QuickTime)</p>
<p><object width="550" height="393"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id=1262916&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=01AAEA&amp;fullscreen=1" /><embed src="http://www.vimeo.com/moogaloop.swf?clip_id=1262916&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=01AAEA&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="550" height="393"></embed></object><br /><a href="http://www.vimeo.com/1262916?pg=embed&amp;sec=1262916">Unit Testing iPhone apps using Ruby</a> from <a href="http://www.vimeo.com/user289979?pg=embed&amp;sec=1262916">Dr Nic</a> on <a href="http://vimeo.com?pg=embed&amp;sec=1262916">Vimeo</a>.</p>
<h2 id="installation_and_usage">Installation and Usage</h2>
<p>To summarize the video, but change &#8216;iphoneruby&#8217; to &#8216;rbiphonetest&#8217;, you install the framework via RubyGems:</p>
<pre>sudo gem install rbiphonetest</pre>
<p>Then change to your project&#8217;s folder and install the test framework:</p>
<pre>rbiphonetest .</pre>
<p>Finally, for each generic, non-UIKit-framework-using class you want to test:</p>
<pre>script/generate model WidgetModel</pre>
<p>Then write your tests in <code>test/test_widget_model.rb</code></p>
<h2 id="supported_cocoa_iphone_frameworks">Supported Cocoa &amp; iPhone frameworks</h2>
<p>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.</p>
<p>I&#8217;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?</p>
<p>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.</p>
<p>So for example, you cannot currently unit test any class that depends on/includes the UIKit framework. <em>Why?</em> It doesn&#8217;t exist on your Mac, so the Mac/Intel compiler cannot link it in. We&#8217;re compiling and running our tests with RubyCocoa, which itself is built against the Mac/Intel frameworks, not the iPhone frameworks. Hell, <a href="http://chopine.be/lrz/">Laurent</a> doesn&#8217;t even own an iPhone <img src='http://drnicwilliams.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  [Laurent is the Apple-employee maintainer of <a href="http://rubycocoa.sourceforge.net/HomePage">RubyCocoa</a> and the newer <a href="http://trac.macosforge.org/projects/ruby/wiki/MacRuby">MacRuby</a>]</p>
<p>Similarly, its no use including/linking the Cocoa framework into your Objective-C class. <em>Why?</em> It doesn&#8217;t exist on the iPhone. It has its own UI frameworks, collectively called &#8216;UIKit&#8217;.</p>
<p>So for the moment we cannot test UI-related, iPhone-API-specific code. But we can test generic Objective-C. That&#8217;s better than a kick in the teeth. Surely. I mean, in the teeth&#8230; that&#8217;d friggin&#8217; hurt.</p>
<p>&#8220;Fair enough Dr Nic, so which frameworks <em>can</em> my code use and yet still unit test it with your oh-so-special test library thingy?&#8221; Keep your pants on, I&#8217;m getting there. [<a href="#keep-your-pants-on">ref</a>]</p>
<p>To the best of my ability, I&#8217;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 &#8216;Foundation&#8217;. It holds gold nuggets like &#8216;NSString&#8217;. </p>
<p>The list of <a href="http://github.com/drnic/rbiphonetest/wikis/platform-differences">platform differences</a> is on the wiki as a reference.</p>
<p>Note, this list doesn&#8217;t guarantee that any two framework classes &#8211; the iPhone and matching Mac framework &#8211; will behave the same. This list is compiled by finding the set of Frameworks with the same name on both platforms, e.g. Foundation.</p>
<p>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 &#8211; (+ is a class method and &#8211; 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&#8217;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.</p>
<h2 id="python_testing_of_iphone_objective_c">Python testing of iPhone Objective-C?</h2>
<p>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.</p>
<h2 id="summary">Summary</h2>
<p>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 &#8220;oooh that code really needs some tests&#8221; classes away from the UI-dependent frameworks then you can hook it up to rbiphonetest and write your tests in Ruby.</p>
<p>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&#8217;m certain the large rspec user-base would be happy campers.</p>
<p>Similarly, someone might like to investigate using MacRuby to run the tests instead of RubyCocoa. Fast tests vs slow tests. You choose.</p>
<h3>What the?</h3>
<p>Sometimes I re-read what I&#8217;ve written and notice things that don&#8217;t seem to make sense, but are in my vocabulary nonetheless. Yep, the things you learn living in Australia.</p>
<p><strong id="keep-your-pants-on">&#8220;Keep your pants on&#8221;</strong> &#8211; 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&#8217;d both agree. Most code-based blog articles are &#8220;pants on&#8221;. This phrase means &#8220;don&#8217;t get upset&#8221;. You can try to figure out how you go from &#8220;don&#8217;t get upset&#8221; to &#8220;keep your pants on&#8221;. I have no idea.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2010/06/01/validate-and-save-your-ruby-in-textmate-with-secret-rubinus-superpowers/' rel='bookmark' title='Permanent Link: Validate and Save your Ruby in TextMate &#8211; with secret Rubinus superpowers'>Validate and Save your Ruby in TextMate &#8211; with secret Rubinus superpowers</a> <small>In some TextMate bundles, if you save a file it...</small></li><li><a href='http://drnicwilliams.com/2009/03/30/closing-in-on-the-dream-one-click-to-deploy-rails-apps/' rel='bookmark' title='Permanent Link: Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;'>Closing in on The Dream: &#8220;one-click-to-deploy Rails apps&#8221;</a> <small> Got a simple app you want to build? Allocate...</small></li><li><a href='http://drnicwilliams.com/2008/12/11/future-proofing-your-ruby-code/' rel='bookmark' title='Permanent Link: Future proofing your Ruby code. Ruby 1.9.1 is coming.'>Future proofing your Ruby code. Ruby 1.9.1 is coming.</a> <small> Bugger. I&#8217;m a Ruby monogamist. I use the Ruby...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2008/07/04/unit-testing-iphone-apps-with-ruby-rbiphonetest/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
<enclosure url="http://drnicwilliams.com/wp-content/uploads/2008/06/rbiphonetest-introduction.mov" length="60255710" type="video/quicktime" />
		</item>
	</channel>
</rss>
