<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>Isaac Kearse</title>
 
 <link href="http://isaac.kearse.co.nz/" />
 <updated>2010-02-14T15:38:43-08:00</updated>
 <id>http://isaac.kearse.co.nz/</id>
 <author>
   <name>Isaac Kearse</name>
   <email>isaac@kearse.co.nz</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/isaackearse" /><feedburner:info uri="isaackearse" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>isaackearse</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry>
   <title>Remote thumbnails with Imagery</title>
   <link href="http://feedproxy.google.com/~r/isaackearse/~3/hbHSql2Zn_Q/" />
   <updated>2010-02-15T00:00:00-08:00</updated>
   <id>http://isaac.kearse.co.nz/2010/02/15/remote-thumbnails-with-heroku-and-imagery</id>
   <content type="html">&lt;p&gt;Just a quick heads up to let you know I posted to our &lt;a href="http://lucidcode.co.nz/blog"&gt;new company blog&lt;/a&gt; about generating thumbnails remotely with Heroku and Imagery.  Check it out &lt;a href="http://lucidcode.co.nz/blog/archives/2010/02/09/remote-thumbnails-with-heroku-and-imagery/"&gt;here&lt;/a&gt;, I&amp;#8217;ll be writing more about work related stuff there so &lt;a href="http://feeds.feedburner.com/lucidcode"&gt;subscribe&lt;/a&gt; if you&amp;#8217;re interested.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=hbHSql2Zn_Q:FMjfawd4QtQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=hbHSql2Zn_Q:FMjfawd4QtQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=hbHSql2Zn_Q:FMjfawd4QtQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=hbHSql2Zn_Q:FMjfawd4QtQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=hbHSql2Zn_Q:FMjfawd4QtQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=hbHSql2Zn_Q:FMjfawd4QtQ:uerw9Fc4_r4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=hbHSql2Zn_Q:FMjfawd4QtQ:uerw9Fc4_r4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/isaackearse/~4/hbHSql2Zn_Q" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://isaac.kearse.co.nz/2010/02/15/remote-thumbnails-with-heroku-and-imagery/</feedburner:origLink></entry>
 
 <entry>
   <title>SafariRSS - HotCocoa Safari RSS Handler</title>
   <link href="http://feedproxy.google.com/~r/isaackearse/~3/U9L_0JAyIR8/" />
   <updated>2010-02-07T00:00:00-08:00</updated>
   <id>http://isaac.kearse.co.nz/2010/02/07/safarirss</id>
   <content type="html">&lt;p&gt;I use Safari as my primary browser and &lt;a href="http://google.com/reader"&gt;Google Reader&lt;/a&gt; (and &lt;a href="http://www.phantomfish.com/byline.html"&gt;Byline&lt;/a&gt;) for reading feeds.  Subscribing to feeds was painful for me for a long time until I discovered &lt;a href="http://code.google.com/p/readernotifier/"&gt;Reader Notifier&lt;/a&gt;.  Reader Notifier will sit in your status bar and notify you when you have new feed entries to read.  You can also set it as your Default &lt;span class="caps"&gt;RSS&lt;/span&gt; reader in Safari and it will redirect you to Google Reader when you click the &lt;span class="caps"&gt;RSS&lt;/span&gt; button.  This felt like overkill to me.  My status bar is sacred, and I don&amp;#8217;t need to be notified throughout the day about new feed entries.  What I needed was a &lt;a href="http://macruby.org/hotcocoa.html"&gt;HotCocoa&lt;/a&gt; application that just did the bare minimum.  Enter &lt;a href="http://github.com/isaac/SafariRSS"&gt;SafariRSS&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The Competition&lt;/h2&gt;
