<?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" xml:lang="en"><title type="text">MKBlog</title><link rel="alternate" type="text/html" href="http://blog.mugunthkumar.com" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/MugunthKumar" /><subtitle type="html">iOS development blog and Usability Guidelines</subtitle><updated>2012-05-14T07:08:15+00:00</updated><generator>http://wordpress.org/?v=3.3.2</generator><sy:updatePeriod xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">hourly</sy:updatePeriod><sy:updateFrequency xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">1</sy:updateFrequency><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/MugunthKumar" /><feedburner:info uri="mugunthkumar" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-sa/3.0/" /><feedburner:emailServiceId>MugunthKumar</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry><title type="text">Panacea for slow Xcode</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MugunthKumar/~3/u4NXr9yNDl4/" /><category term="Coding" /><category term="ios" /><category term="xcode" /><author><name>Mugunth Kumar</name></author><updated>2012-04-02T20:24:44-07:00</updated><id>http://blog.mugunthkumar.com/?p=1716</id><summary type="html">Wrote a quick and dirty script for clearing &amp;#8220;nonsense&amp;#8221; files with a click. Copy the contents of this script to a file on your Mac. Save it to a file named, say, cleanup.sh, preferably in your home directory (or the directory where your terminal opens up by default) Set execute permissions to it by typing, [...]
No related posts.</summary><content type="html">&lt;p&gt;&lt;/p&gt;&lt;p&gt;Wrote a quick and dirty script for clearing &amp;#8220;nonsense&amp;#8221; files with a click.&lt;br /&gt;
&lt;script src="https://gist.github.com/2289050.js"&gt; &lt;/script&gt;&lt;/p&gt;
&lt;p&gt;Copy the contents of this script to a file on your Mac.&lt;br /&gt;
Save it to a file named, say, &lt;strong&gt;cleanup.sh&lt;/strong&gt;, preferably in your home directory (or the directory where your terminal opens up by default)&lt;br /&gt;
Set execute permissions to it by typing,&lt;br /&gt;
&lt;strong&gt;chmod +x cleanup.sh&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You are done.&lt;/p&gt;
&lt;p&gt;Whenever Xcode &amp;#8220;misbehaves&amp;#8221;, just execute this script. It cleans up your Simulator and derived data directory for you.&lt;br /&gt;
Updates welcome.&lt;/p&gt;
&lt;p&gt;&amp;#8211;&lt;br /&gt;
Mugunth&lt;/p&gt;
&lt;p&gt;&lt;map name='google_ad_map_1716_8b86e81420c6776e'&gt;
&lt;area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/1716?pos=0' coords='1,2,367,28' /&gt;
&lt;area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/&gt;&lt;/map&gt;
&lt;img usemap='#google_ad_map_1716_8b86e81420c6776e' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;amp;client=&amp;amp;channel=&amp;amp;output=png&amp;amp;cuid=1716&amp;amp;url= http%3A%2F%2Fblog.mugunthkumar.com%2Fcoding%2Fpanacea-for-slow-xcode%2F' /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href ="http://twitter.com/mugunthkumar"&gt;Follow me &lt;/a&gt; on Twitter&lt;/p&gt;&lt;p&gt;&amp;copy;2012 &lt;a href="http://blog.mugunthkumar.com"&gt;MKBlog&lt;/a&gt;. All Rights Reserved.&lt;/p&gt;.
&lt;p&gt;No related posts.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LmYEnxN4chRU-KEfhq4qub-8xD8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LmYEnxN4chRU-KEfhq4qub-8xD8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LmYEnxN4chRU-KEfhq4qub-8xD8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LmYEnxN4chRU-KEfhq4qub-8xD8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MugunthKumar/~4/u4NXr9yNDl4" height="1" width="1"/&gt;</content><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.mugunthkumar.com/coding/panacea-for-slow-xcode/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">3</slash:comments><feedburner:origLink>http://blog.mugunthkumar.com/coding/panacea-for-slow-xcode/</feedburner:origLink></entry><entry><title type="text">RESTful API Server – Doing it the right way (Part 2)</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MugunthKumar/~3/p98h9PlVe34/" /><category term="Articles" /><category term="Featured Articles" /><category term="android" /><category term="api" /><category term="ios" /><category term="ipad" /><category term="iphone" /><category term="objective c" /><category term="restful" /><author><name>Mugunth Kumar</name></author><updated>2012-04-02T04:30:05-07:00</updated><id>http://blog.mugunthkumar.com/?p=1615</id><summary type="html">In the part 1 of the post, I introduced the RESTful principle and explained how to architecture your server code so as to ensure easier versioning and deprecation of your API. In this part, I&amp;#8217;m going to talk briefly about HATEOAS and hypermedia and then show you the role it plays in a native mobile [...]
Related posts:&lt;ol&gt;
&lt;li&gt;&lt;a href='http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-1/' rel='bookmark' title='RESTful API Server &amp;#8211; Doing it the right way (Part 1)'&gt;RESTful API Server &amp;#8211; Doing it the right way (Part 1)&lt;/a&gt; &lt;small&gt;In 2007, Steve Jobs announced the iPhone that revolutionized the...&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;</summary><content type="html">&lt;p&gt;&lt;/p&gt;&lt;p&gt;In &lt;a href="http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-1/"&gt;the part 1 of the post&lt;/a&gt;, I introduced the RESTful principle and explained how to architecture your server code so as to ensure easier versioning and deprecation of your API. In this part, I&amp;#8217;m going to talk briefly about HATEOAS and hypermedia and then show you the role it plays in a native mobile client development. But the crux of this post is going to be centered around how to implement caching (or rather server side support for caching). Target audience include, server developers and to some extent, iOS or any mobile platform developers.&lt;br /&gt;
&lt;div class='toc toc'&gt;
&lt;h2&gt;Contents&lt;/h2&gt;
&lt;ul class='toc-odd level-1'&gt;
	&lt;li&gt;
		&lt;a href="#HTTP_APIs_REST_and_HATEOAS"&gt;HTTP APIs, REST and HATEOAS&lt;/a&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;a href="#HATEOAS_-_Hypermedia_as_the_Engine_of_Application_State"&gt;HATEOAS - Hypermedia as the Engine of Application State&lt;/a&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;a href="#HATEOAS_for_your_next_API"&gt;HATEOAS for your next API?&lt;/a&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;a href="#Caching"&gt;Caching&lt;/a&gt;
		&lt;ul class='toc-even level-2'&gt;
			&lt;li&gt;
				&lt;a href="#Expiration_model"&gt;Expiration model&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#Validation_model"&gt;Validation model&lt;/a&gt;
				&lt;ul class='toc-odd level-3'&gt;
					&lt;li&gt;
						&lt;a href="#Client_side_coding"&gt;Client side coding&lt;/a&gt;
					&lt;/li&gt;
					&lt;li&gt;
						&lt;a href="#Server_side_coding"&gt;Server side coding&lt;/a&gt;
					&lt;/li&gt;
				&lt;/ul&gt;
			&lt;li&gt;
				&lt;a href="#Choosing_a_caching_model_for_your_resource"&gt;Choosing a caching model for your resource&lt;/a&gt;
			&lt;/li&gt;
		&lt;/ul&gt;
	&lt;li&gt;
		&lt;a href="#Recommended_Reading"&gt;Recommended Reading&lt;/a&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class='toc-end'&gt;&amp;nbsp;&lt;/div&gt;&lt;/p&gt;
&lt;span id="HTTP_APIs_REST_and_HATEOAS"&gt;&lt;h2&gt;HTTP APIs, REST and HATEOAS&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;In today&amp;#8217;s world, HTTP APIs can be classified into&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Web Services&lt;/li&gt;
&lt;li&gt;RPC URI Tunnelling&lt;/li&gt;
&lt;li&gt;HTTP-based Type 1&lt;/li&gt;
&lt;li&gt;HTTP-based Type 2&lt;/li&gt;
&lt;li&gt;REST&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is a very &lt;a href="http://www.nordsc.com/ext/classification_of_http_based_apis.html"&gt;good explanation by Jon Algermissen.&lt;/a&gt; Unfortunately, every API provider calls their service as &amp;#8220;RESTful&amp;#8221; despite otherwise.&lt;/p&gt;
&lt;p&gt;So what really is a RESTful server? Any API server that is hypertext/hypermedia driven is RESTful. That means, the developer/client application should be able to discover &amp;#8220;other available resources&amp;#8221; from the API&amp;#8217;s root URL. This, is in fact the most important constraint for implementing RESTful APIs. Additionally, a pure RESTful server is one that adheres to HATEOAS constraint.&lt;/p&gt;
&lt;span id="HATEOAS_8211_Hypermedia_as_the_Engine_of_Application_State"&gt;&lt;h2&gt;HATEOAS &amp;#8211; Hypermedia as the Engine of Application State&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;The two main constraints that you should follow for implementing HATEOAS are,&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Serve only hypermedia resources.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A hypermedia resource is one that contains content and controls (hyperlinks) to other hypermedia resources. JSON (application/json) is NOT a hypermedia resource. (Again, there are a lot of RESTful, HATEOAS servers that serve JSONs) However, you can add additional keys to the JSON making it behave like a hypermedia resource. (For ex: a href key for linking the resource to an associated thumbnail image)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Single point of entry for the client application.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;From the home page of the API, subsequent &amp;#8220;GET&amp;#8221; endpoints are embedded as URLs (or links) and subsequent &amp;#8220;POST&amp;#8221;, &amp;#8220;PUT&amp;#8221; or &amp;#8220;DELETE&amp;#8221; endpoints are embedded as forms. &lt;/p&gt;
&lt;p&gt;The main advantage of adhering to these two HATEOAS constraint is easier documentation.&lt;/p&gt;
&lt;span id="HATEOAS_for_your_next_API"&gt;&lt;h2&gt;HATEOAS for your next API?&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;&lt;strong&gt;A big NO&lt;/strong&gt;&lt;br /&gt;
Why do I say this? In the past, APIs were predominantly written for consumption in a web based application. These servers normally serves XHTML and applications run on a web browser. A web browser is a &amp;#8220;client&amp;#8221;, much similar to your mobile (iOS/Android/Windows Phone) client that can parse hypermedia resources and understand HTML forms and &amp;#8220;knows&amp;#8221; how to present a form to the user. For mobile client implementations, when your RESTful server&amp;#8217;s resource has a form that you could submit, you can&amp;#8217;t (at least easily) convert it to a native control available on the platform. None of the platform vendors, Apple/Google or Microsoft has built in support for converting a XHTML form to a UIViewController (on iOS) or a Intent(on Android) or a Silverlight Page(on Windows Phone).&lt;/p&gt;
&lt;p&gt;My recommendation is to go with resource representation for all &amp;#8220;GET&amp;#8221; entries and expose controller endpoints (instead of forms) for all POST/PUT and DELETE entries. (Example: /friends/add or /venue/checkin) The controller endpoints can (should) be embedded in other responses (so that the client or the client developer can discover it). Of course, that breaks REST, but it&amp;#8217;s ok. It&amp;#8217;s better to make products that work, than adhering to standards that offer zero benefits. (This will probably make our API a HTTP-based Type 2 API).&lt;/p&gt;
&lt;span id="Caching"&gt;&lt;h2&gt;Caching&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;Let&amp;#8217;s talk about caching. Caching, as you might think, is predominantly a client side (or intermediate proxy) thing. But do you know that a little bit of support from the server side, you can ensure that your API server adheres to conventions expected by a intermediate caching proxies? This in turn means, you will be benefited from free load balancing provided by them. In fact, caching is described in section 13 of the HTTP spec. Here is a &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html"&gt;link to it&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Art Taylor, tweeted this couple of months ago.&lt;/p&gt;
&lt;blockquote class="twitter-tweet"&gt;&lt;p&gt;I have two new rules.1) If your application is slow, add caching.2) If your application is buggy, remove caching.&lt;a href="https://twitter.com/search/%2523Why_is_caching_so_hard"&gt;#Why_is_caching_so_hard&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;— art taylor (@reeses) &lt;a href="https://twitter.com/reeses/status/157344234339446784" data-datetime="2012-01-12T06:12:43+00:00"&gt;January 12, 2012&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;But believe me, caching can be done just right without getting into trouble like this. Two important principles I would recommend that you adhere to are,&lt;/p&gt;
&lt;p&gt;1. Don&amp;#8217;t rollout custom caching schemes on your client.&lt;/p&gt;
&lt;p&gt;2. Understand the basic caching principles explained in &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html"&gt;HTTP 1.1 RFC specification.&lt;/a&gt; The RFC explains two kinds of caching models. Expiration model and Validation model.&lt;/p&gt;
&lt;p&gt;In any client/server application, the server is the authoritative source of information. When you download a resource (a page or a response) from a API server, the server sends some &amp;#8220;hints&amp;#8221; to the client on how to cache them. The server authoritatively dictates if (and when) the client should expire the cache. These &amp;#8220;hints&amp;#8221; can be sent either programmatically or by a server side configuration. Expiration model is usually a configuration on the server (nginx.conf or equivalent) where as validation model requires some programming effort from the server developer. The server developer should determine when to use validation and when to use expiration based on the kind of resource. Expiration model is normally used when the server can make a reliable guess on how long will a given resource be valid. Validation model is used for everything else. Later, I&amp;#8217;ll show you how to code your server for both these models. Once you understand the two models, I&amp;#8217;ll explain when to you use which model.&lt;/p&gt;
&lt;span id="Expiration_model"&gt;&lt;h3&gt;Expiration model&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;Let&amp;#8217;s first look at a very common cache control configuration. If you have configured nginx, you would have added something like this to your nginx.conf. (The Apache equivalent is written into the .htaccess file.)&lt;/p&gt;
&lt;pre&gt;location ~ \.(jpg|gif|png|ico|jpeg|css|swf)$ {
                expires 7d;
        }&lt;/pre&gt;
