<?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/"
	>

<channel>
	<title>SamuraiBlog.com &#187; deferred</title>
	<atom:link href="http://samuraiblog.com/wordpress/tag/deferred/feed/" rel="self" type="application/rss+xml" />
	<link>http://samuraiblog.com/wordpress</link>
	<description>Cursing and Cigarettes</description>
	<pubDate>Sat, 24 Apr 2010 01:36:47 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>JSON-RPC in Objective-C</title>
		<link>http://samuraiblog.com/wordpress/2009/11/06/json-rpc-in-objective-c/</link>
		<comments>http://samuraiblog.com/wordpress/2009/11/06/json-rpc-in-objective-c/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 12:11:28 +0000</pubDate>
		<dc:creator>Samuel Sutch</dc:creator>
		
		<category><![CDATA[Articles]]></category>

		<category><![CDATA[Code]]></category>

		<category><![CDATA[cocoa]]></category>

		<category><![CDATA[deferred]]></category>

		<category><![CDATA[deferredkit]]></category>

		<category><![CDATA[iphone]]></category>

		<category><![CDATA[json-rpc]]></category>

		<category><![CDATA[objective-c]]></category>

		<guid isPermaLink="false">http://samuraiblog.com/wordpress/?p=208</guid>
		<description><![CDATA[Handling JSON in Objective-C is already pretty easy with the excellent strict parser provided by json-framework. However, interacting with a web service in a graphical application can be hard to get right. Frequently unresponsive or unpredictable behavior is a big turnoff for users. Recently I have been developing a lot for the iPhone and more [...]]]></description>
			<content:encoded><![CDATA[<p>Handling JSON in Objective-C is already pretty easy with the excellent strict parser provided by <a href="http://code.google.com/p/json-framework/">json-framework</a>. However, interacting with a web service in a graphical application can be hard to get right. Frequently unresponsive or unpredictable behavior is a big turnoff for users. Recently I have been developing a lot for the iPhone and more often than not, ideas that beget these applications revolve around central web applications. Many client-server interactions usually boil down to the familiar CRUD apps we&#8217;re all so familiar generating with Rails and Django but require much more effort.</p>
<p>Writing applications for a mobile device introduces several challenges: limited memory, slow network and a language and framework designed without an eye on modern agile web services. Recently while writing an iPhone application with heavy web interaction I got lazy doing all that work and wrote <a href="http://github.com/samuraisam/DeferredKit">DeferredKit</a> - a port of <a href="http://twistedmatrix.com/projects/core/documentation/howto/defer.html">Twisted&#8217;s Deferred</a> with many extensions for us Objective-C coders. DeferredKit makes asynchronous programming in Objective-C really easy with very little overhead and includes an asynchronous JSON-RPC client. It allows you to write code like this:</p>
<pre lang="c">
  - (void)doRegistration {
    [[[[[DKDeferred jsonService:SERVICE_URL]
       myApp] register:array_(self.username, self.password)]
      addCallback:callbackTS(self, doRegistrationCompleted:)]
     addErrback:callbackTS(self, doRegistrationFailed:)];
  }

  - (id)doRegistrationCompleted:(id)result {
    // do something with result
    return result;
  }

  - (id)doRegistrationFailed:(NSError *)err {
    // do something with error
    return err;
  }
</pre>
<h3>Jumping In</h3>
<p>Getting started with DeferredKit is relatively easy. Download the <a href="http://github.com/samuraisam/DeferredKit/tarball/master"source tarball</a> or pull DeferredKit from github and drop everything from <code>DeferredKit/CocoaDeferred/Source</code> into your project (you can also compile DeferredKit as a direct dependency in Xcode, a how-to is in the README).</p>
<p>First, a bit of explanation. Despite the recent addition of blocks to the Objective-C language, the blocks runtime is not available to us iPhone developers (or anybody who wants to deploy to targets older than 10.6, sadly). Also, since there is no native function object in Objective-C, functions can not be passed around as first-class citizens, stored in collection types, persisted, etc. DeferredKit provides one called <code>DKCallback</code>. You will almost never have to touch the interface of <code>DKCallback</code> since handy macros are provided to generate function objects.</p>
<p>A deferred is defined as an object that encapsulates a return value that is not yet available (meaning, it will be returned from the network when done downloading, or return from a thread when done computing). The deferred then dispatches the value to a series of callbacks as soon as it becomes available.</p>
<p>JSON-RPC is exposed in DeferredKit through a class called <code>DKJSONServiceProxy</code> which employs a bit of magic to enable the dynamic method calling pattern you saw above. For convenience, <code>autorelease</code> constructors are also provided in DKDeferred:</p>
<pre lang="c">
  id service = [DKDeferred jsonService:@"http://myservice.net/json/" name:@"myapp.sayHello"];
</pre>
<p><small>(note: don&#8217;t forget to <code>#import DKDeferred+JSON.h</code>)</small></p>
<p>Calling a method returns a deferred:</p>
<pre lang="c">
  DKDeferred *d = [service :args_array];
</pre>
<p>To which you must add at least one callback for the call to be performed. In this case, <code>callbackTS</code> builds a callback with a <code>target</code> (can be any object), and a <code>selector</code> to be performed. A callback could also be a function pointer, <code>NSInvocation</code> or any object conforming to the DKCallback protocol.</p>
<pre lang="c">
  [d addCallback:callbackTS(self, gotSayHelloResults:)];
</pre>
<p>In case your JSON-RPC server returns an error (via the <code>error</code> key) or encounters a network error or parse error, deferred will automatically call any errbacks, or &#8220;error callbacks,&#8221; added with an <code>NSError</code> object.</p>
<pre lang="c">
  [d addErrback:callbackTS(self, handleSayHelloError:)];
</pre>
<p>Callbacks and errbacks are written as a function or method which takes a single argument, the result and returns <code>id</code>. JSON-RPC results will always be an <code>NSDictionary</code> with a <code>result</code> key, among others.</p>
<pre lang="c">
  - (id)gotSayHelloResults:(id)results {
    self.helloLabel.text = [results objectForKey:@"result"];
    return nil;
  }
</pre>
<p>Errbacks are the same as callbacks except they will always be called with an <code>NSError</code> argument. The <code>userDict</code> dictionary will be populated with the error dictionary produced by your JSON-RPC server. <code>userDict</code> will be different for different error types however, so be sure to check which kind of error is being returned.</p>
<pre lang="c">
  - (id)handleSayHelloError:(NSError *)err {
    [self alertError:[[[error userDict] objectForKey:@"error"] objectForKey:@"message"]];
    return nil;
  }
</pre>
<h3>Conclusion</h3>
<p>I&#8217;ve only had the opportunity to touch on the basics of DeferredKit, but a post is coming soon with more details. It is a tested, lightweight framework for writing asynchronous code and can greatly improve your productivity when working with web services.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://samuraiblog.com/wordpress/2009/11/06/json-rpc-in-objective-c/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