&lt;p&gt;Halfway through coding this app I was googling for some info on NSAppleEventManager and came across a remarkably similar project called &lt;a href="http://code.google.com/p/reader-helper/"&gt;Reader Helper&lt;/a&gt;.  This is a good example of one of the benefits of using MacRuby &amp;amp; HotCocoa, with SafariRSS weighing in at around 25% of Reader Helper in terms of lines of code.  On the flip side Reader Helper weighs in at less than 1% of the download size of SafariRSS if we bundle MacRuby with the application.  Anyway I&amp;#8217;m glad this project existed, as I was able to translate some of the code into MacRuby very easily.&lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://github.com/isaac/SafariRSS/downloads"&gt;Download SafariRSS&lt;/a&gt; and then go into Preferences in Safari and select it as the Default &lt;span class="caps"&gt;RSS&lt;/span&gt; reader:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/RSS.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Go to an awesome website and click on the &lt;span class="caps"&gt;RSS&lt;/span&gt; button on the right hand side of the Address Bar:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/MacRuby.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Wait a few seconds and you will be redirected to Google Reader with the option of subscribing to the feed in question:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/reader.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Changing the redirect to another &lt;span class="caps"&gt;URL&lt;/span&gt; or launching another application should be a trivial exercise, here is the entire app:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
 &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;hotcocoa&amp;#39;&lt;/span&gt;
&lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;LoadError&lt;/span&gt;
  &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
  &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;hotcocoa&amp;#39;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt;

  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;HotCocoa&lt;/span&gt;
  
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;
    &lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;SafariRSS&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;eventManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NSAppleEventManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sharedAppleEventManager&lt;/span&gt;
      &lt;span class="n"&gt;gurl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;GURL&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unpack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;N&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;
      &lt;span class="n"&gt;eventManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setEventHandler&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;andSelector&lt;/span&gt;&lt;span class="ss"&gt;:&amp;quot;getURL:reply:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;forEventClass&lt;/span&gt;&lt;span class="ss"&gt;:gurl&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;andEventID&lt;/span&gt;&lt;span class="ss"&gt;:gurl&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="ss"&gt;:reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paramDescriptorForKeyword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;----&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unpack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;N&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stringValue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;feed://&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;http://&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;NSWorkspace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sharedWorkspace&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;openURL&lt;/span&gt; &lt;span class="no"&gt;NSURL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URLWithString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;http://www.google.com/reader/view/feed/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;NSApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sharedApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;terminate&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;I&amp;#8217;m not totally happy with how long it takes to launch the app and redirect to the &lt;span class="caps"&gt;URL&lt;/span&gt;, but all the apps I tried seem to take a similar length of time so I don&amp;#8217;t think its an issue with MacRuby.  Any ideas on how to speed it up would be much appreciated.&lt;br /&gt;