&lt;p&gt;nginx translates this config to an equivalent HTTP cache header. In this case, the server sends a &amp;#8220;Expires&amp;#8221; or &amp;#8220;Cache-Control: max-age=n&amp;#8221; header for all images (amongst others) and expects the client to cache them for 7 days. This means, you normally don&amp;#8217;t have to re-request the same content again within the next 7 days. Every major web browser (and intermediate proxies) respects this header and works as expected. Unfortunately, a vast majority of the open source image caching frameworks for iOS, including the popular SDWebImage, uses a built in cache control mechanism, that deletes images after n days. The problem here is, these frameworks don&amp;#8217;t cater to validation model and your mobile client application that uses these frameworks must resort to hacks.&lt;/p&gt;
&lt;p&gt;Let me show you an example where this could go wrong. Lets&amp;#8217; go back to our &amp;#8220;next Facebook&amp;#8221; app. When your user uploads an avatar image, he expects to see the changes propagated on all the views. Some clever developers empty the cache after the call to update-profile-image succeeds. (This means, every view controller now have to load the content from the server again). Everything goes well and you have successfully cheated your project manager and every view controller now shows the latest profile picture. However, it doesn&amp;#8217;t eliminate the problem completely. The user&amp;#8217;s new profile picture is visible to his friends only after 7 days. Clearly unacceptable. So how do you solve this? As I already told, you have to accept the fact that the server is the only authoritative source for the latest data. Don&amp;#8217;t use dirty tricks on the client to expire the cache.&lt;/p&gt;
&lt;span id="Validation_model"&gt;&lt;h3&gt;Validation model&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;Both Facebook and Twitter solve the problem of expiring profile images (after a new image is uploaded) using validation model. In a validation model, the server sends an identifier unique to the requested resource and the client caches both the identifier and the response. In HTTP parlance, this unique identifier is called as an ETag. When you make a second request to the same resource, you should send this ETag. The server uses this identifier to check if the resource you requested has changed (remember, the server is &lt;strong&gt;the&lt;/strong&gt; authoritative source). If the resource has indeed changed, it sends you the latest copy. Otherwise, it sends a 304 Not Modified. Validation model requires programming effort on both client and server. I&amp;#8217;ll walk you through both in the next section.&lt;/p&gt;
&lt;span id="Client_side_coding"&gt;&lt;h4&gt;Client side coding&lt;/h4&gt;&lt;/span&gt;
&lt;p&gt;As a matter of fact, on iOS, if you use &lt;a href="http://blog.mugunthkumar.com/coding/ios-tutorial-image-cache-and-loading-thumbnails-using-mknetworkkit/"&gt;MKNetworkKit, it does all these automatically for you&lt;/a&gt;. But for the sake of Android and Windows Phone developers, I&amp;#8217;ll explain how this should be implemented.&lt;/p&gt;
&lt;p&gt;The validation model uses &lt;strong&gt;ETag&lt;/strong&gt; and &lt;strong&gt;Last-Modified&lt;/strong&gt; HTTP Headers. Client side support for validation model is easier than server side implementation. If you received a ETag with a resource, when you make a second request to the same resource, send the ETag in &amp;#8220;IF-NONE-MATCH&amp;#8221; header. Alternatively, if you received a &amp;#8220;Last-Modified&amp;#8221; with a resource, send it in &amp;#8220;IF-MODIFIED-SINCE&amp;#8221; header on subsequent requests. Again, the server determines when to use &amp;#8220;ETags&amp;#8221; and when to use &amp;#8220;Last-Modified&amp;#8221;&lt;/p&gt;
&lt;p&gt;&lt;img style="display:block; margin-left:auto; margin-right:auto;" src="http://blog.mugunthkumar.com/wp-content/uploads/RESTful-caching.png" alt="Implementing caching in your API server" title="RESTful caching.png" border="0" width="600" height="557" /&gt;&lt;/p&gt;
&lt;p&gt;Implementing expiration model is easy. Just calculate the expiry date based on the headers, &amp;#8220;Expires&amp;#8221; or &amp;#8220;Cache-Control:max-age-n&amp;#8221; and delete the cache after this day.&lt;/p&gt;
&lt;span id="Server_side_coding"&gt;&lt;h4&gt;Server side coding&lt;/h4&gt;&lt;/span&gt;
&lt;p&gt;&lt;strong&gt;ETag based caching&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ETags are usually calculated on the server using object hashing algorithms. (Most high level server side languages like Java/C#/Scala has methods to hash an object). Before serializing the responses, the server should compute the object hash and add this value to the header as ETag. Now, If the client has indeed sent a IF-NONE-MATCH in the request and that ETag matches with what you have computed, send a 304 Not Modified. Otherwise, serialize your response and send the new ETag.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Last-Modified based caching&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Last-Modified implementation is slightly tricky. Let&amp;#8217;s assume that you have an endpoint that points to thelist of friends resource.&lt;/p&gt;
&lt;p&gt;http://api.mynextfacebook.com/friends/&lt;/p&gt;
&lt;p&gt;When using ETags, you computed the hash of the array of friends. If you are using Last-Modified, you should send the Last-Modified date of this resource. Because this resource is a list; this date could actually mean the date when the user last accepted a new friend. It requires the server developer to store the last modified date for every user in the database. Slightly tricky than ETags, but there is a huge performance advantage.&lt;br /&gt;
When the client requests this resource for the first time, you send the complete list of friends. Subsequent requests from client will now have a &amp;#8220;IF-MODIFIED-SINCE&amp;#8221; header. Your server should be programmed to send only the list of friends that are added after this date. The database fetching pseudo code that was previously something like this,&lt;/p&gt;
&lt;p&gt;select * from friends&lt;/p&gt;
&lt;p&gt;becomes,&lt;/p&gt;
&lt;p&gt;select * from friends where friendedDate &amp;gt; IF-MODIFIED-SINCE&lt;/p&gt;
&lt;p&gt;If the database select returns zero results, send a 304 Not Modified. So if the user has 300 friends but only two of them are new friends, serialize and send only those two records back to the client. Your database fetching time and the resource payload is reduced by a huge margin. &lt;/p&gt;
&lt;p&gt;Of course, this is a super simplified pseudo code. Server developer will probably have a headache when you support unfriending (deletion) or blocking friends. The server should be able to send hints using which the client should be able to tell which all friends were newly added and which all were deleted. This technique in fact requires additional effort on the server side.&lt;/p&gt;
&lt;span id="Choosing_a_caching_model_for_your_resource"&gt;&lt;h3&gt;Choosing a caching model for your resource&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;Whew! That was some heavy stuff. I&amp;#8217;m now going to establish some ground rules on when to use what type of caching mechanism.&lt;/p&gt;
&lt;p&gt;1) All static images should be served using a expiration model.&lt;/p&gt;
&lt;p&gt;2) All dynamically changeable data should be served using a validation model.&lt;/p&gt;
&lt;p&gt;3) If your dynamic data is a list, you should use Last-Modified based validation model. (For example: /friends).&lt;br /&gt;
Other wise, you should use ETag based validation model (For example: /friends/firstname.lastname&lt;/p&gt;
&lt;p&gt;4) Images or any resource that might be updated by the user (like profile image) should again use the ETag based validation model. Though they are images, they are not static in your application (like your company logo). Moreover, you cannot reliably calculate the expiry date for such a resource. The other (slightly easier to implement but a bit hackish) way is to use a URL fault. URL fault works like this.&lt;br /&gt;
When you send a avatar URL embedded in a resource, make sure that, some part of the URL is dynamic. That is instead of representing an avatar URL as&lt;/p&gt;
&lt;p&gt;http://images.mynextfacebook.com/person/firstname.lastname/avatar&lt;/p&gt;
&lt;p&gt;represent it like this&lt;/p&gt;
&lt;p&gt;http://images.mynextfacebook.com/person/firstname.lastname/avatar/&amp;lt;randomhash&amp;gt;&lt;/p&gt;
&lt;p&gt;Ensure that the random hash changes when the user updates the image. The API that sends the list of friends resource will now have a different URL for friends who updated their image. Changes to profile images happen almost instantly!&lt;/p&gt;
&lt;p&gt;If both server and client adheres to already established caching standards, your iOS app and your product can &amp;#8220;fly&amp;#8221;. What I did in this post is a mere explanation of those standards which aren&amp;#8217;t followed by a vast majority of developers.&lt;/p&gt;
&lt;p&gt;That ends this part of the post. In the last and final part, we will discuss about how to communicate errors and do error handling properly and support internationalization for your application.&lt;/p&gt;
&lt;span id="Recommended_Reading"&gt;&lt;h2&gt;Recommended Reading&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;REST API Design Rulebook, By Mark Masse&lt;br /&gt;
&lt;a href="http://shop.oreilly.com/product/0636920021575.do"&gt;http://shop.oreilly.com/product/0636920021575.do&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8211;&lt;br /&gt;
Mugunth&lt;/p&gt;
&lt;p&gt;&lt;map name='google_ad_map_1615_8b86e81420c6776e'&gt;
&lt;area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/1615?pos=0' coords='1,2,367,28' /&gt;
&lt;area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/&gt;&lt;/map&gt;
&lt;img usemap='#google_ad_map_1615_8b86e81420c6776e' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;amp;client=&amp;amp;channel=&amp;amp;output=png&amp;amp;cuid=1615&amp;amp;url= http%3A%2F%2Fblog.mugunthkumar.com%2Farticles%2Frestful-api-server-doing-it-the-right-way-part-2%2F' /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href ="http://twitter.com/mugunthkumar"&gt;Follow me &lt;/a&gt; on Twitter&lt;/p&gt;&lt;p&gt;&amp;copy;2012 &lt;a href="http://blog.mugunthkumar.com"&gt;MKBlog&lt;/a&gt;. All Rights Reserved.&lt;/p&gt;.
&lt;p&gt;Related posts:&lt;ol&gt;
&lt;li&gt;&lt;a href='http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-1/' rel='bookmark' title='RESTful API Server &amp;#8211; Doing it the right way (Part 1)'&gt;RESTful API Server &amp;#8211; Doing it the right way (Part 1)&lt;/a&gt; &lt;small&gt;In 2007, Steve Jobs announced the iPhone that revolutionized the...&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nQkREsvUpi8oIJa0QXZIBUeWEZ8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nQkREsvUpi8oIJa0QXZIBUeWEZ8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nQkREsvUpi8oIJa0QXZIBUeWEZ8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nQkREsvUpi8oIJa0QXZIBUeWEZ8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MugunthKumar/~4/p98h9PlVe34" height="1" width="1"/&gt;</content><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-2/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><feedburner:origLink>http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-2/</feedburner:origLink></entry><entry><title type="text">Adding Twitter support (iOS 5 with oAuth fallback) to your iOS App with RSOAuthEngine</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MugunthKumar/~3/J57npISsqZM/" /><category term="Coding" /><category term="ios5" /><category term="mknetworkkit" /><category term="rsoauthengine" /><category term="twitter" /><author><name>Mugunth Kumar</name></author><updated>2012-03-14T07:05:15-07:00</updated><id>http://blog.mugunthkumar.com/?p=1668</id><summary type="html">Till today, the two most commonly used ways (without writing tediously long code) to integrate Twitter connect to your app is Ben Gottlieb&amp;#8217;s Twitter OAuth library By using ShareKit The only problem I have with both these libraries is that, they are bloated. You end up adding at least 20 classes (more than 50 files [...]
No related posts.</summary><content type="html">&lt;p&gt;&lt;/p&gt;&lt;p&gt;Till today, the two most commonly used ways (without writing tediously long code) to integrate Twitter connect to your app is&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/bengottlieb/Twitter-OAuth-iPhone/"&gt;Ben Gottlieb&amp;#8217;s Twitter OAuth library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;By using &lt;a href="http://getsharekit.com/"&gt;ShareKit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The only problem I have with both these libraries is that, they are bloated. You end up adding at least 20 classes (more than 50 files in the first case and even more if you go with ShareKit).&lt;/p&gt;
&lt;p&gt;Call me a person with &lt;a href="http://en.wikipedia.org/wiki/Not_invented_here"&gt;Not Invented Here&lt;/a&gt; syndrome, but I hate adding third party code unless it offers considerable number of features that is critical to the app&amp;#8217;s functionality. Today, when working on a code base, I deleted over 52 files that adds a functionality that allows a user to tweet &amp;#8220;achievements&amp;#8221; from within the app.&lt;/p&gt;
&lt;div class="wp-caption aligncenter" style="width: 610px"&gt;&lt;img style="border-style: initial; border-color: initial; border-width: 0px;" title="Deleting Twitter Sharing Code means getting rid of 52 files in your app" src="http://blog.mugunthkumar.com/wp-content/uploads/Xcode-24.jpg" alt="Deleting Twitter Sharing Code means getting rid of 52 files in your app" width="600" height="238" border="0" /&gt;&lt;p class="wp-caption-text"&gt;Deleting Twitter Sharing Code means getting rid of 52 files in your app&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;To me, this is a bloat. Same goes with ShareKit. You will use every single ShareKit supported social network &lt;strong&gt;only&lt;/strong&gt; if you are writing a Google Reader (or any RSS reader) app or a Instapaper competitor. In most apps, Facebook and Twitter sharing is all that you need. 52 files for that, is a BLOAT.&lt;/p&gt;
&lt;span id="Introducing_RSOAuthEngine"&gt;&lt;h2&gt;Introducing RSOAuthEngine&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;RSOAuthEngine, in the words of the original author (&lt;a href="https://twitter.com/#!/rsieiro"&gt;Rodrigo Sieiro&lt;/a&gt;), is a ARC based OAuth engine for &lt;a href="http://mknetworkkit.com"&gt;MKNetworkKit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;He originally posted his &lt;a href="https://github.com/rsieiro/RSOAuthEngine"&gt;RSOAuthEngine on Github&lt;/a&gt; about a month ago. It is possibly the leanest implementation of Twitter oAuth I&amp;#8217;ve ever seen. His sample code also contained a demo on how to use RSOAuthEngine with Twitter and with Instapaper.&lt;/p&gt;
&lt;span id="The_fork"&gt;&lt;h3&gt;The fork&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;Today, I &lt;a href="https://github.com/MugunthKumar/RSOAuthEngine"&gt;forked his code&lt;/a&gt; and added a neat and important feature, iOS 5 Twitter Accounts support. I added a category class and a config file to his code and this is how it looks now.&lt;/p&gt;
&lt;div class="wp-caption aligncenter" style="width: 259px"&gt;&lt;br /&gt;
&lt;img title="RSOAuthEngine based Twitter Connect ~ 10 files" src="http://blog.mugunthkumar.com/wp-content/uploads/RSOAuthEngine-Files.jpg" alt="RSOAuthEngine Files" width="249" height="205" border="0" /&gt;&lt;p class="wp-caption-text"&gt;RSOAuthEngine based Twitter Connect ~ 10 files&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Just 10 files (3 classes and a category addition) that enables your app users to send tweets from the app.&lt;br /&gt;
Since MKNetworkKit provides operation freezing by default, users can send tweets even when they are offline. Those tweets are queued, frozen and sent when the connectivity is back again.&lt;/p&gt;
&lt;span id="Using_RSOAuthEngine"&gt;&lt;h2&gt;Using RSOAuthEngine&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;&lt;strong&gt;Step 1: &lt;/strong&gt;&lt;br /&gt;
Clone the &lt;a href="https://github.com/MugunthKumar/RSOAuthEngine"&gt;RSOAuthEngine fork from github&lt;/a&gt;. Add the RSOauthEngine code by dragging the directories RSOAuthEngine, Twitter and UIActionSheet+MKAdditions. If you are not using &lt;a href="http://mknetworkkit.com"&gt;MKNetworkKit&lt;/a&gt;, you might have to add that too.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2: &lt;/strong&gt; Add the Twitter.framework and Account.Framework and weak link it. Weak linking ensures that your app doesn&amp;#8217;t crash on devices running iOS 4 and below. If you are adding MKNetworkKit for the first time, you might want to add the related frameworks as well. See this &lt;a href="http://blog.mugunthkumar.com/products/ios-framework-introducing-mknetworkkit/"&gt;blog post&lt;/a&gt; for details.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3: &lt;/strong&gt;Open RSTwitterConfigs.h and set the oAuth consumer key and consumer secret from twitter.&lt;br /&gt;
Fill in your callback URL. All these information should match exactly to the app you created on &lt;a href="https://dev.twitter.com/apps"&gt;twitter&amp;#8217;s website&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 4: &lt;/strong&gt;Initialize the RSTwitterEngine in your app delegate like this.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt; self.twitterEngine &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;RSTwitterEngine alloc&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt; initWithStatusChangedHandler&lt;span style="color: #002200;"&gt;:^&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #400080;"&gt;NSString&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;newStatus&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    DLog&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;%@&amp;quot;&lt;/span&gt;, newStatus&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt;;
  &lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Logging is purely optional.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 5: &lt;/strong&gt;To send a tweet, set the presenting view controller of the twitter engine to the current view controller (where the &amp;#8220;tweet/share button&amp;#8221; is present) and call the sendTweet method.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;ApplicationDelegate.twitterEngine.presentingViewController &lt;span style="color: #002200;"&gt;=&lt;/span&gt; self;
&amp;nbsp;
  &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;ApplicationDelegate.twitterEngine sendTweet&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;Hi there&amp;quot;&lt;/span&gt; withCompletionBlock&lt;span style="color: #002200;"&gt;:^&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #400080;"&gt;NSError&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;error&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
   &lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;span id="The_magic_behind_the_scenes"&gt;&lt;h3&gt;The magic behind the scenes&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;The fork I wrote automatically authenticates the user the first time you call the sendTweet:withCompletionBlock method. It presents a UIViewController with a UIWebView that shows the Twitter oAuth login page, extracts the credentials and saves it. The true magic is, on iOS 5+ devices, if the user has configured his twitter account on the Settings app, it shows the Twitter account authorization request and uses the built-in twitter account.&lt;/p&gt;
&lt;div class="wp-caption aligncenter" style="width: 340px"&gt;&lt;img style="border-style: initial; border-color: initial; border-width: 0px;" title="Accessing iOS Twitter Accounts" src="http://blog.mugunthkumar.com/wp-content/uploads/iOS-Simulator-1.png" alt="Accessing iOS Twitter Accounts" width="330" height="600" border="0" /&gt;&lt;p class="wp-caption-text"&gt;Accessing iOS Twitter Accounts&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If the user has configured multiple twitter accounts, he sees&lt;/p&gt;
&lt;div class="wp-caption aligncenter" style="width: 358px"&gt;&lt;img style="border-style: initial; border-color: initial; border-width: 0px;" title="The code automatically shows this dialog when multiple iOS Twitter Accounts are available" src="http://blog.mugunthkumar.com/wp-content/uploads/iOS-Simulator1.png" alt="The code automatically shows this dialog when multiple iOS Twitter Accounts are available" width="348" height="600" border="0" /&gt;&lt;p class="wp-caption-text"&gt;The code automatically shows this dialog when multiple iOS Twitter Accounts are available&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;If there is exactly 1 account, that account is automatically used without further prompts.&lt;/p&gt;
&lt;span id="The_fallback"&gt;&lt;h3&gt;The fallback&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;If there are no accounts configured or if the user is running iOS 4.3 or lower, the code falls back to traditional oAuth and shows a web view based authentication form.&lt;/p&gt;
&lt;p&gt;Once the authentication workflow is done, the tweet is sent. Authentication information is saved and reused in subsequent calls to sendTweet:withCompletionBlock:.&lt;/p&gt;
&lt;p&gt;The complete twitter sharing integration is done with just 3 classes. This, to me, is arguably the most leanest twitter sharing code in the Interwebs.&lt;/p&gt;
&lt;p&gt;Fork it share it and do whatever you want. The code (both mine and Rodrigo&amp;#8217;s) is licensed under MIT license.&lt;/p&gt;
&lt;p&gt;On similar lines, I just finished a Facebook Sharing library&lt;/p&gt;
&lt;p&gt;&amp;#8211;&lt;br /&gt;
Mugunth&lt;/p&gt;
&lt;p&gt;&lt;map name='google_ad_map_1668_8b86e81420c6776e'&gt;
&lt;area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/1668?pos=0' coords='1,2,367,28' /&gt;
&lt;area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/&gt;&lt;/map&gt;
&lt;img usemap='#google_ad_map_1668_8b86e81420c6776e' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;amp;client=&amp;amp;channel=&amp;amp;output=png&amp;amp;cuid=1668&amp;amp;url= http%3A%2F%2Fblog.mugunthkumar.com%2Fcoding%2Fadding-twitter-support-ios-5-with-oauth-fallback-to-your-ios-app-with-rsoauthengine%2F' /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href ="http://twitter.com/mugunthkumar"&gt;Follow me &lt;/a&gt; on Twitter&lt;/p&gt;&lt;p&gt;&amp;copy;2012 &lt;a href="http://blog.mugunthkumar.com"&gt;MKBlog&lt;/a&gt;. All Rights Reserved.&lt;/p&gt;.
&lt;p&gt;No related posts.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aelp-I_y18i8QBdHxLcJkHpE3XU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aelp-I_y18i8QBdHxLcJkHpE3XU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aelp-I_y18i8QBdHxLcJkHpE3XU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aelp-I_y18i8QBdHxLcJkHpE3XU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MugunthKumar/~4/J57npISsqZM" height="1" width="1"/&gt;</content><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.mugunthkumar.com/coding/adding-twitter-support-ios-5-with-oauth-fallback-to-your-ios-app-with-rsoauthengine/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">3</slash:comments><feedburner:origLink>http://blog.mugunthkumar.com/coding/adding-twitter-support-ios-5-with-oauth-fallback-to-your-ios-app-with-rsoauthengine/</feedburner:origLink></entry><entry><title type="text">ARC retain cycles and blocks</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MugunthKumar/~3/R3gQQ3lAJeQ/" /><category term="Coding" /><category term="arc" /><category term="blocks" /><category term="ios" /><category term="retain cycles" /><author><name>Mugunth Kumar</name></author><updated>2012-03-05T07:33:08-08:00</updated><id>http://blog.mugunthkumar.com/?p=1664</id><summary type="html">I wrote a method to add blocks based completion handler support to AVAudioPlayer. The calling code looks like this. __block MKAudioPlayer *player = &amp;#91;&amp;#91;MKAudioPlayer alloc&amp;#93; initWithResourceName:@&amp;#34;Test.mp3&amp;#34;&amp;#93;; &amp;#91;player playWithCompletionHandler:^&amp;#123; player = nil; &amp;#125;&amp;#93;; The playWithCompletionHandler method naively copies the block into a property like this. -&amp;#40;void&amp;#41; playWithCompletionHandler:&amp;#40;VoidBlock&amp;#41; block &amp;#123; &amp;#160; self.audioCompletedBlock = block; &amp;#91;self.thePlayer play&amp;#93;; &amp;#125; [...]
No related posts.</summary><content type="html">&lt;p&gt;&lt;/p&gt;&lt;p&gt;I wrote a method to add blocks based completion handler support to AVAudioPlayer. The calling code looks like this.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;__block MKAudioPlayer &lt;span style="color: #002200;"&gt;*&lt;/span&gt;player &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;MKAudioPlayer alloc&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt; initWithResourceName&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;Test.mp3&amp;quot;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;player playWithCompletionHandler&lt;span style="color: #002200;"&gt;:^&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
	player &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #a61390;"&gt;nil&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The playWithCompletionHandler method naively copies the block into a property like this.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #002200;"&gt;-&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #a61390;"&gt;void&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; playWithCompletionHandler&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;VoidBlock&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; block &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    self.audioCompletedBlock &lt;span style="color: #002200;"&gt;=&lt;/span&gt; block;
    &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self.thePlayer play&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Smell something? No? Not yet?&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s consider the other case where the block is a property and you set the completion handler like this&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;__block MKAudioPlayer &lt;span style="color: #002200;"&gt;*&lt;/span&gt;player &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;MKAudioPlayer alloc&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt; initWithResourceName&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;Test.mp3&amp;quot;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
player.completionHandler &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;^&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
	player &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #a61390;"&gt;nil&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;player play&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this case, LLVM compiler is clever enough to warn you. However, in the previous case, you end up with a retain cycle when the block copies the MKAudioPlayer reference within the playWithCompletionHandler method.&lt;/p&gt;
&lt;p&gt;Neither the LLVM compiler nor the static analyzer warn you about this. And that doesn&amp;#8217;t mean everything is fine. The first block of code leaks memory because of a retain cycle created when you copy the block.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BEWARE OF RETAIN CYCLES!&lt;/strong&gt; With ARC, It just got a little more difficult to debug problems related to memory leaks.&lt;/p&gt;
&lt;p&gt;I noted this problem a while ago when &lt;a href="https://twitter.com/#!/brianensorapps/status/175743886789054464"&gt;brianensorapps tweeted me&lt;/a&gt; a problem with my sample code and wrote this post after reading this tweet.&lt;/p&gt;
&lt;blockquote class="twitter-tweet"&gt;&lt;p&gt;Retain cycles caused by blocks have become one of the hardest problems in Cocoa programming in my opinion.&lt;/p&gt;
&lt;p&gt;— Ole Begemann (@olebegemann) &lt;a href="https://twitter.com/olebegemann/status/176668422090919936" data-datetime="2012-03-05T14:00:08+00:00"&gt;March 5, 2012&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I seriously wish Apple improves the LLVM static analyzer to avoid true negatives and catch, if possible, all retain cycles.&lt;/p&gt;
&lt;p&gt;&amp;#8211;&lt;br /&gt;
Mugunth&lt;/p&gt;
&lt;p&gt;&lt;map name='google_ad_map_1664_8b86e81420c6776e'&gt;
&lt;area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/1664?pos=0' coords='1,2,367,28' /&gt;
&lt;area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/&gt;&lt;/map&gt;
&lt;img usemap='#google_ad_map_1664_8b86e81420c6776e' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;amp;client=&amp;amp;channel=&amp;amp;output=png&amp;amp;cuid=1664&amp;amp;url= http%3A%2F%2Fblog.mugunthkumar.com%2Fcoding%2Farc-retain-cycles-and-blocks%2F' /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href ="http://twitter.com/mugunthkumar"&gt;Follow me &lt;/a&gt; on Twitter&lt;/p&gt;&lt;p&gt;&amp;copy;2012 &lt;a href="http://blog.mugunthkumar.com"&gt;MKBlog&lt;/a&gt;. All Rights Reserved.&lt;/p&gt;.
&lt;p&gt;No related posts.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4_2Qap-MwvFhpl1fyb9nz-YM3Mg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4_2Qap-MwvFhpl1fyb9nz-YM3Mg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4_2Qap-MwvFhpl1fyb9nz-YM3Mg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4_2Qap-MwvFhpl1fyb9nz-YM3Mg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MugunthKumar/~4/R3gQQ3lAJeQ" height="1" width="1"/&gt;</content><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.mugunthkumar.com/coding/arc-retain-cycles-and-blocks/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://blog.mugunthkumar.com/coding/arc-retain-cycles-and-blocks/</feedburner:origLink></entry><entry><title type="text">A note on MKInfoPanelDemo</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MugunthKumar/~3/4Ry5NnLSq1s/" /><category term="Personal" /><category term="rant" /><author><name>Mugunth Kumar</name></author><updated>2012-03-01T17:52:24-08:00</updated><id>http://blog.mugunthkumar.com/?p=1631</id><summary type="html">MKInfoPanel is a open source class written by me (that was available on Github) that attempts to mimic the non modal alerts used in Tweetbot. Yesterday, Tapbots tweeted that MKInfoPanelDemo, the open source iOS project, is infringing their copyrights and they weren&amp;#8217;t happy about the project on Github. A DMCA notice was sent to Github [...]
No related posts.</summary><content type="html">&lt;p&gt;&lt;/p&gt;&lt;p&gt;MKInfoPanel is a open source class written by me (that &lt;strong&gt;was&lt;/strong&gt; available on Github) that attempts to mimic the non modal alerts used in Tweetbot.&lt;/p&gt;
&lt;p&gt;Yesterday, &lt;a href="https://twitter.com/tapbot_paul/status/175030954757341184"&gt;Tapbots tweeted&lt;/a&gt; that MKInfoPanelDemo, the open source iOS project, is infringing their copyrights and they weren&amp;#8217;t happy about the project on Github. A DMCA notice was sent to Github (so far no one from Github contacted me on that) to remove the project, but I removed it before hand just to be on the safer side.&lt;/p&gt;
&lt;span id="What_you_should_know_"&gt;&lt;h3&gt;What you should know &lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;If you are using that on your projects or your client projects, &lt;strong&gt;please be assured that all the assets and colors used were recreated by me and not just a copy of what is shipped with Tapbot&amp;#8217;s application.&lt;/strong&gt; Sure, it looks similar to Tweetbot&amp;#8217;s implementation because it was an imitation of their work, much like &lt;a href="https://github.com/levey/QuadCurveMenu"&gt;Quad Curve Menu&lt;/a&gt;, or &lt;a href="http://blog.massivehealth.com/post/18563684407/clear"&gt;Clear app&amp;#8217;s open source implementation&lt;/a&gt; or the infamous &lt;a href="https://github.com/enormego/EGOTableViewPullRefresh"&gt;pull-to-refresh implementation by enormego&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All assets inside any IPA file are &lt;a href="http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html"&gt;byte swapped&lt;/a&gt; because PNG optimization is enabled by default. This means, you cannot lift a PNG file and re-use in your project at least easily (at least without reswapping those bits). It&amp;#8217;s far more easier to recreate them from scratch (come on, it&amp;#8217;s just an exclamation mark inside a triangle)&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not a lawyer, but the allegation that the project infringes their rights is completely baseless and wrong. Since the guys behind Tweetbot are not cool like Loren Brichter or Realmac Software, I&amp;#8217;ve decided to remove the code from Github. &lt;/p&gt;
&lt;p&gt;You can always get the code for educational purposes from here.&lt;/p&gt;
&lt;p&gt;Source Code&lt;br /&gt;
&lt;a href="http://blog.mugunthkumar.com/wp-content/uploads/MKInfoPanelDemo.zip" title="MKInfoPanelDemo.zip" alt="MKInfoPanelDemo"&gt;MKInfoPanelDemo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thanks for those innumerable DMs that you guys sent on how people would have mis-understood me for pulling the project. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;br /&gt;
The code is &lt;a href="https://github.com/MugunthKumar/MKInfoPanelDemo"&gt;available again on Github&lt;/a&gt; following this tweet.&lt;/p&gt;
&lt;blockquote class="twitter-tweet" data-in-reply-to="175561775159324672"&gt;&lt;p&gt;@&lt;a href="https://twitter.com/mugunthkumar"&gt;mugunthkumar&lt;/a&gt; @&lt;a href="https://twitter.com/Cocoanetics"&gt;Cocoanetics&lt;/a&gt; again you&amp;#8217;re welcome to re-submit the code, AFAIK the DCMA is no more.&lt;/p&gt;
&lt;p&gt;&amp;mdash; Paul Haddad (@tapbot_paul) &lt;a href="https://twitter.com/tapbot_paul/status/175562398277701632" data-datetime="2012-03-02T12:45:12+00:00"&gt;March 2, 2012&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;script src="//platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;Huge thanks to &lt;a href="http://cocoanetics.com/"&gt;@cocoanetics&lt;/a&gt; for making this happen.&lt;br /&gt;
&amp;#8211;&lt;br /&gt;
Mugunth&lt;/p&gt;
&lt;p&gt;&lt;map name='google_ad_map_1631_8b86e81420c6776e'&gt;
&lt;area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/1631?pos=0' coords='1,2,367,28' /&gt;
&lt;area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/&gt;&lt;/map&gt;
&lt;img usemap='#google_ad_map_1631_8b86e81420c6776e' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;amp;client=&amp;amp;channel=&amp;amp;output=png&amp;amp;cuid=1631&amp;amp;url= http%3A%2F%2Fblog.mugunthkumar.com%2Fpersonal%2Fa-note-on-mkinfopaneldemo%2F' /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href ="http://twitter.com/mugunthkumar"&gt;Follow me &lt;/a&gt; on Twitter&lt;/p&gt;&lt;p&gt;&amp;copy;2012 &lt;a href="http://blog.mugunthkumar.com"&gt;MKBlog&lt;/a&gt;. All Rights Reserved.&lt;/p&gt;.
&lt;p&gt;No related posts.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mc4dYvwvSfFHQloF1JTAnaqAINo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mc4dYvwvSfFHQloF1JTAnaqAINo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mc4dYvwvSfFHQloF1JTAnaqAINo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mc4dYvwvSfFHQloF1JTAnaqAINo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MugunthKumar/~4/4Ry5NnLSq1s" height="1" width="1"/&gt;</content><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.mugunthkumar.com/personal/a-note-on-mkinfopaneldemo/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">2</slash:comments><feedburner:origLink>http://blog.mugunthkumar.com/personal/a-note-on-mkinfopaneldemo/</feedburner:origLink></entry><entry><title type="text">RESTful API Server – Doing it the right way (Part 1)</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MugunthKumar/~3/PM-cUv4jDMI/" /><category term="Articles" /><category term="Featured Articles" /><category term="android" /><category term="api" /><category term="ios" /><category term="ipad" /><category term="iphone" /><category term="objective c" /><category term="restful" /><author><name>Mugunth Kumar</name></author><updated>2012-03-01T07:01:25-08:00</updated><id>http://blog.mugunthkumar.com/?p=1401</id><summary type="html">In 2007, Steve Jobs announced the iPhone that revolutionized the technology industry and changed the way we work and do business. It is 2012 now and increasingly, more and more websites are offering native iOS and Android clients as front ends to their service. Not all startups have the funding to develop apps in addition [...]
Related posts:&lt;ol&gt;
&lt;li&gt;&lt;a href='http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-2/' rel='bookmark' title='RESTful API Server &amp;#8211; Doing it the right way (Part 2)'&gt;RESTful API Server &amp;#8211; Doing it the right way (Part 2)&lt;/a&gt; &lt;small&gt;In the part 1 of the post, I introduced the...&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;</summary><content type="html">&lt;p&gt;&lt;/p&gt;&lt;p&gt;In 2007, Steve Jobs announced the iPhone that revolutionized the technology industry and changed the way we work and do business. It is 2012 now and increasingly, more and more websites are offering native iOS and Android clients as front ends to their service. Not all startups have the funding to develop apps in addition to their core product. To increase the adoption rate of their product, these companies, release a public API that developers can use to build apps on top. Twitter was probably the first company to be &amp;#8220;API first&amp;#8221; and now increasingly more number of companies are following this strategy as it is really a great way to build an ecosystem around your product.&lt;/p&gt;
&lt;p&gt;Startup life is full of pivots. If you code base cannot support the pivoting decisions you make, you lose. A server code that is nimble enough to adapt to business needs, decides the make or break of a startup. Successful startups are not those that come up with great ideas, but those that are good at executing them. Success of a startup depends on the success of their product, whether it&amp;#8217;s their iOS app or their service or their API. In my past 3 years, I&amp;#8217;ve worked on a variety of iOS apps (mostly for startups) consuming web services and in this blog, I&amp;#8217;ve tried to consolidate my knowledge and show you the best practices that you should adopt when developing a RESTful API. A good RESTful API is one that is not resistive to changes.&lt;/p&gt;
&lt;div class='toc toc'&gt;
&lt;h2&gt;Contents&lt;/h2&gt;
&lt;ul class='toc-odd level-1'&gt;
	&lt;li&gt;
		&lt;a href="#Target_Audience"&gt;Target Audience&lt;/a&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;a href="#Structure_and_Organization"&gt;Structure and Organization&lt;/a&gt;
	&lt;/li&gt;
	&lt;li&gt;
		&lt;a href="#RESTful_constraints"&gt;RESTful constraints&lt;/a&gt;
		&lt;ul class='toc-even level-2'&gt;
			&lt;li&gt;
				&lt;a href="#Statelessness"&gt;Statelessness&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#Cacheable_and_a_Layered_architecture"&gt;Cacheable and a Layered architecture&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#Client-server_separation_of_concerns_and_a_uniform_interface"&gt;Client-server separation of concerns and a uniform interface&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#REST_Requests_and_the_four_HTTP_methods"&gt;REST Requests and the four HTTP methods&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#Cacheable_constraint_and_GET_requests"&gt;Cacheable constraint and GET requests&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#That_POST_vs_PUT_debate"&gt;That POST vs PUT debate&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#DELETE_method"&gt;DELETE method&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#REST_Responses"&gt;REST Responses&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#Authentication"&gt;Authentication&lt;/a&gt;
			&lt;/li&gt;
		&lt;/ul&gt;
	&lt;li&gt;
		&lt;a href="#API_documentation"&gt;API documentation&lt;/a&gt;
		&lt;ul class='toc-even level-2'&gt;
			&lt;li&gt;
				&lt;a href="#Documentation"&gt;Documentation&lt;/a&gt;
				&lt;ul class='toc-odd level-3'&gt;
					&lt;li&gt;
						&lt;a href="#Documenting_Request_Parameters"&gt;Documenting Request Parameters&lt;/a&gt;
					&lt;/li&gt;
					&lt;li&gt;
						&lt;a href="#Documenting_Response_Parameters"&gt;Documenting Response Parameters&lt;/a&gt;
					&lt;/li&gt;
				&lt;/ul&gt;
&lt;/ul&gt;
			&lt;li&gt;
				&lt;a href="#Reasons_to_version_and_deprecate_your_API"&gt;Reasons to version and deprecate your API&lt;/a&gt;
				&lt;ul class='toc-even level-2'&gt;
					&lt;li&gt;
						&lt;a href="#Versioning"&gt;Versioning&lt;/a&gt;
						&lt;ul class='toc-odd level-3'&gt;
							&lt;li&gt;
								&lt;a href="#Versioned_URL_paradigm"&gt;Versioned URL paradigm&lt;/a&gt;
							&lt;/li&gt;
							&lt;li&gt;
								&lt;a href="#Versioned_model_paradigm"&gt;Versioned model paradigm&lt;/a&gt;
							&lt;/li&gt;
						&lt;/ul&gt;
					&lt;li&gt;
						&lt;a href="#Deprecation"&gt;Deprecation&lt;/a&gt;
					&lt;/li&gt;
				&lt;/ul&gt;
			&lt;li&gt;
				&lt;a href="#Caching"&gt;Caching&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#Error_handling_amp_Internationalization_of_your_API"&gt;Error handling &amp;amp; Internationalization of your API&lt;/a&gt;
			&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class='toc-end'&gt;&amp;nbsp;&lt;/div&gt;
&lt;span id="Target_Audience"&gt;&lt;h2&gt;Target Audience&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;This blog post is targeted for readers who have intermediate to advanced knowledge in developing RESTful APIs and some basic knowledge of any object oriented (or functional) server side programming language like Java/Ruby/Scala. (Note: I intentionally ignored PHP or &lt;a href="http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html"&gt;Programmable Hyperlinked Pasta&lt;/a&gt;)&lt;/p&gt;
&lt;span id="Structure_and_Organization"&gt;&lt;h2&gt;Structure and Organization&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;The post is quite detailed and the first part explains basics of REST and the second part explains documenting and versioning your API. The first part is for beginners. The second part is for pros. I know, you are a pro. So, here is a link to jump ahead to &lt;a href="#API_documentation"&gt;API documentation&lt;/a&gt; section right away! This is probably where you should start if you think this post is a &lt;a href="http://www.urbandictionary.com/define.php?term=tl%3Bdr"&gt;tl;dr&lt;/a&gt;.&lt;/p&gt;
&lt;span id="RESTful_constraints"&gt;&lt;h2&gt;RESTful constraints&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;A RESTful server is one that conforms to the REST constraints. Here is a Wikipedia article on &lt;a href="http://en.wikipedia.org/wiki/Representational_state_transfer"&gt;REST&lt;/a&gt;. When you develop a API that would predominantly be consumed by a mobile device, following and understanding the three most important constraints would be helpful, not just in developing the API, but in maintaining it and making changes moving forward. Let me explain.&lt;/p&gt;
&lt;span id="Statelessness"&gt;&lt;h3&gt;Statelessness&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;The first constraint is statelessness. Put in simple words, a RESTful server should not contain contextual information about the client. A client, on the other hand, can maintain context of the server&amp;#8217;s state though. In other words, you shouldn&amp;#8217;t make your server remember the state of a mobile device using an API.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s imagine that your startup is the &amp;#8220;next Facebook&amp;#8221;. A good example of where a developer would potentially make such mistakes is to expose an API that allows a mobile device to set the last read item on a stream (say a Facebook feed). API endpoint that normally returns the feed (say /feed) will now return items that are new after this last read item. Sounds clever right? You &amp;#8220;optimize&amp;#8221; the data transfer between the client and server right? Wrong.&lt;/p&gt;
&lt;p&gt;What could possibly go wrong in this case is when the user accesses your service from two or three devices and one device sets the last read status and the other device doesn&amp;#8217;t have a way to download items that was already read on other devices.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Stateless means, the data returned for a specific API call should not be dependent on calls that are made before it.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The right way to optimize this call, is to pass the timestamp of the last read feed item to the server along with the API call that returns the feed (/feed?lastFeed=20120228). There are other, more standard way of doing this using HTTP Modified Since header. But we will leave that for now. I&amp;#8217;ll discuss this in part 2 of this post.&lt;/p&gt;
&lt;p&gt;The client, however can (should) remember access tokens generated on the server and send it other APIs that require them.&lt;/p&gt;
&lt;span id="Cacheable_and_a_Layered_architecture"&gt;&lt;h3&gt;Cacheable and a Layered architecture&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;The second constraint is to provide a certainty to the client that a response can be cached and reused for a set period of time without making round trips to server. This client can be the real mobile client or any intermediate proxy server. I will explain more about caching later in part 2 of this post.&lt;/p&gt;
&lt;span id="Client-server_separation_of_concerns_and_a_uniform_interface"&gt;&lt;h3&gt;Client-server separation of concerns and a uniform interface&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;A RESTful server should abstract and hide away as much implementation details as possible from the client. That is, the client shouldn&amp;#8217;t bother (or know) about what database the server uses or how many load balancers are currently active and other such stuff. Maintaining a &lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns"&gt;good separation of concerns&lt;/a&gt; helps in scaling when your product becomes &amp;#8220;viral&amp;#8221;.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s probably the three most important constraints you should have in mind while developing a RESTful server. There are three other minor constraints, but they all overlap with what we discussed here.&lt;/p&gt;
&lt;span id="REST_Requests_and_the_four_HTTP_methods"&gt;&lt;h3&gt;REST Requests and the four HTTP methods&lt;/h3&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;GET&lt;/li&gt;
&lt;li&gt;POST&lt;/li&gt;
&lt;li&gt;PUT&lt;/li&gt;
&lt;li&gt;DELETE&lt;/li&gt;
&lt;/ul&gt;
&lt;span id="Cacheable_constraint_and_GET_requests"&gt;&lt;h3&gt;Cacheable constraint and GET requests&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;Key takeaway from this is, GET method doesn&amp;#8217;t alter the server state. This inherently means your requests could be cached by any intermediate proxies (think: reduced load). So as a server developer, you shouldn&amp;#8217;t expose a &amp;#8220;GET&amp;#8221; method that updates data in your database. It breaks RESTful philosophy specifically the second constraint I talked about earlier. Your &amp;#8220;GET&amp;#8221; methods should not even update a access log or insert a record that maintains the &amp;#8220;last logged in&amp;#8221; time. If you are updating your database, it should be always be a POST/PUT method.&lt;/p&gt;
&lt;span id="That_POST_vs_PUT_debate"&gt;&lt;h3&gt;That POST vs PUT debate&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;The HTTP 1.1 specification says, PUT is &lt;a href="http://en.wikipedia.org/wiki/Idempotence"&gt;idempotent&lt;/a&gt;. This means, the client can make multiple PUT requests to the same URI and yet doesn&amp;#8217;t create/update duplicate records.&lt;/p&gt;
&lt;p&gt;Assignment operations are a good example of idempotent operation.&lt;/p&gt;
&lt;pre&gt;String userId = this.request["USER_ID"];&lt;/pre&gt;
&lt;p&gt;Even if this operation is executed twice or three times, there is no harm (other than lost CPU cycles).&lt;/p&gt;
&lt;p&gt;POST on the other hand is &lt;strong&gt;not&lt;/strong&gt; idempotent. It&amp;#8217;s like an increment operator. You should use POST or PUT based on whether or not the action performed is idempotent. In programmer&amp;#8217;s parlance, if the client &amp;#8220;knows&amp;#8221; the URL of the object that would be created, you should use PUT. If the client knows the URL of the creator/factory, use POST.&lt;/p&gt;
&lt;pre&gt;PUT www.example.com/post/1234&lt;/pre&gt;
&lt;p&gt;Use PUT if the client knows the URI that would be created as a result of the call. Even if the client calls this PUT method multiple times, there is no harm or no duplicate records created.&lt;/p&gt;
&lt;pre&gt;POST www.example.com/createpost&lt;/pre&gt;
&lt;p&gt;Use POST if the server creates the unique key and sends results back to the client. Duplicate records will be created when the call is repeated later on with the same parameters.&lt;/p&gt;
&lt;p&gt;Read &lt;a href="http://stackoverflow.com/a/2691891/90165"&gt;this answer&lt;/a&gt; on Stackoverflow for more.&lt;/p&gt;
&lt;span id="DELETE_method"&gt;&lt;h3&gt;DELETE method&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;DELETE is straight forward. It&amp;#8217;s again idempotent like PUT, and should be used to delete a record if it is present.&lt;/p&gt;
&lt;span id="REST_Responses"&gt;&lt;h3&gt;REST Responses&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;Responses from your RESTful server can either use XML or JSON. Personally, I would prefer JSON over XML as JSON is less verbose and data transferred is usually less compared to the same response in XML format. The difference might be in the order of a few hundred kilobytes, but given the speed of 3G networks and intermittent mobile data connectivity, these few hundred kilobyte changes can have a huge impact when downloading the response data.&lt;/p&gt;
&lt;span id="Authentication"&gt;&lt;h3&gt;Authentication&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;Authentication should be done over https and the client should send the password encrypted using some cryptographic algorithm. Getting a sha1 hash of a NSString in Objective-C is fairly straight forward and the following code illustrates this.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #002200;"&gt;-&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #400080;"&gt;NSString&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; sha1
&lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
	&lt;span style="color: #a61390;"&gt;const&lt;/span&gt; &lt;span style="color: #a61390;"&gt;char&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;cstr &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self cStringUsingEncoding&lt;span style="color: #002200;"&gt;:&lt;/span&gt;NSUTF8StringEncoding&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
	&lt;span style="color: #400080;"&gt;NSData&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;data &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #400080;"&gt;NSData&lt;/span&gt; dataWithBytes&lt;span style="color: #002200;"&gt;:&lt;/span&gt;cstr length&lt;span style="color: #002200;"&gt;:&lt;/span&gt;self.length&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&amp;nbsp;
	uint8_t digest&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;CC_SHA1_DIGEST_LENGTH&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&amp;nbsp;
	CC_SHA1&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;data.bytes, data.length, digest&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
	&lt;span style="color: #400080;"&gt;NSMutableString&lt;/span&gt;&lt;span style="color: #002200;"&gt;*&lt;/span&gt; output &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #400080;"&gt;NSMutableString&lt;/span&gt; stringWithCapacity&lt;span style="color: #002200;"&gt;:&lt;/span&gt;CC_SHA1_DIGEST_LENGTH &lt;span style="color: #002200;"&gt;*&lt;/span&gt; &lt;span style="color: #2400d9;"&gt;2&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&amp;nbsp;
	&lt;span style="color: #a61390;"&gt;for&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #a61390;"&gt;int&lt;/span&gt; i &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #2400d9;"&gt;0&lt;/span&gt;; i &amp;lt;; CC_SHA1_DIGEST_LENGTH; i&lt;span style="color: #002200;"&gt;++&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt;
		&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;output appendFormat&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;%02x&amp;quot;&lt;/span&gt;, digest&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;i&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&amp;nbsp;
	&lt;span style="color: #a61390;"&gt;return&lt;/span&gt; output;
&lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The server should match the encrypted password with the encrypted password stored previously on the server. In any case, you should never transfer passwords in plain text from the client to the server. There is NO EXCEPTION to this rule. The day your users come to know that you are storing passwords as plain text will probably be the day your startup dies. Trust that is once lost can never be gotten back.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.ietf.org/rfc/rfc2617.txt"&gt;RFC 2617&lt;/a&gt; specifies two ways to authenticate with a HTTP server. The first is Basic Access Authentication and the second is Digest Authentication. For internal mobile client use, Basic or Digest authentication is sufficient and most server side (and client side) languages have built in mechanism for implementing this authentication scheme.&lt;br /&gt;
If you are planning to make your API public, you should consider using oAuth or better oAuth 2.0. oAuth allows your end users to share the content created within your application with other third party vendors without handling over the keys (username/password). oAuth also allows user to be in full control over what is shared and what is rights do the requesting third party application has.&lt;/p&gt;
&lt;p&gt;Facebook Graph API is, by and large, the biggest implementation of oAuth to date. By using oAuth, a Facebook user can share photos with a third party application without sharing other personal information and his access details (username/password). A user can also revoke access to a &amp;#8220;rogue&amp;#8221; third party application without changing his password.&lt;/p&gt;
&lt;p&gt;So far, I talked about the basics of REST. Now lets dive into the meat of the post. In the subsequent sections I&amp;#8217;ll talk about best practices that you should follow when documenting, versioning and deprecating your API.&lt;/p&gt;
&lt;span id="API_documentation"&gt;&lt;h2&gt;API documentation&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;The worst documentation that a server developer could write is the one that contains a laundry list of API endpoints, the parameters that are required and the corresponding response from the server. The problem with this is, it&amp;#8217;s too difficult to make incremental changes to the server and changing response data as the product evolves becomes a nightmare. I&amp;#8217;m proposing some suggestions on how to document your API so that a client developer would understand you better. In the course of time, that will also help you in becoming a better server developer!&lt;/p&gt;
&lt;span id="Documentation"&gt;&lt;h3&gt;Documentation&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;The first step, I would recommend, is to start thinking about your top level model objects before you start the documentation. Then think about actions that can be done on these objects. The &lt;a href="https://developer.foursquare.com/docs/"&gt;foursquare API documentation&lt;/a&gt; is a good example to start with. They have a set of top level objects like venues, users and so on. They also have a set of actions that can be performed on these objects. Once you know the top level objects and actions in your product, designing the endpoints becomes easier and clearer. For example, to &amp;#8220;add&amp;#8221; a new venue, you would probably have to call a method similar to /venues/add&lt;/p&gt;
&lt;p&gt;Document every member of the top level objects in your documentation. Next, document your request and responses using these top level objects rather than raw primitive data types. Instead of writing, this API would return three strings, the first being the id, second name and third description, write that this API would return a venue model.&lt;/p&gt;
&lt;span id="Documenting_Request_Parameters"&gt;&lt;h4&gt;Documenting Request Parameters&lt;/h4&gt;&lt;/span&gt;
&lt;p&gt;Let&amp;#8217;s assume that you have a API that allows the user to login with a Facebook token. Let&amp;#8217;s call that api as /login.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Request &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;/login&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Headers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Authorization: Token XXXXX&lt;br /&gt;
User-Agent: MyGreatApp/1.0&lt;br /&gt;
Accept: application/json&lt;br /&gt;
Accept-Encoding: compress, gzip&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Encoding type &amp;#8211; application/x-www-form-urlencoded&lt;/p&gt;
&lt;p&gt;token &amp;#8211; &amp;#8220;Facebook Auth Token&amp;#8221; (mandatory)&lt;/p&gt;
&lt;p&gt;profileInfo = &amp;#8220;json string containing public profile information from Facebook&amp;#8221; (optional)&lt;/p&gt;
&lt;p&gt;This profileInfo is a &lt;em&gt;top-level object&lt;/em&gt;. Since you have already documented this object&amp;#8217;s internal structure, mentioning this alone would suffice.&lt;/p&gt;
&lt;p&gt;If your server uses the same Accept, Accept-Encoding and parameter encoding, you can document it separately instead of repeating them everywhere.&lt;/p&gt;
&lt;span id="Documenting_Response_Parameters"&gt;&lt;h4&gt;Documenting Response Parameters&lt;/h4&gt;&lt;/span&gt;
&lt;p&gt;Responses from API should be documented based on the top level model objects. Quoting from the same foursquare example, the /venue/#venueid# method returns a &lt;a href="https://developer.foursquare.com/docs/responses/venue"&gt;complete venue model&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In case your model is big and you want to reduce the payload, consider creating a &lt;em&gt;compact model&lt;/em&gt;. You should use this for APIs that return a list of model objects. Foursquare&amp;#8217;s API does this as well. Their search API returns an array of &lt;a href="https://developer.foursquare.com/docs/responses/venue"&gt;compact venue&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Exchanging ideas, documenting or letting other developers know what you will return has just gotten easier when you document your API using model objects. The most important takeaway from this section is to treat this document as a contract between you, the server developer and client developers (iOS/Android/Windows Phone/Whatever)&lt;/p&gt;
&lt;span id="Reasons_to_version_and_deprecate_your_API"&gt;&lt;h2&gt;Reasons to version and deprecate your API&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;Prior to mobile applications, in the era of Web 2.0 applications, API versioning was never a problem. Both the client (Javascript/AJAX front-end) and the server was deployed at the same time. Consumers (your customers) always use the latest front-end client to access your system. Since you are the company that writes both the client and server, you have full control over how to use your API and changes to the API can always be implemented immediately on the front-end. Unfortunately, with native clients this is not possible. You might deploy API version 2 assuming everything will go well, but will blow up on older versions of your iOS apps because there would be still users using the older version of iPhone app even after you pushed an update through App Store. Some companies resort to using push notification to pester users to update their app. This will only end up in losing that customer. I have seen many many iPhones that have more than a 100 app updates pending. There is a pretty good chance that your app might be one of them. You should always be prepared for versioning the API and deprecate them as and when it&amp;#8217;s proper to do so. But do support your APIs for at least three months.&lt;/p&gt;
&lt;span id="Versioning"&gt;&lt;h3&gt;Versioning&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;Deploying your server code on a different directory and using a different URL endpoint doesn&amp;#8217;t automatically mean you have effectively migrated your server code.&lt;br /&gt;
That&amp;#8217;s&lt;br /&gt;
http://example.com/api/v1 will be used by version 1.0 of the app and your latest and greatest version 2.0 of the app will use http://example.com/api/v2&lt;/p&gt;
&lt;p&gt;When you make an update, you almost and always make changes to internal data structures, and model objects within your server. That includes changes to the database (adding or removing columns). To make things clear, let&amp;#8217;s assume that your &amp;#8220;next Facebook&amp;#8221; app has a API called /feed that returns &amp;#8220;Feed&amp;#8221; objects.&lt;br /&gt;
Today, as of version 1, your Feed object contains a URL to a person&amp;#8217;s picture (avatarURL), the person name (personName) the feed entry text (feedEntryText) and the timestamp (timeStamp) of the news entry.&lt;br /&gt;
Later on, in your version 2, you introduce a feature where you allow advertisers to market their products in the feed. Now, your feed object contains, let&amp;#8217;s say, a new field called &amp;#8220;sourceName&amp;#8221; that super cedes person name on the UI. That&amp;#8217;s, the app should display &amp;#8220;sourceName&amp;#8221;, instead of &amp;#8220;personName&amp;#8221;. Since the UI no longer need to display personName when &amp;#8220;sourceName&amp;#8221; is present, you decide not to send &amp;#8220;personName&amp;#8221; when &amp;#8220;sourceName&amp;#8221; is present. This all sounds good till the older version, version 1 of your application hits your newly deployed server. It starts displaying your advertised entries without a title since &amp;#8220;personName&amp;#8221; is missing. A &amp;#8220;clever&amp;#8221; way of handling this, is to send both &amp;#8220;personName&amp;#8221; and &amp;#8220;sourceName&amp;#8221;. But, my friend, life isn&amp;#8217;t always that easy. As a developer, you can&amp;#8217;t keep track of every single change that has ever been made for every single model object in your class. It&amp;#8217;s just not an efficient way of doing it and 6 months later, you will almost forget why &lt;em&gt;something&lt;/em&gt; was added to your code.&lt;/p&gt;
&lt;p&gt;Thinking back, in web 2.0, this wasn&amp;#8217;t a problem at all. The Javascript front-end would have been immediately updated to cater to the API changes. However iOS apps are disconnected unlike a web application. It&amp;#8217;s the user&amp;#8217;s prerogative to update it.&lt;/p&gt;
&lt;p&gt;I have a very elegant solution to propose for this kind of tricky situation.&lt;/p&gt;
&lt;span id="Versioned_URL_paradigm"&gt;&lt;h4&gt;Versioned URL paradigm&lt;/h4&gt;&lt;/span&gt;
&lt;p&gt;First is to differentiate multiple versions using the URL.&lt;br /&gt;
http://api.example.com/v1/feeds will be consumed by version 1 of the iOS app and&lt;br /&gt;
http://api.example.com/v2/feeds will be consumed by version 2 of the iOS app.&lt;/p&gt;
&lt;p&gt;While this method sounds good, you can&amp;#8217;t go on creating duplicate copies of your deployed code base for every single change you make to the output format. I recommend this only when you make a huge breaking release/change. For minor changes, consider versioning your models.&lt;/p&gt;
&lt;span id="Versioned_model_paradigm"&gt;&lt;h4&gt;Versioned model paradigm&lt;/h4&gt;&lt;/span&gt;
&lt;p&gt;I showed you how to document your models a while ago. Consider this document as a contractual agreement between the server and client developer. You should never make a change to this model without changing the version. This means, in our previous case, there would be two models, Feed1 and Feed2.&lt;br /&gt;
Feed2 has sourceName and outputs sourceName and removes personName when sourceName is present.&lt;br /&gt;
Feed1 behavior remains same like how it was agreed upon when documented.&lt;/p&gt;
&lt;p&gt;The request controller code flow will look closely similar to this.&lt;/p&gt;
&lt;div class="wp-caption alignnone" style="width: 354px"&gt;&lt;img style="border-style: initial; border-color: initial; border-width: 0px;" title="RESTful controller pseudo-code flow chart" src="http://blog.mugunthkumar.com/wp-content/uploads/IMG_0078.jpg" alt="RESTful controller pseudo-code flow chart" width="344" height="600" border="0" /&gt;&lt;p class="wp-caption-text"&gt;RESTful controller pseudo-code flow chart&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;You should consider moving the instantiation code into the class as a &lt;a href="http://en.wikipedia.org/wiki/Factory_method_pattern"&gt;factory method&lt;/a&gt;. The controller pseudo-code should look similar to this&lt;/p&gt;
&lt;pre&gt;Feed myFeedObject = Feed.createFeedObject("1.0");
myFeedObject.populateWithDBObject(FeedDao* feedDaoObject);&lt;/pre&gt;
&lt;p&gt;Whether it is 1.0 or 2.0 is decided by the controller from the UserAgent string. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;br /&gt;
Rather than depending on version numbers in UserAgent string, the client should send the version number in Accept header.&lt;br /&gt;
So instead of sending&lt;br /&gt;
&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Accept: application/json&lt;/strong&gt;&lt;br /&gt;
&lt;br/&gt;you should send&lt;br /&gt;
&lt;br/&gt;&lt;strong&gt;Accept: application/myservice.1.0+json&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This way, you have the ability to request a different version of response object for every REST resource you request.&lt;br /&gt;
Thanks for hacker news readers who sent this to me.&lt;/p&gt;
&lt;p&gt;The controller asks the Feed factory method to create the correct feed object based on the incoming request (all requests have UserAgent that looks like AppName/1.0) and based on the version of the client. When you implement your server like this, *any* change is easy. Making a change to your server without breaking existing contracts will be a breeze. Just create new models, make change to the factory method to instantiate this new model for newer versions and you are set to go!&lt;/p&gt;
&lt;p&gt;With this architecture in place, your version 1 and version 2 of the app can still talk to the same server. Your controller will render the version 1 object to the older client and version 2 object to the newer client.&lt;/p&gt;
&lt;span id="Deprecation"&gt;&lt;h3&gt;Deprecation&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;With the versioned model paradigm I proposed, deprecating your API gets a lot more easier. This is very important when you make your API public at a later stage.&lt;br /&gt;
When you make a major version update, cleanup all the factory methods in your models based on your business decisions.&lt;br /&gt;
If you decide not to support version 1 of the iOS app with the release of version 3 of the API, remove the associated models, remove the lines that instantiate version 1 of the model (in your factory method) and you are good to go.&lt;/p&gt;
&lt;p&gt;Versioning and deprecation goes a long way in ensuring the longevity of your company and the product by ensuring that you will always be nimble enough for most of the pivoting decisions made by the business owner. Businesses die when they cannot pivot. Usually resistance to pivoting comes internally from the technical team. This technique should solve that problem.&lt;/p&gt;
&lt;span id="Caching"&gt;&lt;h2&gt;Caching&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;The next important performance improvement that you should focus on when you build an API is to support caching. If you are like most other and think caching is a client side thing, think again. &lt;a href="http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-2/"&gt;Part 2 of this blog post&lt;/a&gt; explains how to support caching based on HTTP 1.1 standards.&lt;/p&gt;
&lt;span id="Error_handling_amp_Internationalization_of_your_API"&gt;&lt;h2&gt;Error handling &amp;amp; Internationalization of your API&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;Notifying your client of the kind of errors that happened on server is as important as sending the correct data. I&amp;#8217;ll explain about error handling and Internationalization of your API in part 3 of this post. Not making any promises, but this will surely take some time.&lt;/p&gt;
&lt;p&gt;&amp;#8211;&lt;br /&gt;
Mugunth&lt;/p&gt;
&lt;p&gt;&lt;map name='google_ad_map_1401_8b86e81420c6776e'&gt;
&lt;area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/1401?pos=0' coords='1,2,367,28' /&gt;
&lt;area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/&gt;&lt;/map&gt;
&lt;img usemap='#google_ad_map_1401_8b86e81420c6776e' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;amp;client=&amp;amp;channel=&amp;amp;output=png&amp;amp;cuid=1401&amp;amp;url= http%3A%2F%2Fblog.mugunthkumar.com%2Farticles%2Frestful-api-server-doing-it-the-right-way-part-1%2F' /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href ="http://twitter.com/mugunthkumar"&gt;Follow me &lt;/a&gt; on Twitter&lt;/p&gt;&lt;p&gt;&amp;copy;2012 &lt;a href="http://blog.mugunthkumar.com"&gt;MKBlog&lt;/a&gt;. All Rights Reserved.&lt;/p&gt;.
&lt;p&gt;Related posts:&lt;ol&gt;
&lt;li&gt;&lt;a href='http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-2/' rel='bookmark' title='RESTful API Server &amp;#8211; Doing it the right way (Part 2)'&gt;RESTful API Server &amp;#8211; Doing it the right way (Part 2)&lt;/a&gt; &lt;small&gt;In the part 1 of the post, I introduced the...&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/qP4Txi_XpJtK28mIfVQBX12_Vmc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qP4Txi_XpJtK28mIfVQBX12_Vmc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/qP4Txi_XpJtK28mIfVQBX12_Vmc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qP4Txi_XpJtK28mIfVQBX12_Vmc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MugunthKumar/~4/PM-cUv4jDMI" height="1" width="1"/&gt;</content><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-1/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">21</slash:comments><feedburner:origLink>http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-1/</feedburner:origLink></entry><entry><title type="text">Ownership of presented view controllers with and without ARC</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MugunthKumar/~3/17JS4KWYZXM/" /><category term="Articles" /><category term="arc" /><category term="ios" /><category term="ios 5" /><category term="objective c" /><category term="uiviewcontroller" /><author><name>Mugunth Kumar</name></author><updated>2012-02-25T19:58:42-08:00</updated><id>http://blog.mugunthkumar.com/?p=1587</id><summary type="html">Yesterday, I tweeted a classical design issue on who should own a view controller. The controller that presents a modal controller should dismiss it. Don&amp;#8217;t do [self dismissModalViewControllerAnimated:NO] in the child. — Mugunth Kumar () (@mugunthkumar) February 25, 2012 &amp;#160; Calling [self dismissModalViewControllerAnimated:NO] on child is like committing seppuku. A child shouldn&amp;#8217;t kill itself. — [...]
No related posts.</summary><content type="html">&lt;p&gt;&lt;/p&gt;&lt;p&gt;Yesterday, I tweeted a classical design issue on who should own a view controller.&lt;/p&gt;
&lt;blockquote class="twitter-tweet"&gt;&lt;p&gt;The controller that presents a modal controller should dismiss it. Don&amp;#8217;t do [self dismissModalViewControllerAnimated:NO] in the child.&lt;/p&gt;
&lt;p&gt;— Mugunth Kumar () (@mugunthkumar) &lt;a href="https://twitter.com/mugunthkumar/status/173412344003702785" data-datetime="2012-02-25T14:21:39+00:00"&gt;February 25, 2012&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote class="twitter-tweet"&gt;&lt;p&gt;Calling [self dismissModalViewControllerAnimated:NO] on child is like committing seppuku. A child shouldn&amp;#8217;t kill itself.&lt;/p&gt;
&lt;p&gt;— Mugunth Kumar () (@mugunthkumar) &lt;a href="https://twitter.com/mugunthkumar/status/173414228961656833" data-datetime="2012-02-25T14:29:08+00:00"&gt;February 25, 2012&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The negative replies I received to the tweet were phenomenal that I had to write this post explaining the &amp;#8220;why&amp;#8221; behind the tweet.&lt;/p&gt;
&lt;span id="Memory_management_with_pushed_view_controllers"&gt;&lt;h2&gt;Memory management with pushed view controllers&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;Things are straight forward when you &amp;#8220;push&amp;#8221; a view controller to the navigation stack. The UINavigationController retains/takes ownership of your view controller and you can forget about it. viewDidAppear/viewDidDisappear methods are called notifying the controllers to prepare itself. &lt;/p&gt;
&lt;span id="Memory_management_with_presented_view_controllers"&gt;&lt;h2&gt;Memory management with presented view controllers&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;However, this is not the case when you present a view controller modally.&lt;/p&gt;
&lt;span id="Memory_Management_pre_ARC"&gt;&lt;h2&gt;Memory Management pre ARC&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;Lets see how memory management worked in the pre-ARC era (read: last year). Before ARC, there are two ways to retain the child view controller. The first (and slightly cumbersome) method is to have a retain property for every child controller, on the parent controller.&lt;/p&gt;
&lt;span id="Method_1"&gt;&lt;h3&gt;Method 1&lt;/h3&gt;&lt;/span&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #a61390;"&gt;@interface&lt;/span&gt; MasterViewController
&lt;span style="color: #a61390;"&gt;@property&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;nonatomic, retain&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; ChildViewController &lt;span style="color: #002200;"&gt;*&lt;/span&gt;child;
&lt;span style="color: #a61390;"&gt;@end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Presenting the view modally requires you to allocate it and then present it.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;self.child &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;ChildViewController alloc&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt; initWith…&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
self.child.delegate &lt;span style="color: #002200;"&gt;=&lt;/span&gt; self;
&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self.navigationController presentModalViewController&lt;span style="color: #002200;"&gt;:&lt;/span&gt;self.child animated&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #a61390;"&gt;YES&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;
…
…&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Implement the delegates&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #002200;"&gt;-&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #a61390;"&gt;void&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; childViewController&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;UIViewController&lt;span style="color: #002200;"&gt;*&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; childController didFinishWithResult &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
  &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self.child dismissModalViewControllerAnimated&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #a61390;"&gt;YES&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
  self.child.delegate &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #a61390;"&gt;nil&lt;/span&gt;;
  self.child &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #a61390;"&gt;nil&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;span id="Method_2"&gt;&lt;h3&gt;Method 2&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;The second method is like the classical email sheet, where the didFinishWithResult delegate sends a pointer to self.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #002200;"&gt;-&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #a61390;"&gt;void&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; childViewController&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;UIViewController&lt;span style="color: #002200;"&gt;*&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; childController didFinishWithResult &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;childController dismissModalViewControllerAnimated&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #a61390;"&gt;YES&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;childController release&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The only advantage of this method is, you don&amp;#8217;t need to retain a pointer to the child in the parent view controller.&lt;br /&gt;
You allocate the child view controller when you show it and release it when the method returns. However, this method isn&amp;#8217;t going to work with ARC. You cannot allocate a pointer in one method and release it in another without the parent specifying a ownership qualifier on that pointer. That means we have only one option, retain a strong reference to the child.&lt;/p&gt;
&lt;span id="Memory_Management_with_ARC"&gt;&lt;h2&gt;Memory Management with ARC&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;Memory management with ARC is going to be exactly similar to method 1 that I showed you earlier, except that instead of a retain, you specify a &lt;strong&gt;strong &lt;/strong&gt;ownership qualifier.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #a61390;"&gt;@interface&lt;/span&gt; MasterViewController
&lt;span style="color: #a61390;"&gt;@property&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;nonatomic, strong&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; ChildViewController &lt;span style="color: #002200;"&gt;*&lt;/span&gt;child;
&lt;span style="color: #a61390;"&gt;@end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The presenting and delegate handling remains the same. It gets tricky when you try to implement method 2 with ARC. The problem is, ARC compiler doesn&amp;#8217;t allow a pointer to linger around. So your child controller gets deallocated after it&amp;#8217;s presented unless you need to &amp;#8220;own&amp;#8221; the pointer explicitly.&lt;/p&gt;
&lt;p&gt;The other easier way is to use blocks. With completion delegates implemented as blocks, this becomes easier. This, I would say, is synonymous to the method 2 which I described before.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;ChildViewController &lt;span style="color: #002200;"&gt;*&lt;/span&gt;child &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;ChildViewController alloc&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt; initWith…&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&amp;nbsp;
  __weak __block ChildViewController &lt;span style="color: #002200;"&gt;*&lt;/span&gt;weakChild &lt;span style="color: #002200;"&gt;=&lt;/span&gt; child; 
&amp;nbsp;
  child.completionHandler &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;^&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #a61390;"&gt;BOOL&lt;/span&gt; result&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
	&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self dismissModalViewControllerAnimated&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #a61390;"&gt;YES&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
	weakChild &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #a61390;"&gt;nil&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;;
&amp;nbsp;
&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self.navigationController presentModalViewController&lt;span style="color: #002200;"&gt;:&lt;/span&gt;child animated&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #a61390;"&gt;YES&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;span id="Back_to_square_one"&gt;&lt;h2&gt;Back to square one&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;In both methods, with or without ARC, we dismiss the child controller on the callback method in the parent. Coming back to our original problem, if you dismiss a child controller by calling&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self dismissModalViewControllerAnimated&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #a61390;"&gt;YES&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The parent has no way to know that the child controller has completed it task and has been dismissed.&lt;br /&gt;
Using viewDidAppear on parent to release a child view controller and use boolean logic is, well, BOOL sh!t.&lt;/p&gt;
&lt;p&gt;ARC manages memory in the following ways depending on your design.&lt;br /&gt;
1. If you captured the child within a completion handler, the memory allocated to the child leaks&lt;br /&gt;
2. If your child controller is a local stack variable and there is no completion handler block, the memory allocated to the child gets released prematurely (as soon as the view is presented and results in a crash)&lt;br /&gt;
3. If your child controller is owned by the parent with a strong reference, it lingers around till the parent view gets deallocated (if you set it to nil in viewDidUnload of the master).&lt;/p&gt;
&lt;p&gt;All these three methods are probably not the right way to do. The only right way is to invoke a completion handler and let the parent dismiss your child safely. This is the reason why I tweeted,&lt;/p&gt;
&lt;blockquote class="twitter-tweet"&gt;&lt;p&gt;Calling [self dismissModalViewControllerAnimated:NO] on child is like committing seppuku. A child shouldn&amp;#8217;t kill itself.&lt;/p&gt;
&lt;p&gt;— Mugunth Kumar () (@mugunthkumar) &lt;a href="https://twitter.com/mugunthkumar/status/173414228961656833" data-datetime="2012-02-25T14:29:08+00:00"&gt;February 25, 2012&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Apple follows this pattern throughout their sample code and within their framework. So, I repeat, don&amp;#8217;t ever dismiss a child view controller within a child.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 1:&lt;/strong&gt; Method 2 works fine with ARC in this case since presentModalViewController bumps up the retain count. (Thanks Hollance and Johan Kool for pointing this out) However, do note that, there are some methods very similar to this, that are likely to be affected. CLLocationManager&amp;#8217;s startUpdatingLocation will not call the delegate if there is no owner for the CLLocationManager object. Same happens to MKReverseGeocoder. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2:&lt;/strong&gt;When you call dismissModalViewController on a child, the UIKit framework automatically takes care of forwarding the message to the parent view controller.&lt;br /&gt;
&amp;#8211;&lt;br /&gt;
Mugunth&lt;/p&gt;
&lt;p&gt;&lt;map name='google_ad_map_1587_8b86e81420c6776e'&gt;
&lt;area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/1587?pos=0' coords='1,2,367,28' /&gt;
&lt;area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/&gt;&lt;/map&gt;
&lt;img usemap='#google_ad_map_1587_8b86e81420c6776e' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;amp;client=&amp;amp;channel=&amp;amp;output=png&amp;amp;cuid=1587&amp;amp;url= http%3A%2F%2Fblog.mugunthkumar.com%2Farticles%2Fownership-of-presented-view-controllers-with-and-without-arc%2F' /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href ="http://twitter.com/mugunthkumar"&gt;Follow me &lt;/a&gt; on Twitter&lt;/p&gt;&lt;p&gt;&amp;copy;2012 &lt;a href="http://blog.mugunthkumar.com"&gt;MKBlog&lt;/a&gt;. All Rights Reserved.&lt;/p&gt;.
&lt;p&gt;No related posts.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dJkEvyomY6e9wu_mnvxmhLTizOw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dJkEvyomY6e9wu_mnvxmhLTizOw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dJkEvyomY6e9wu_mnvxmhLTizOw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dJkEvyomY6e9wu_mnvxmhLTizOw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MugunthKumar/~4/17JS4KWYZXM" height="1" width="1"/&gt;</content><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.mugunthkumar.com/articles/ownership-of-presented-view-controllers-with-and-without-arc/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">8</slash:comments><feedburner:origLink>http://blog.mugunthkumar.com/articles/ownership-of-presented-view-controllers-with-and-without-arc/</feedburner:origLink></entry><entry><title type="text">iOS5 Programming: Pushing the limits book updates</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MugunthKumar/~3/pbRsGWJJwLc/" /><category term="Products" /><category term="book" /><category term="ios5" /><category term="ios5ptl" /><category term="iosptl" /><author><name>Mugunth Kumar</name></author><updated>2012-02-15T20:40:24-08:00</updated><id>http://blog.mugunthkumar.com/?p=1542</id><summary type="html">iOS5 Programming: Pushing the limits Rob and myself created a new website, iosptl.com where we will be posting minor updates to the book and other relevant information that might be of use to iOS developers. iOS is a cutting edge technology. Like everything on the cutting edge, it’s constantly growing and changing. A book captures [...]
Related posts:&lt;ol&gt;
&lt;li&gt;&lt;a href='http://blog.mugunthkumar.com/products/introducing-my-book-ios-5-programming-pushing-the-limits/' rel='bookmark' title='Introducing my book: iOS 5 Programming Pushing the Limits'&gt;Introducing my book: iOS 5 Programming Pushing the Limits&lt;/a&gt; &lt;small&gt;iOS 5 Programming Pushing the Limits Developing Extraordinary Mobile Apps...&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;</summary><content type="html">&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://iosptl.com"&gt;iOS5 Programming: Pushing the limits&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Rob and myself created a new website, &lt;a href="http://iosptl.com"&gt;iosptl.com&lt;/a&gt; where we will be posting minor updates to the book and other relevant information that might be of use to iOS developers.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;iOS is a cutting edge technology. Like everything on the cutting edge, it’s constantly growing and changing. A book captures a moment in time, and &lt;em&gt;iOS:PTL&lt;/em&gt; captured the state of the art during the iOS 5 beta in 2011. Most things about iOS development don’t change from month to month, and we expect most of the book to be accurate long into the future. But some things do change, and this website will capture those updates so that the reader can have the most accurate information today.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Checkout the website and &lt;a href="http://iosptl.com/feed"&gt;subscribe to the feed&lt;/a&gt; or follow us on twitter for up to date information on the book.&lt;br /&gt;
&lt;a href="http://twitter.com/mugunthkumar"&gt;@mugunthkumar&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://twitter.com/cocoaphony"&gt;@cocoaphony&lt;/a&gt;&lt;br /&gt;
&amp;#8211;&lt;br /&gt;
Mugunth&lt;/p&gt;
&lt;p&gt;&lt;map name='google_ad_map_1542_8b86e81420c6776e'&gt;
&lt;area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/1542?pos=0' coords='1,2,367,28' /&gt;
&lt;area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/&gt;&lt;/map&gt;
&lt;img usemap='#google_ad_map_1542_8b86e81420c6776e' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;amp;client=&amp;amp;channel=&amp;amp;output=png&amp;amp;cuid=1542&amp;amp;url= http%3A%2F%2Fblog.mugunthkumar.com%2Fproducts%2Fios5-programming-pushing-the-limits-book-updates%2F' /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href ="http://twitter.com/mugunthkumar"&gt;Follow me &lt;/a&gt; on Twitter&lt;/p&gt;&lt;p&gt;&amp;copy;2012 &lt;a href="http://blog.mugunthkumar.com"&gt;MKBlog&lt;/a&gt;. All Rights Reserved.&lt;/p&gt;.
&lt;p&gt;Related posts:&lt;ol&gt;
&lt;li&gt;&lt;a href='http://blog.mugunthkumar.com/products/introducing-my-book-ios-5-programming-pushing-the-limits/' rel='bookmark' title='Introducing my book: iOS 5 Programming Pushing the Limits'&gt;Introducing my book: iOS 5 Programming Pushing the Limits&lt;/a&gt; &lt;small&gt;iOS 5 Programming Pushing the Limits Developing Extraordinary Mobile Apps...&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/trms99hm1VJCgxHyQwRKHzoHrBQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/trms99hm1VJCgxHyQwRKHzoHrBQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/trms99hm1VJCgxHyQwRKHzoHrBQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/trms99hm1VJCgxHyQwRKHzoHrBQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MugunthKumar/~4/pbRsGWJJwLc" height="1" width="1"/&gt;</content><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.mugunthkumar.com/products/ios5-programming-pushing-the-limits-book-updates/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">7</slash:comments><feedburner:origLink>http://blog.mugunthkumar.com/products/ios5-programming-pushing-the-limits-book-updates/</feedburner:origLink></entry><entry><title type="text">Some thoughts on iOS and your privacy (Address Book)</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MugunthKumar/~3/q-P_VDlXVcM/" /><category term="Articles" /><category term="addressbook" /><category term="ios" /><category term="ios 5" /><category term="path" /><category term="privacy" /><category term="thoughts" /><author><name>Mugunth Kumar</name></author><updated>2012-02-07T23:00:17-08:00</updated><id>http://blog.mugunthkumar.com/?p=1504</id><summary type="html">The recent furore behind the fact that, Path, one of the most beautiful iOS app out there, uploads your entire address book to their servers when you create an account, is probably targeted at the wrong guys. Why do I say this? Read on. Who else is doing it? It&amp;#8217;s not just Path. Hipster is [...]
No related posts.</summary><content type="html">&lt;p&gt;&lt;/p&gt;&lt;p&gt;The recent furore behind the fact that, Path, one of the most beautiful iOS app out there, uploads your entire address book to their servers when you create an account, is probably targeted at the wrong guys. Why do I say this? Read on.&lt;/p&gt;
&lt;span id="Who_else_is_doing_it"&gt;&lt;h3&gt;Who else is doing it?&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;It&amp;#8217;s not just Path. Hipster is doing it. Whatsapp is doing it. Foursquare is doing it. &lt;a href="http://news.ycombinator.com/item?id=3565028"&gt;Instagram is doing it&lt;/a&gt;. Viber is doing it. &amp;#8220;Insert your new hot social networking app here&amp;#8221; is doing it. This tweet summarizes this.&lt;/p&gt;
&lt;blockquote class="twitter-tweet tw-align-center"&gt;&lt;p&gt;for those who just realized that Path uploads your entire address book:you&amp;#8217;re such a cute innocent person.Guess what they do with ur fb&lt;/p&gt;
&lt;p&gt;— Amudi Sebastian (@amudi) &lt;a href="https://twitter.com/amudi/status/167072379867107328" data-datetime="2012-02-08T02:28:54+00:00"&gt;February 8, 2012&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Some companies explicitly ask for users&amp;#8217; permission (Whatsapp and Viber)&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
&lt;div class="wp-caption aligncenter" style="width: 154px"&gt;&lt;img style="border-style: initial; border-color: initial; border-width: 0px;" title="Whatsapp asking for user's permission to upload address book" src="http://blog.mugunthkumar.com/wp-content/uploads/Pastebot-2012-02-08-14.38.38-PM-4.png" alt="Whatsapp asking for user's permission to upload address book" width="144" height="216" border="0" /&gt;&lt;p class="wp-caption-text"&gt;Whatsapp asking for user&amp;#39;s permission to upload address book&lt;/p&gt;&lt;/div&gt;
&lt;div class="wp-caption aligncenter" style="width: 154px"&gt;&lt;img style="border-style: initial; border-color: initial; border-width: 0px;" title="Viber asking for user's permission to upload address book" src="http://blog.mugunthkumar.com/wp-content/uploads/Pastebot-2012-02-08-14.38.38-PM-2.png" alt="Viber asking for user's permission to upload address book" width="144" height="216" border="0" /&gt;&lt;p class="wp-caption-text"&gt;Viber asking for user&amp;#39;s permission to upload address book&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Some companies do it when the user explicitly ask them to do. For example, foursquare and Instagram both have an option called &amp;#8220;Find friends from Contacts&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Instagram uploads when you ask it to find your friends from Contacts.&lt;/p&gt;
&lt;div class="wp-caption aligncenter" style="width: 154px"&gt;&lt;img style="border-style: initial; border-color: initial; border-width: 0px;" title="Instagram uploads your contacts when you tap on &amp;quot;From my contact list&amp;quot;" src="http://blog.mugunthkumar.com/wp-content/uploads/Pastebot-2012-02-08-14.45.57-PM-1.png" alt="Instagram uploads your contacts when you tap on &amp;quot;From my contact list&amp;quot;" width="144" height="216" border="0" /&gt;&lt;p class="wp-caption-text"&gt;Instagram uploads your contacts when you tap on &amp;quot;From my contact list&amp;quot;&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Foursquare uploads &amp;#8220;proactively&amp;#8221; when you open the &amp;#8220;Invite Friends&amp;#8221; view. This is again as bad as Path.&lt;/p&gt;
&lt;div class="wp-caption aligncenter" style="width: 154px"&gt;&lt;img style="border-style: initial; border-color: initial; border-width: 0px;" title="Foursquare uploads in the background when you open this view" src="http://blog.mugunthkumar.com/wp-content/uploads/Pastebot-2012-02-08-14.45.57-PM-2.png" alt="Foursquare uploads in the background when you open this view" width="144" height="216" border="0" /&gt;&lt;p class="wp-caption-text"&gt;Foursquare uploads in the background when you open this view&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;To a techie like you and me, we know that this option would upload the entire address book. To any other iOS user, it&amp;#8217;s not really clear. May be they should have added an additional prompt like Whatsapp. But then, that would _alert_ the user and he will probably opt out.&lt;/p&gt;
&lt;p&gt;Some companies bury it deep inside their privacy policy (that no one reads). While there are many bad examples, Viber really stands out as a good example. Their privacy policy explicitly states what all they do with the contacts they read from your device.&lt;/p&gt;
&lt;p&gt;But most company&amp;#8217;s privacy policy is written in legal lingo, mostly incomprehensible to the common man.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I&amp;#8217;m not arguing that two wrongs make a right&lt;/strong&gt;. The point I want to put forth is that, this is not a problem with the third party app maker. It&amp;#8217;s a platform issue. When a Android app steals your private information, why do you blame Google instead of the third party app developer? If Google allowed API access to your sensitive information using a opt-in dialog like iOS rather than a manifest file, would there be so many trojans on Android marketplace?&lt;/p&gt;
&lt;p&gt;The whole problem in this recent furore roots down to the security layer of iOS. iOS allows any programmer to access all of your address book with just two lines of code.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;ABAddressBookRef addressBookRef &lt;span style="color: #002200;"&gt;=&lt;/span&gt; ABAddressBookCreate&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt;;
CFArrayRef allContacts &lt;span style="color: #002200;"&gt;=&lt;/span&gt; ABAddressBookCopyArrayOfAllPeople&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;addressBookRef&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt;;
&lt;span style="color: #11740a; font-style: italic;"&gt;// upload this to server and do something really nasty&lt;/span&gt;
CFRelease&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;addressBookRef&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt;;
CFRelease&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;allContacts&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There is no prompt whatsoever shown by the system.&lt;/p&gt;
&lt;span id="What_should_Apple_do"&gt;&lt;h3&gt;What should Apple do?&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;Show an access control dialog when an application makes a request to access address book. Probably from the version first iteration of iOS, you get a prompt when any app (including Apple&amp;#8217;s own apps) requests for your location or for your unique device token for sending you notifications. Apple should extend this feature to programatic access of your contacts and calendar as well (EventKit.framework).&lt;/p&gt;
&lt;p&gt;Personally, I&amp;#8217;m least bothered about apps stealing my contacts. I&amp;#8217;ll be more bothered if an app steals my events. Let me give you an example.&lt;/p&gt;
&lt;p&gt;Imagine that I have a meeting with a client ABC from 10 AM to 11 AM on Feb 10th at their office, One Marina Boulevard, Singapore. Just imagine what all can be done when a company knows this information. They can stalk me. They can rob my home when I&amp;#8217;m not there. They can sell this information to a &amp;#8220;order a pizza&amp;#8221; guy who could cold-call me during lunch time to up-sell his pizza. Well, most of these don&amp;#8217;t really happen. But they _can_ technically happen.&lt;/p&gt;
&lt;p&gt;Reading your calendar to know your upcoming events is also few lines of code&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;EKEventStore &lt;span style="color: #002200;"&gt;*&lt;/span&gt;store &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;EKEventStore alloc&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt; init&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&lt;span style="color: #400080;"&gt;NSPredicate&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;eventPredicate &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;store predicateForEventsWithStartDate&lt;span style="color: #002200;"&gt;:&lt;/span&gt;startDate endDate&lt;span style="color: #002200;"&gt;:&lt;/span&gt;endDate calendars&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #a61390;"&gt;nil&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&lt;span style="color: #400080;"&gt;NSArray&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;matchingEvents &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;store eventsMatchingPredicate&lt;span style="color: #002200;"&gt;:&lt;/span&gt;eventPredicate&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&lt;span style="color: #11740a; font-style: italic;"&gt;// upload this to server and do something really nasty&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;span id="How_can_you_help"&gt;&lt;h3&gt;How can you help?&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;If you are a iOS developer, open bugreport.apple.com and file a bug report like this radar &lt;a href="http://openradar.appspot.com/10824178"&gt;10824178&lt;/a&gt;. Duplicate this. The more a bug gets duplicated, the more faster it reaches Apple.&lt;/p&gt;
&lt;p&gt;If you are an iDevice user, remember that there is no free lunch. When a company makes a product free, &lt;strong&gt;YOU&lt;/strong&gt; are their product. Be cautious when a app requests for any additional information like your location or push notifications. There are plenty of apps that I know, that use push notifications purely for marketing. Marketing emails in Web 2.0 era is slowly being transformed to push notifications in this mobile dominated decade. Sad part is that, there is no way to unsubscribe from those annoying push notifications apart from deleting the app.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s all hope that Apple addresses this issue at the earliest before something really _bad_ happens.&lt;/p&gt;
&lt;p&gt;&amp;#8211;&lt;br /&gt;
Mugunth&lt;/p&gt;
&lt;p&gt;&lt;map name='google_ad_map_1504_8b86e81420c6776e'&gt;
&lt;area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/1504?pos=0' coords='1,2,367,28' /&gt;
&lt;area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/&gt;&lt;/map&gt;
&lt;img usemap='#google_ad_map_1504_8b86e81420c6776e' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;amp;client=&amp;amp;channel=&amp;amp;output=png&amp;amp;cuid=1504&amp;amp;url= http%3A%2F%2Fblog.mugunthkumar.com%2Farticles%2Fsome-thoughts-on-ios-and-your-privacy-address-book%2F' /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href ="http://twitter.com/mugunthkumar"&gt;Follow me &lt;/a&gt; on Twitter&lt;/p&gt;&lt;p&gt;&amp;copy;2012 &lt;a href="http://blog.mugunthkumar.com"&gt;MKBlog&lt;/a&gt;. All Rights Reserved.&lt;/p&gt;.
&lt;p&gt;No related posts.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wdiIH9x88rvvMXtlq5ZQ4SFOtRw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wdiIH9x88rvvMXtlq5ZQ4SFOtRw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wdiIH9x88rvvMXtlq5ZQ4SFOtRw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wdiIH9x88rvvMXtlq5ZQ4SFOtRw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MugunthKumar/~4/q-P_VDlXVcM" height="1" width="1"/&gt;</content><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.mugunthkumar.com/articles/some-thoughts-on-ios-and-your-privacy-address-book/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">5</slash:comments><feedburner:origLink>http://blog.mugunthkumar.com/articles/some-thoughts-on-ios-and-your-privacy-address-book/</feedburner:origLink></entry><entry><title type="text">iOS Tutorial: Image Cache and Loading Thumbnails using MKNetworkKit</title><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MugunthKumar/~3/qZ24l_17NS8/" /><category term="Coding" /><category term="arc" /><category term="cache" /><category term="flickr" /><category term="image" /><category term="ios 5" /><category term="mknetworkkit" /><author><name>Mugunth Kumar</name></author><updated>2012-01-21T20:30:29-08:00</updated><id>http://blog.mugunthkumar.com/?p=1485</id><summary type="html">If you have been following me on Twitter or reading MKBlog, you would already be knowing about MKNetworkKit. I wrote a introductory post on MKNetworkKit couple of months ago and later explained in a more detailed post on how to use it in other sophisticated scenarios. From feedback so far, Image Caching was one aspect [...]
Related posts:&lt;ol&gt;
&lt;li&gt;&lt;a href='http://blog.mugunthkumar.com/coding/ios-tutorial-advanced-networking-with-mknetworkkit/' rel='bookmark' title='iOS Tutorial: Advanced Networking with MKNetworkKit'&gt;iOS Tutorial: Advanced Networking with MKNetworkKit&lt;/a&gt; &lt;small&gt;Couple of weeks ago, I wrote a clean, fast networking...&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;</summary><content type="html">&lt;p&gt;&lt;/p&gt;&lt;p&gt;If you have been &lt;a href="http://twitter.com/mugunthkumar"&gt;following me on Twitter&lt;/a&gt; or reading MKBlog, you would already be knowing about MKNetworkKit.&lt;/p&gt;
&lt;p&gt;I wrote a &lt;a href="http://blog.mugunthkumar.com/products/ios-framework-introducing-mknetworkkit/"&gt;introductory post on MKNetworkKit&lt;/a&gt; couple of months ago and later explained in a &lt;a href="http://blog.mugunthkumar.com/coding/ios-tutorial-advanced-networking-with-mknetworkkit/"&gt;more detailed post&lt;/a&gt; on how to use it in other sophisticated scenarios.&lt;/p&gt;
&lt;div class='toc toc'&gt;
&lt;h2&gt;Contents&lt;/h2&gt;
&lt;ul class='toc-odd level-1'&gt;
		&lt;ul class='toc-even level-2'&gt;
			&lt;li&gt;
				&lt;a href="#Step_1:_Create_a_Flickr_Engine"&gt;Step 1: Create a Flickr Engine&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#Step_2:_Create_a_custom_cache_directory_for_storing_the_cached_Flickr_thumbanils"&gt;Step 2: Create a custom cache directory for storing the cached Flickr thumbanils&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#Step_3:_Write_a_method_to_list_flickr_images_for_a_specified_tag"&gt;Step 3: Write a method to list flickr images for a specified tag&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#Step_4:_Create_a_custom_table_view_cell_for_loading_flickr_images"&gt;Step 4: Create a custom table view cell for loading flickr images&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#Step_5:_Clear_previously_loaded_images_if_the_cell_will_be_reused"&gt;Step 5: Clear previously loaded images if the cell will be reused&lt;/a&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;a href="#Step_6:_Fade_in_thumbnails_like_the_Apple_trailers_app"&gt;Step 6: Fade in thumbnails like the Apple trailers app&lt;/a&gt;
			&lt;/li&gt;
		&lt;/ul&gt;
	&lt;li&gt;
		&lt;a href="#Source_Code"&gt;Source Code&lt;/a&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class='toc-end'&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;From feedback so far, Image Caching was one aspect of MKNetworkKit that developers didn&amp;#8217;t understand pretty well. In this post, I&amp;#8217;ll try to explain how to use MKNetworkKit for image caching and loading thumbnails.&lt;br /&gt;
Thumbnails are often used in iOS apps to load friend&amp;#8217;s avatar pictures from a Facebook feed or flickr thumbnails for a given tag and in many similar cases.&lt;/p&gt;
&lt;p&gt;MKNetworkEngine makes it a breeze to add this feature into your app. What not? With MKNetworkKit, you will even know if the response image is from cache or loaded for the first time. Using this information, you can &amp;#8220;fade in&amp;#8221; your thumbnails when you load the images for the first time (like in Apple&amp;#8217;s &lt;a href="http://itunes.apple.com/us/app/itunes-movie-trailers/id471966214?mt=8"&gt;iTunes Movie Trailers&lt;/a&gt; app).&lt;/p&gt;
&lt;p&gt;The completed example looks like this.&lt;/p&gt;
&lt;div class="wp-caption aligncenter" style="width: 331px"&gt;&lt;img style="border-style: initial; border-color: initial; border-width: 0px;" title="iOS Simulator.png" src="http://blog.mugunthkumar.com/wp-content/uploads/iOS-Simulator.png" alt="IOS Simulator" width="321" height="600" border="0" /&gt;&lt;p class="wp-caption-text"&gt;Screenshot showing images loaded asynchronously using MKNetworkKit&lt;/p&gt;&lt;/div&gt;
&lt;p style="text-align: left;"&gt;Having said that, lets get our hands dirty with some real code. In this example, I&amp;#8217;ll show you how to load images from Flickr on a table view controller asynchronously.&lt;/p&gt;
&lt;span id="Step_1:_Create_a_Flickr_Engine"&gt;&lt;h3&gt;Step 1: Create a Flickr Engine&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;Easy peasy. Create a subclass of MKNetworkEngine and let&amp;#8217;s name it as &amp;#8220;FlickrEngine&amp;#8221;. Initialize your flickr engine with api.flickr.com as hostname in your application delegate.&lt;/p&gt;
&lt;span id="Step_2:_Create_a_custom_cache_directory_for_storing_the_cached_Flickr_thumbanils"&gt;&lt;h3&gt;Step 2: Create a custom cache directory for storing the cached Flickr thumbanils&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;Override cacheDirectoryName and return a custom directory for storing the cached thumbnails.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #002200;"&gt;-&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #400080;"&gt;NSString&lt;/span&gt;&lt;span style="color: #002200;"&gt;*&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; cacheDirectoryName &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span style="color: #400080;"&gt;NSArray&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;paths &lt;span style="color: #002200;"&gt;=&lt;/span&gt; NSSearchPathForDirectoriesInDomains&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;NSCachesDirectory, NSUserDomainMask, &lt;span style="color: #a61390;"&gt;YES&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style="color: #400080;"&gt;NSString&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;documentsDirectory &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;paths objectAtIndex&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #2400d9;"&gt;0&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
    &lt;span style="color: #400080;"&gt;NSString&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;cacheDirectoryName &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;documentsDirectory stringByAppendingPathComponent&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;FlickrImages&amp;quot;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
    &lt;span style="color: #a61390;"&gt;return&lt;/span&gt; cacheDirectoryName;
&lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This step is optional. But, since thumbnails can easily occupy precious disk space, you might want to clear them at periodic intervals. MKNetworkEngine provides a handy method (emptyCache) to empty the cache directory for a specific engine. The default implementation of this method removes all files within the cache directory of that engine. If you don&amp;#8217;t override cacheDirectoryName and provide a distinct cache directory for your engine, you will end up emptying the shared cache directory, when you call emptyCache.&lt;/p&gt;
&lt;span id="Step_3:_Write_a_method_to_list_flickr_images_for_a_specified_tag"&gt;&lt;h3&gt;Step 3: Write a method to list flickr images for a specified tag&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;By now, you already know that creating a network request using MKNetworkKit is a no-brainer. The following shows how to create a request for loading images for a given tag.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #002200;"&gt;-&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #a61390;"&gt;void&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; imagesForTag&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #400080;"&gt;NSString&lt;/span&gt;&lt;span style="color: #002200;"&gt;*&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; tag onCompletion&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;FlickrImagesResponseBlock&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; imageURLBlock onError&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;MKNKErrorBlock&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; errorBlock &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    MKNetworkOperation &lt;span style="color: #002200;"&gt;*&lt;/span&gt;op &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self operationWithPath&lt;span style="color: #002200;"&gt;:&lt;/span&gt;FLICKR_IMAGE_URL&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;tag urlEncodedString&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&amp;nbsp;
    &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;op onCompletion&lt;span style="color: #002200;"&gt;:^&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;MKNetworkOperation &lt;span style="color: #002200;"&gt;*&lt;/span&gt;completedOperation&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
        &lt;span style="color: #400080;"&gt;NSDictionary&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;response &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;completedOperation responseJSON&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
        imageURLBlock&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;response objectForKey&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;photos&amp;quot;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt; objectForKey&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;photo&amp;quot;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
    &lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt; onError&lt;span style="color: #002200;"&gt;:^&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #400080;"&gt;NSError&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;error&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
        errorBlock&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;error&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt;;
    &lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&amp;nbsp;
    &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self enqueueOperation&lt;span style="color: #002200;"&gt;:&lt;/span&gt;op&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The FLICKR_IMAGE_URL macro is defined as&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #6e371a;"&gt;#define FLICKR_IMAGE_URL(__TAG__) [NSString stringWithFormat:@&amp;quot;services/rest/?method=flickr.photos.search&amp;amp;amp;api_key=%@&amp;amp;amp;tags=%@&amp;amp;amp;per_page=200&amp;amp;amp;format=json&amp;amp;amp;nojsoncallback=1&amp;quot;, FLICKR_KEY, __TAG__]&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that, the host name api.flickr.com gets prefixed automatically when you create operations on this engine.&lt;/p&gt;
&lt;p&gt;You should generate a new flickr api key and replace it in the FLICKR_KEY macro. You can create one for free &lt;a href="http://www.flickr.com/services/apps/create/apply"&gt;here.&lt;/a&gt; (For running the example, you can use my key)&lt;/p&gt;
&lt;span id="Step_4:_Create_a_custom_table_view_cell_for_loading_flickr_images"&gt;&lt;h3&gt;Step 4: Create a custom table view cell for loading flickr images&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;In this custom cell, write a method setFlickrData: that updates the cell from the dictionary you receive by invoking the flickr REST API&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #002200;"&gt;-&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #a61390;"&gt;void&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; setFlickrData&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #400080;"&gt;NSDictionary&lt;/span&gt;&lt;span style="color: #002200;"&gt;*&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; thisFlickrImage &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    self.titleLabel.text &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;thisFlickrImage objectForKey&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
	self.authorNameLabel.text &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;thisFlickrImage objectForKey&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;owner&amp;quot;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
    self.loadingImageURLString &lt;span style="color: #002200;"&gt;=&lt;/span&gt;
    &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #400080;"&gt;NSString&lt;/span&gt; stringWithFormat&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;http://farm%@.static.flickr.com/%@/%@_%@_s.jpg&amp;quot;&lt;/span&gt;,
     &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;thisFlickrImage objectForKey&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;farm&amp;quot;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;, &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;thisFlickrImage objectForKey&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;,
     &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;thisFlickrImage objectForKey&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;, &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;thisFlickrImage objectForKey&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;@&lt;/span&gt;&lt;span style="color: #bf1d1a;"&gt;&amp;quot;secret&amp;quot;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&amp;nbsp;
    self.imageLoadingOperation &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;ApplicationDelegate.flickrEngine imageAtURL&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #400080;"&gt;NSURL&lt;/span&gt; URLWithString&lt;span style="color: #002200;"&gt;:&lt;/span&gt;self.loadingImageURLString&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;
                                    onCompletion&lt;span style="color: #002200;"&gt;:^&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;UIImage &lt;span style="color: #002200;"&gt;*&lt;/span&gt;fetchedImage, &lt;span style="color: #400080;"&gt;NSURL&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;url, &lt;span style="color: #a61390;"&gt;BOOL&lt;/span&gt; isInCache&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
                                        &lt;span style="color: #a61390;"&gt;if&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self.loadingImageURLString isEqualToString&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;url absoluteString&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
                                                self.thumbnailImage.image &lt;span style="color: #002200;"&gt;=&lt;/span&gt; fetchedImage;
                                    &lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;&lt;p&gt;Tip: Avoid setting the individual labels of a table view cell in the cellForRowAtIndexPath: method. It makes the cell less portable across your other view controllers.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Carefully note the use of the variable self.loadingImageURLString. If you don&amp;#8217;t save the loading image&amp;#8217;s URL in an ivar, your images will continue to be updated when the previous operation completes. To circumvent this, either cancel the operation when a cell is reused, or check if the returned URL is the original URL that was loaded for this cell (by storing it in ivar).&lt;/p&gt;
&lt;p&gt;As on &lt;a href="https://github.com/MugunthKumar/MKNetworkKit/commit/b9ba2d6501b498e837abf49cb999dbbd67b30a4f"&gt;this commit&lt;/a&gt;, MKNetworkEngine&amp;#8217;s imageAtURL method will return you the actual operation created. You should retain this and cancel it when not necessary.&lt;/p&gt;
&lt;span id="Step_5:_Clear_previously_loaded_images_if_the_cell_will_be_reused"&gt;&lt;h3&gt;Step 5: Clear previously loaded images if the cell will be reused&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;You should clear previously loaded images by overriding prepareForReuse method. It&amp;#8217;s a one-liner.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #002200;"&gt;-&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #a61390;"&gt;void&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; prepareForReuse &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    self.thumbnailImage.image &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #a61390;"&gt;nil&lt;/span&gt;;
    &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self.imageLoadingOperation cancel&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you don&amp;#8217;t write this, you will see old images on the cell while the new image is being loaded.&lt;br /&gt;
Instead of &amp;#8220;nil&amp;#8221; you can also show a default placeholder image here.&lt;/p&gt;
&lt;p&gt;You should also consider canceling the old imageLoadingOperation so as to load the latest visible cells faster. If you don&amp;#8217;t cancel the operation, when the user scrolls fast to the bottom of the list, the engine loads all the images from the first cell (including images for cells that are now hidden and reused) and there by slowing down the image load operation for the currently visible cell. You can test this from the code by commenting it out and checking the performance.&lt;/p&gt;
&lt;span id="Step_6:_Fade_in_thumbnails_like_the_Apple_trailers_app"&gt;&lt;h3&gt;Step 6: Fade in thumbnails like the Apple trailers app&lt;/h3&gt;&lt;/span&gt;
&lt;p&gt;MKNetworkEngine&amp;#8217;s imageAtURL method returns the image in a block method. The block method, onCompletion looks like this.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #002200;"&gt;^&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;UIImage &lt;span style="color: #002200;"&gt;*&lt;/span&gt;fetchedImage, &lt;span style="color: #400080;"&gt;NSURL&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;url, &lt;span style="color: #a61390;"&gt;BOOL&lt;/span&gt; isInCache&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
                                        &lt;span style="color: #a61390;"&gt;if&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self.loadingImageURLString isEqualToString&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;url absoluteString&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
                                                self.thumbnailImage.image &lt;span style="color: #002200;"&gt;=&lt;/span&gt; fetchedImage;
                                    &lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If the variable isInCache is false, you can &amp;#8220;fade in&amp;#8221; the image so as to add a nice UI touch to your app. The following code block illustrates this.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="objc" style="font-family:monospace;"&gt;&lt;span style="color: #002200;"&gt;^&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;UIImage &lt;span style="color: #002200;"&gt;*&lt;/span&gt;fetchedImage, &lt;span style="color: #400080;"&gt;NSURL&lt;/span&gt; &lt;span style="color: #002200;"&gt;*&lt;/span&gt;url, &lt;span style="color: #a61390;"&gt;BOOL&lt;/span&gt; isInCache&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
                                        &lt;span style="color: #a61390;"&gt;if&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self.loadingImageURLString isEqualToString&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;url absoluteString&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
                                            &lt;span style="color: #a61390;"&gt;if&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;isInCache&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
                                                self.thumbnailImage.image &lt;span style="color: #002200;"&gt;=&lt;/span&gt; fetchedImage;
                                            &lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt; &lt;span style="color: #a61390;"&gt;else&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
                                                UIImageView &lt;span style="color: #002200;"&gt;*&lt;/span&gt;loadedImageView &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;UIImageView alloc&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt; initWithImage&lt;span style="color: #002200;"&gt;:&lt;/span&gt;fetchedImage&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
                                                loadedImageView.frame &lt;span style="color: #002200;"&gt;=&lt;/span&gt; self.thumbnailImage.frame;
                                                loadedImageView.alpha &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #2400d9;"&gt;0&lt;/span&gt;;
                                                &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;self.contentView addSubview&lt;span style="color: #002200;"&gt;:&lt;/span&gt;loadedImageView&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
&amp;nbsp;
                                                &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;UIView animateWithDuration&lt;span style="color: #002200;"&gt;:&lt;/span&gt;&lt;span style="color: #2400d9;"&gt;0.4&lt;/span&gt;
                                                                 animations&lt;span style="color: #002200;"&gt;:^&lt;/span&gt;
                                                 &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
                                                     loadedImageView.alpha &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #2400d9;"&gt;1&lt;/span&gt;;
                                                     self.thumbnailImage.alpha &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #2400d9;"&gt;0&lt;/span&gt;;
                                                 &lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;
                                                                 completion&lt;span style="color: #002200;"&gt;:^&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #a61390;"&gt;BOOL&lt;/span&gt; finished&lt;span style="color: #002200;"&gt;&amp;#41;&lt;/span&gt;
                                                 &lt;span style="color: #002200;"&gt;&amp;#123;&lt;/span&gt;
                                                     self.thumbnailImage.image &lt;span style="color: #002200;"&gt;=&lt;/span&gt; fetchedImage;
                                                     self.thumbnailImage.alpha &lt;span style="color: #002200;"&gt;=&lt;/span&gt; &lt;span style="color: #2400d9;"&gt;1&lt;/span&gt;;
                                                     &lt;span style="color: #002200;"&gt;&amp;#91;&lt;/span&gt;loadedImageView removeFromSuperview&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
                                                 &lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #002200;"&gt;&amp;#93;&lt;/span&gt;;
                                            &lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;
                                        &lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;
                                    &lt;span style="color: #002200;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;span id="Source_Code"&gt;&lt;h2&gt;Source Code&lt;/h2&gt;&lt;/span&gt;
&lt;p&gt;The complete source code is available as a demo on &lt;a href="https://github.com/MugunthKumar/MKNetworkKit"&gt;MKNetworkKit&amp;#8217;s Github repository&lt;/a&gt;.&lt;br /&gt;
&amp;#8211;&lt;br /&gt;
Mugunth&lt;/p&gt;
&lt;p&gt;&lt;map name='google_ad_map_1485_8b86e81420c6776e'&gt;
&lt;area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/1485?pos=0' coords='1,2,367,28' /&gt;
&lt;area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/&gt;&lt;/map&gt;
&lt;img usemap='#google_ad_map_1485_8b86e81420c6776e' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;amp;client=&amp;amp;channel=&amp;amp;output=png&amp;amp;cuid=1485&amp;amp;url= http%3A%2F%2Fblog.mugunthkumar.com%2Fcoding%2Fios-tutorial-image-cache-and-loading-thumbnails-using-mknetworkkit%2F' /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href ="http://twitter.com/mugunthkumar"&gt;Follow me &lt;/a&gt; on Twitter&lt;/p&gt;&lt;p&gt;&amp;copy;2012 &lt;a href="http://blog.mugunthkumar.com"&gt;MKBlog&lt;/a&gt;. All Rights Reserved.&lt;/p&gt;.
&lt;p&gt;Related posts:&lt;ol&gt;
&lt;li&gt;&lt;a href='http://blog.mugunthkumar.com/coding/ios-tutorial-advanced-networking-with-mknetworkkit/' rel='bookmark' title='iOS Tutorial: Advanced Networking with MKNetworkKit'&gt;iOS Tutorial: Advanced Networking with MKNetworkKit&lt;/a&gt; &lt;small&gt;Couple of weeks ago, I wrote a clean, fast networking...&lt;/small&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/KHrVZO6lxMutyZJ7Sx0cFk_pjR0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KHrVZO6lxMutyZJ7Sx0cFk_pjR0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/KHrVZO6lxMutyZJ7Sx0cFk_pjR0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KHrVZO6lxMutyZJ7Sx0cFk_pjR0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MugunthKumar/~4/qZ24l_17NS8" height="1" width="1"/&gt;</content><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blog.mugunthkumar.com/coding/ios-tutorial-image-cache-and-loading-thumbnails-using-mknetworkkit/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">18</slash:comments><feedburner:origLink>http://blog.mugunthkumar.com/coding/ios-tutorial-image-cache-and-loading-thumbnails-using-mknetworkkit/</feedburner:origLink></entry></feed>