Checkout the source on &lt;a href="http://github.com/isaac/SafariRSS"&gt;GitHub&lt;/a&gt; and let me know what you think.  I have only tested this app on &lt;a href="http://www.macruby.org/downloads.html"&gt;MacRuby 0.5&lt;/a&gt; but it will probably work on 0.6 also.  As usual you can find a version with MacRuby bundled in &lt;a href="http://github.com/isaac/SafariRSS/downloads"&gt;the downloads section of the GitHub repo&lt;/a&gt;.  I tried to make embedding MacRuby a little easier with this app, but I&amp;#8217;ll go into the details of that in a future post.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=U9L_0JAyIR8:z3ZFyEgZ1O4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=U9L_0JAyIR8:z3ZFyEgZ1O4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=U9L_0JAyIR8:z3ZFyEgZ1O4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=U9L_0JAyIR8:z3ZFyEgZ1O4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=U9L_0JAyIR8:z3ZFyEgZ1O4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=U9L_0JAyIR8:z3ZFyEgZ1O4:uerw9Fc4_r4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=U9L_0JAyIR8:z3ZFyEgZ1O4:uerw9Fc4_r4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/isaackearse/~4/U9L_0JAyIR8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://isaac.kearse.co.nz/2010/02/07/safarirss/</feedburner:origLink></entry>
 
 <entry>
   <title>Packaging A HotCocoa Application</title>
   <link href="http://feedproxy.google.com/~r/isaackearse/~3/a5aJZASowaA/" />
   <updated>2010-02-01T00:00:00-08:00</updated>
   <id>http://isaac.kearse.co.nz/2010/02/01/packaging-hotcocoa</id>
   <content type="html">&lt;p&gt;&lt;a href="http://www.macruby.org/hotcocoa.html"&gt;HotCocoa&lt;/a&gt; is a thin, idiomatic Ruby layer that sits above Cocoa and other frameworks.  HotCocoa used to be included in &lt;a href="http://www.macruby.org"&gt;MacRuby&lt;/a&gt; but is now managed as a &lt;a href="http://github.com/richkilmer/hotcocoa"&gt;separate gem&lt;/a&gt;.  Developing a HotCocoa application with TextMate and Terminal is a lightweight and expressive alternative to using Xcode and Interface Builder and I encourage everyone to give it a shot.  Now that &lt;a href="http://github.com/richkilmer/hotcocoa/network"&gt;HotCocoa is hosted on GitHub&lt;/a&gt; forking and sending pull requests is probably the easiest way for a lot of people to contribute to the MacRuby ecosystem.&lt;/p&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Getting started with HotCocoa from the Terminal is a breeze:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  &lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;macgem&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;hotcocoa&lt;/span&gt;
  &lt;span class="n"&gt;hotcocoa&lt;/span&gt; &lt;span class="n"&gt;demo&lt;/span&gt;
  &lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;demo&lt;/span&gt;
  &lt;span class="n"&gt;macrake&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;These commands will install HotCocoa, create a skeleton demo application and launch the application, which should look something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/demo.png" alt="" /&gt;&lt;/p&gt;
&lt;h2&gt;Distribution&lt;/h2&gt;
&lt;p&gt;Packaging up a HotCocoa app for distribution is also dead simple:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  &lt;span class="n"&gt;macrake&lt;/span&gt; &lt;span class="n"&gt;deploy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;This task will copy the entire MacRuby Framework, including the HotCocoa gem, into the application bundle ready for download as a self-contained app.&lt;/p&gt;
&lt;p&gt;When I was packaging up &lt;a href="http://isaac.kearse.co.nz/2010/01/31/stopwatch/"&gt;Stopwatch&lt;/a&gt; for &lt;a href="http://github.com/isaac/Stopwatch/downloads"&gt;download&lt;/a&gt; I decided to not include the standard library and cut down the size of the app from around 150MB to 30MB.  This turned out to be harder than I expected.  Rubygems is part of the standard library and since HotCocoa is now a gem I had to embed HotCocoa into the app without requiring Rubygems.  Here are &lt;a href="http://github.com/isaac/Stopwatch/blob/master/Rakefile"&gt;the two rake tasks&lt;/a&gt; that unpack HotCocoa and embed MacRuby in the application without the standard library:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="ss"&gt;:unpack&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="sb"&gt;`macgem unpack hotcocoa`&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;directory?&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;hotcocoa-0.5.1&amp;quot;&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="ss"&gt;:embed&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:clean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:unpack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:build&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="sb"&gt;`macruby_deploy --no-stdlib --embed &amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;AppConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;.app&amp;quot;`&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;We also need to make sure HotCocoa is added to the application bundle by adding it to the sources in &lt;a href="http://github.com/isaac/Stopwatch/blob/master/config/build.yml"&gt;config/build.yml&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="yaml"&gt;  &lt;span class="l-Scalar-Plain"&gt;name&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;Stopwatch&lt;/span&gt;
  &lt;span class="l-Scalar-Plain"&gt;load&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;lib/application.rb&lt;/span&gt;
  &lt;span class="l-Scalar-Plain"&gt;version&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;
  &lt;span class="l-Scalar-Plain"&gt;resources&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt;
    &lt;span class="p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;resources/**/*.*&lt;/span&gt;
  &lt;span class="l-Scalar-Plain"&gt;sources&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; 
    &lt;span class="p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;lib/**/*.rb&lt;/span&gt;
    &lt;span class="p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;hotcocoa*/lib/**/*.rb&lt;/span&gt;
  &lt;span class="l-Scalar-Plain"&gt;agent&lt;/span&gt;&lt;span class="p-Indicator"&gt;:&lt;/span&gt; &lt;span class="l-Scalar-Plain"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;And finally, require HotCocoa at the top of &lt;a href="http://github.com/isaac/Stopwatch/blob/master/lib/application.rb"&gt;lib/application.rb&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;..&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;hotcocoa-0.5.1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;lib&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;hotcocoa&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;So now embedding MacRuby &amp;amp; HotCocoa without the standard library is as simple as running:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  &lt;span class="n"&gt;macrake&lt;/span&gt; &lt;span class="n"&gt;embed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;All &lt;a href="http://github.com/isaac/Stopwatch/downloads"&gt;zipped up&lt;/a&gt; the entire application is around 10MB.&lt;/p&gt;
&lt;h2&gt;Building&lt;/h2&gt;
&lt;p&gt;I also made a &lt;a href="http://github.com/isaac/hotcocoa/commit/4a594b07f045867f608fd2ca473a2e54dcff1c9e"&gt;small modification&lt;/a&gt; to the HotCocoa application builder so that Stopwatch could run as an agent in the background.  When I was trying to build my forked version of the HotCocoa gem I got this nasty error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  &lt;span class="n"&gt;macgem&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="n"&gt;hotcocoa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gemspec&lt;/span&gt; 
  &lt;span class="no"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="no"&gt;While&lt;/span&gt; &lt;span class="n"&gt;executing&lt;/span&gt; &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;IOError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;opened&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;reading&lt;/span&gt;
  &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;opened&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;reading&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;IOError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;A workaround for this is to use the &lt;span class="caps"&gt;MRI&lt;/span&gt; gem command for building and then macgem for installing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="n"&gt;hotcocoa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gemspec&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;macgem&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;hotcocoa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gem&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=a5aJZASowaA:5YohfqE05MI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=a5aJZASowaA:5YohfqE05MI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=a5aJZASowaA:5YohfqE05MI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=a5aJZASowaA:5YohfqE05MI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=a5aJZASowaA:5YohfqE05MI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=a5aJZASowaA:5YohfqE05MI:uerw9Fc4_r4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=a5aJZASowaA:5YohfqE05MI:uerw9Fc4_r4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/isaackearse/~4/a5aJZASowaA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://isaac.kearse.co.nz/2010/02/01/packaging-hotcocoa/</feedburner:origLink></entry>
 
 <entry>
   <title>Stopwatch - A HotCocoa Status Bar Timer</title>
   <link href="http://feedproxy.google.com/~r/isaackearse/~3/ziOA5FknQc0/" />
   <updated>2010-01-31T00:00:00-08:00</updated>
   <id>http://isaac.kearse.co.nz/2010/01/31/stopwatch</id>
   <content type="html">&lt;p&gt;&lt;a href="http://luciddesign.co.nz"&gt;At work&lt;/a&gt; we use a job management web app called &lt;a href="http://www.workflowmax.com"&gt;WorkflowMax&lt;/a&gt;.  This product has a &lt;a href="http://www.workflowmax.com/overview.aspx"&gt;huge array of features&lt;/a&gt; but I mostly just use it for tracking the time I spend on client work.  It ships with a javascript timer in the web app that is probably sufficient for most people, but I wanted to be able to work offline.  They have an &lt;a href="http://www.workflowmax.com/api-overview.aspx"&gt;&lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; so this seemed like a great excuse to build a &lt;a href="http://www.macruby.org"&gt;MacRuby&lt;/a&gt; &amp;amp; &lt;a href="http://www.macruby.org/hotcocoa.html"&gt;HotCocoa&lt;/a&gt; application.&lt;/p&gt;
&lt;p&gt;I decided Stopwatch should be a simple menu that lives in the status bar.  On startup it will ask you for your WorkflowMax credentials:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/preferences.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;WorkflowMax were kind enough to give me a demo account that people can use to try out the application.  If you would like to play along at home you can use these credentials:&lt;/p&gt;
&lt;p&gt;- Account Key: B65C7527334C4892A96549DBC7B88FB7&lt;br /&gt;
- Email Address: isaac@kearse.co.nz&lt;/p&gt;
&lt;p&gt;Once you have entered your credentials in the Preferences panel and clicked Save, you should see an interface like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/open.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;From right to left the drop down menus will show all your clients, all the jobs for a client and all the tasks for a job.  When you click on the task &amp;#8220;Design&amp;#8221; on the left the timer will start and display a clock and task description in your status bar:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/started.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;The timer will increment every minute and when you click on it you will be presented with a few options:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/stop.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;You can enter some notes about the task you&amp;#8217;re working on, stop the task or start another task (which will also stop the current task).  If the task is stopped the time you have worked will be written to disk in xml format, and then posted to the server when you have an internet connection.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/stopped.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Once stopped the task will stay in the status bar and to start it again you can just click start:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/start.png" alt="" /&gt;&lt;/p&gt;
&lt;h2&gt;Download&lt;/h2&gt;
&lt;p&gt;You can ownload a self contained app here: &lt;a href="http://github.com/isaac/Stopwatch/downloads"&gt;http://github.com/isaac/Stopwatch/downloads&lt;/a&gt;, or find the source on github here: &lt;a href="http://github.com/isaac/Stopwatch"&gt;http://github.com/isaac/Stopwatch&lt;/a&gt;.  If you want to build the app from source I recommend you install &lt;a href="http://macruby.icoretech.org"&gt;the latest MacRuby nightly build&lt;/a&gt; first.&lt;/p&gt;
&lt;p&gt;I have bundled a slightly modified copy of the &lt;a href="http://www.macruby.org/hotcocoa.html"&gt;HotCocoa&lt;/a&gt; &lt;a href="http://github.com/richkilmer/hotcocoa"&gt;gem&lt;/a&gt; into Stopwatch and pushed my changes upstream.  Also bundled with the app are a few other libraries: &lt;a href="http://github.com/mattetti/macruby-httpwrapper"&gt;macruby-httpwrapper&lt;/a&gt; by &lt;a href="http://merbist.com"&gt;Matt Aimonetti&lt;/a&gt; and &lt;a href="http://github.com/Caged/aixmlserialize"&gt;aixmlserialize&lt;/a&gt; by &lt;a href="http://labratrevenge.com"&gt;Justin Palmer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll talk more about the technical aspects of the app in later posts, so let me know if there is anything you would like me to cover.  Developing a MacRuby app with HotCocoa was a great experience and I was more than happy to have a holiday from  Interface Builder and Xcode.  If only I could develop iPhone &amp;amp; iPad apps in TextMate and Terminal!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=ziOA5FknQc0:EZKkBGjakis:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=ziOA5FknQc0:EZKkBGjakis:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=ziOA5FknQc0:EZKkBGjakis:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=ziOA5FknQc0:EZKkBGjakis:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=ziOA5FknQc0:EZKkBGjakis:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=ziOA5FknQc0:EZKkBGjakis:uerw9Fc4_r4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=ziOA5FknQc0:EZKkBGjakis:uerw9Fc4_r4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/isaackearse/~4/ziOA5FknQc0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://isaac.kearse.co.nz/2010/01/31/stopwatch/</feedburner:origLink></entry>
 
 <entry>
   <title>Asynchronous Table Views With MacRuby</title>
   <link href="http://feedproxy.google.com/~r/isaackearse/~3/WU79caebkN4/" />
   <updated>2010-01-10T00:00:00-08:00</updated>
   <id>http://isaac.kearse.co.nz/2010/01/10/async-table-views-with-macruby</id>
   <content type="html">&lt;p&gt;Developing the initial UI for &lt;a href="http://isaac.kearse.co.nz/2010/01/01/birdwatch/"&gt;BirdWatch&lt;/a&gt; was relatively pain-free.  After I put aside my fear and distrust of Interface Builder and figured out how everything fitted together with outlets and delegates it all came together quickly.  This is roughly what it looked like:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/initial.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Each search query in &lt;a href="http://isaac.kearse.co.nz/2010/01/01/birdwatch/"&gt;BirdWatch&lt;/a&gt; is an atom feed stored as an instance of PSFeed by the PubSub framework.  When you click on the &amp;#8220;macruby&amp;#8221; query highlighted in blue above, the entries for that feed are sent to the table view on the right.  Each entry in the feed is an instance of PSEntry and corresponds to one row in the table view. Each row is represented by the class Status:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Status&lt;/span&gt;

  &lt;span class="kp"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:text&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NSImage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imageNamed&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;NSUser&amp;#39;&lt;/span&gt;
    &lt;span class="vi"&gt;@text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plainTextString&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The instance variables @image and @text populate the left and right cell of each table view row respectively.&lt;/p&gt;
&lt;p&gt;These are all simple method calls to local resources so its no suprise this table view loads and scrolls very quickly.  But its a little boring, lets see what happens when we add some more visual interest and interactivity.&lt;/p&gt;
&lt;h2&gt;Twitter Profile Pictures&lt;/h2&gt;
&lt;p&gt;My first priority was to add twitter profile pictures to spice things up and show at a glance the author of each status message.  Unlike the status text, the profile image is not stored locally by the PubSub framework and will need to be downloaded from twitter.  First we find the &lt;span class="caps"&gt;URL&lt;/span&gt; of the picture in the status xml.  In this case I want a bigger version so I do a gsub on the string returned. Then I construct a &lt;span class="caps"&gt;NSURL&lt;/span&gt; instance and finally create and return the image:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Status&lt;/span&gt;

  &lt;span class="kp"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:text&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;links&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XMLRepresentation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nodesForXPath&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;//link[@type=&amp;quot;image/png&amp;quot;]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="ss"&gt;:nil&lt;/span&gt;
    &lt;span class="n"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;links&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attributeForName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;href&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stringValue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gsub&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;_normal.&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;_bigger.&amp;#39;&lt;/span&gt;
    &lt;span class="vi"&gt;@image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NSImage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alloc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;initByReferencingURL&lt;/span&gt; &lt;span class="no"&gt;NSURL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URLWithString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plainTextString&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/beachball.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;At this point my application grinds to a halt and the beach ball of death becomes a constant companion.  The initial loading time for each query is very slow, and trying to scroll through a large list of status messages is extremely painful.  It seems downloading the profile images from twitter is blocking the UI and causing the application to become unresponsive.&lt;/p&gt;
&lt;h2&gt;Asynchronous NSURLConnections&lt;/h2&gt;
&lt;p&gt;Cocoa provides great support for asynchronous requests which we can leverage to download the profile images in the background and keep the app responsive.  You may recognise some of the code below from the excellent &lt;a href="http://www.macruby.org/hotcocoa/functionality.html"&gt;hotcoca tutorials&lt;/a&gt; on the &lt;a href="http://www.macruby.org"&gt;MacRuby site&lt;/a&gt;.  The approach I&amp;#8217;ll use here is to load the system-provided image when an instance of Status is first initialized.  Then just before the cell is displayed on the screen I&amp;#8217;ll kick off an asynchronous request to download the image from twitter, update the instance variable @image and reload the cell.  Here is the method we will use in the table view delegate to start the request:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tableView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;willDisplayCell&lt;/span&gt;&lt;span class="ss"&gt;:cell&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;forTableColumn&lt;/span&gt;&lt;span class="ss"&gt;:column&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="ss"&gt;:row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cell&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cell&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;NSUser&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@entries&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;download&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NSImage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alloc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;initWithData&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
      &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reloadDataForRowIndexes&lt;/span&gt; &lt;span class="no"&gt;NSIndexSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;indexSetWithIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;columnIndexes&lt;/span&gt;&lt;span class="ss"&gt;:NSIndexSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;indexSetWithIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;So first we are checking if this is an image cell and if the cell is still holding the placeholder image.  Then we retrieve the status that corresponds to this cell and call the method &amp;#8220;download&amp;#8221; on that status.  The download method takes a block which will return the downloaded data asynchronously.  This is where MacRuby really shines: putting a simple &lt;span class="caps"&gt;DSL&lt;/span&gt; on top of a complicated Cocoa class.  Here is what the Status class looks with the download method and friends added:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Status&lt;/span&gt;

  &lt;span class="kp"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:text&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NSImage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imageNamed&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;NSUser&amp;#39;&lt;/span&gt;
    &lt;span class="vi"&gt;@text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plainTextString&lt;/span&gt;
    &lt;span class="vi"&gt;@loading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="vi"&gt;@data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NSMutableData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
    &lt;span class="vi"&gt;@url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;links&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XMLRepresentation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nodesForXPath&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;//link[@type=&amp;quot;image/png&amp;quot;]&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="ss"&gt;:nil&lt;/span&gt;
    &lt;span class="n"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;links&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attributeForName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;href&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stringValue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gsub&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;_normal.&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;_bigger.&amp;#39;&lt;/span&gt;
    &lt;span class="no"&gt;NSURL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URLWithString&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;download&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@loading&lt;/span&gt;
    &lt;span class="vi"&gt;@loading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="vi"&gt;@block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;
    &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;NSURLRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;requestWithURL&lt;/span&gt; &lt;span class="vi"&gt;@url&lt;/span&gt;
    &lt;span class="no"&gt;NSURLConnection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alloc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;initWithRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;delegate&lt;/span&gt;&lt;span class="ss"&gt;:self&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;didReceiveResponse&lt;/span&gt;&lt;span class="ss"&gt;:response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLength&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;didReceiveData&lt;/span&gt;&lt;span class="ss"&gt;:data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;appendData&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;didFailWithError&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@loading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectionDidFinishLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@block&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="vi"&gt;@data&lt;/span&gt;
    &lt;span class="vi"&gt;@loading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Before a download is started the @loading instance variable is checked to ensure we don&amp;#8217;t try and start an extra request for the same object.  During the request the data returned is appended to the @data instance variable and when it has finished @data is passed back to the original block in the table view delegate.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/pictures.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;With this code in place the interface is snappy no matter how terrible your internet connection is, which is important if you are living in rural New Zealand.  It&amp;#8217;s also a lot easier on the eyes to see profile pictures in full colour and makes the content much more engaging.&lt;/p&gt;
&lt;p&gt;Now to deal with that status message text: where are the links? who is talking? how long ago?&lt;br /&gt;
That will have to wait for another blog post because you would be shocked if you knew how long this has taken me to write.&lt;/p&gt;
&lt;p&gt;You can have a look at the entire BirdWatch application on github here: &lt;a href="http://github.com/isaac/BirdWatch"&gt;http://github.com/isaac/BirdWatch&lt;/a&gt;.  I have simplified some of the code above for readability.  Please feel free to fork away and send patches or &lt;a href="http://github.com/isaac/BirdWatch/issues"&gt;open up an issue on GitHub&lt;/a&gt; if you come across any problems or have any feature requests.  I recommend installing the &lt;a href="http://macruby.icoretech.org/"&gt;latest MacRuby nightly&lt;/a&gt; before you try to build and run the app from Xcode.  If you don&amp;#8217;t have the latest MacRuby nightly installed you can download a version with MacRuby embedded in the app from here: &lt;a href="http://github.com/isaac/BirdWatch/downloads"&gt;http://github.com/isaac/BirdWatch/downloads&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=WU79caebkN4:_Cp3iWsW_aA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=WU79caebkN4:_Cp3iWsW_aA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=WU79caebkN4:_Cp3iWsW_aA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=WU79caebkN4:_Cp3iWsW_aA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=WU79caebkN4:_Cp3iWsW_aA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=WU79caebkN4:_Cp3iWsW_aA:uerw9Fc4_r4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=WU79caebkN4:_Cp3iWsW_aA:uerw9Fc4_r4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/isaackearse/~4/WU79caebkN4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://isaac.kearse.co.nz/2010/01/10/async-table-views-with-macruby/</feedburner:origLink></entry>
 
 <entry>
   <title>Meet BirdWatch - MacRuby Twitter Search</title>
   <link href="http://feedproxy.google.com/~r/isaackearse/~3/4rfRhafmXRE/" />
   <updated>2010-01-01T00:00:00-08:00</updated>
   <id>http://isaac.kearse.co.nz/2010/01/01/birdwatch</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;[&lt;span class="caps"&gt;UPDATE&lt;/span&gt;]&lt;/strong&gt; If you don&amp;#8217;t have the latest MacRuby nightly installed you can download with a version with MacRuby embedded in the app from here: &lt;a href="http://github.com/isaac/BirdWatch/downloads"&gt;http://github.com/isaac/BirdWatch/downloads&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://isaac.kearse.co.nz/images/BirdWatch.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve been following &lt;a href="http://macruby.org"&gt;MacRuby&lt;/a&gt; with interest for a while and after watching the &lt;a href="http://peepcode.com/products/meet-macruby"&gt;Meet MacRuby&lt;/a&gt; screencast from &lt;a href="http://peepcode.com"&gt;PeepCode&lt;/a&gt; I decided a twitter search client would be a good learning project.&lt;/p&gt;
&lt;p&gt;To keep everything as simple as possible I decided to use the &lt;a href="http://apiwiki.twitter.com/Twitter-Search-API-Method%3A-search"&gt;Twitter Search &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; in conjunction with the  &lt;a href="http://developer.apple.com/mac/library/documentation/InternetWeb/Conceptual/PubSub/Introduction/Introduction.html"&gt;Publication Subscription Framework&lt;/a&gt;.  Every search query made from the app becomes an atom feed, which is parsed, stored and updated by the PubSub framework.&lt;/p&gt;
&lt;p&gt;You can get the source &lt;a href="http://github.com/isaac/BirdWatch"&gt;here&lt;/a&gt; and download the app &lt;a href="http://github.com/isaac/BirdWatch/downloads"&gt;here&lt;/a&gt;. I had a few issues embedding MacRuby into the application so you currently need MacRuby installed to run the app, if this is an issue for anyone &lt;a href="http://github.com/isaac/BirdWatch/issues"&gt;let me know&lt;/a&gt; and I&amp;#8217;ll sort it out.&lt;/p&gt;
&lt;p&gt;Future plans include a Mail.app style unread count for each search, a transition from Interface Builder to hotcocoa for the UI and possibly integrating web views somehow to remove the complexity of building up attributed strings for each status message.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=4rfRhafmXRE:nVoZ5o59vKY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=4rfRhafmXRE:nVoZ5o59vKY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=4rfRhafmXRE:nVoZ5o59vKY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=4rfRhafmXRE:nVoZ5o59vKY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=4rfRhafmXRE:nVoZ5o59vKY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/isaackearse?a=4rfRhafmXRE:nVoZ5o59vKY:uerw9Fc4_r4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/isaackearse?i=4rfRhafmXRE:nVoZ5o59vKY:uerw9Fc4_r4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/isaackearse/~4/4rfRhafmXRE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://isaac.kearse.co.nz/2010/01/01/birdwatch/</feedburner:origLink></entry>
 
 
</feed>
