<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Hollance</title>
	
	<link>http://www.hollance.com</link>
	<description>Professional Freelance Software Development for iPhone and iPad</description>
	<lastBuildDate>Mon, 26 Mar 2012 01:28:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/hollance" /><feedburner:info uri="hollance" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>How to make apps if you’re not a good programmer</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/7-KMs6k_DXQ/</link>
		<comments>http://www.hollance.com/2012/02/how-to-make-apps-if-youre-not-a-good-programmer/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 08:38:19 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Business]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[Marketing]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=984</guid>
		<description><![CDATA[The other day I received an email with the following question: &#8220;I have this great idea for a game, but I&#8217;m new to iOS development and this goes way over my head. So I&#8217;m wondering if you could help with the development or know anyone else who can? Of course, we&#8217;ll split the profits.&#8221; Since [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I received an email with the following question:</p>
<blockquote><p>&#8220;I have this great idea for a game, but I&#8217;m new to iOS development and this goes way over my head. So I&#8217;m wondering if you could help with the development or know anyone else who can? Of course, we&#8217;ll split the profits.&#8221;</p></blockquote>
<p>Since this isn&#8217;t the first time I&#8217;ve received such a request, I thought I&#8217;d put up my answer here.</p>
<p>It&#8217;s not easy getting started, that&#8217;s for sure. It can take a long time to go from noob to someone who can make quality apps. Also, not everyone is cut out to be a programmer.</p>
<p>Having a great idea is only the beginning, but the money is in the execution. If you don&#8217;t know how to execute, then you might need to take another approach to get the app made.</p>
<p>Even if you can pull off the programming part, that is not enough to make your app a success. You also need to get it to the right people, in the right place, at the right time. That also takes certain skills.</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2012/02/comic-idea.png"><img class="aligncenter size-full wp-image-1009" title="comic-idea" src="http://www.hollance.com/wp-content/uploads/2012/02/comic-idea.png" alt="" width="495" height="295" /></a></p>
<h3>Sell your idea to find your team</h3>
<p>Here&#8217;s what I would do: To find someone to work on this with you (for a part of the profits rather than work-for-hire), you&#8217;ll have to convince them of the potential of your idea. The best way to do that is to make a short demo video. Appsterdam&#8217;s Mike Lee wrote a <a href="http://mur.mu.rs/?p=327">good blog post</a> about that.</p>
<p>With that video you can set up a project on <a href="http://www.kickstarter.com">Kickstarter</a> or a similar site, that allows you to raise money from small-time investors and at the same time attract attention from developers and even potential customers. With that money you can hire a professional programmer, designer, and anyone else you need.</p>
<p>Let&#8217;s say you raise only $5,000. That by itself won&#8217;t be enough to pay for the development of the app, but it will serve as a decent down payment for the people you will hire. With some up-front cash and a convincing demo video, professional developers might be more willing to work for profit sharing.</p>
<p>In other words, if you don&#8217;t have the programming or design chops to make the app by yourself, you will have to play the role of a producer (like a movie producer) instead of a programmer, and gather a team of people who are willing to work with you.</p>
<p>Most of these people &#8212; if they are any good &#8212; aren&#8217;t interested in working for profit if you&#8217;re not also bringing something to the table. Asking someone to work on your project for a share of the (hypothetical) profits is asking them to invest their time and talent into your idea &#8212; and by extension, your leadership &#8212; at their expense, based on nothing but a promise of a fat payday. You&#8217;d better be ready to deliver on that promise!</p>
<h3>But what if someone steals my idea?</h3>
<p>You&#8217;re putting your great idea out there for the world to see in order to attract investors and talent, so what&#8217;s to stop others from simply copying it?</p>
<p>Here&#8217;s the thing: it is incredibly hard to make a hit game or app. If your idea is something anyone can build in a handful of days that is guaranteed to sell itself without any effort, then keep it to yourself. These are one in a million ideas and chances are yours isn&#8217;t one of them.</p>
<p>Your idea will take many months of dedicated effort to turn into something real and many more to find its way to customers. No one will steal it because no one else will care about it as much as you do or is willing to put in that kind of effort.</p>
<p>It&#8217;s not the idea that is worth money, it&#8217;s the execution of the idea. Most of the hit games on the App Store are not 100% original ideas &#8212; for example, Angry Birds and Tiny Wings are both based on other games &#8212; just very well executed versions of those existing ideas.</p>
<h3>The idea isn&#8217;t really yours to keep</h3>
<p>Now personally, I believe that you have to let go of the notion that you can &#8220;own&#8221; an idea. An idea by itself is nothing. That&#8217;s why you can&#8217;t really &#8220;steal&#8221; ideas. On the other hard, you can certainly own the execution of the idea, and that is protected by copyright laws and by the fact that&#8217;s it&#8217;s just a lot of hard work.</p>
<p>The only way you will ever profit from your idea, is to make sure you are the one with the best version of that idea.</p>
<p>If your idea is truly good but you put out a very basic, average implementation of the game that you programmed and designed yourself, chances are that hardly anyone will care about it. But it might inspire some other developer and a few months later some other team makes a lot of money from your idea but done better. You will have blown your opportunity.</p>
<p>So if you want to be the one with the hit app, you need to be the one making the most amazing version of it. And that requires programming help if you&#8217;re not a very good programmer, design help if you&#8217;re not a good designer, and marketing help if you&#8217;re not a very good business person.</p>
<p>So start working on that video!</p>
<p><em>Illustration by Oscar S.R. / miutopia (from openclipart.org)</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2012/02/how-to-make-apps-if-youre-not-a-good-programmer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2012/02/how-to-make-apps-if-youre-not-a-good-programmer/</feedburner:origLink></item>
		<item>
		<title>Don’t Abuse the App Delegate</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/7QOFSrhiR2E/</link>
		<comments>http://www.hollance.com/2012/02/dont-abuse-the-app-delegate/#comments</comments>
		<pubDate>Sat, 18 Feb 2012 10:36:34 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=948</guid>
		<description><![CDATA[Many of my tutorials (and real apps) have code in AppDelegate.m that looks like this: - &#40;BOOL&#41;application:&#40;UIApplication *&#41;application didFinishLaunchingWithOptions:&#40;NSDictionary *&#41;launchOptions &#123; DataModel *dataModel = &#91;&#91;DataModel alloc&#93; init&#93;; self.rootViewController.dataModel = dataModel; . . . &#125; The app delegate creates the data model object and passes it to the root view controller. The class may be called [...]]]></description>
			<content:encoded><![CDATA[<p>Many of my <a href="http://e2f8cftfu-v2qzepkpolpohp65.hop.clickbank.net/">tutorials</a> (and real apps) have code in AppDelegate.m that looks like this:</p>

<div class="wp_codebox"><table><tr id="p9486"><td class="code" id="p948code6"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>application<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIApplication <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>application
    didFinishLaunchingWithOptions<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/"><span style="color: #400080;">NSDictionary</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>launchOptions
<span style="color: #002200;">&#123;</span>
    DataModel <span style="color: #002200;">*</span>dataModel <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DataModel alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
    self.rootViewController.dataModel <span style="color: #002200;">=</span> dataModel;
    . . .
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>The app delegate creates the data model object and passes it to the root view controller.</p>
<p>The class may be called something different than DataModel, but that&#8217;s essentially what it is, the data model for the app. In a Core Data app, this could be an instance of NSManagedObjectContext.</p>
<p>At some point, the root view controller opens another screen, and it passes along the DataModel object to this new view controller:</p>

<div class="wp_codebox"><table><tr id="p9487"><td class="code" id="p948code7"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView
    didSelectRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
    SecondViewController <span style="color: #002200;">*</span>controller <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>SecondViewController alloc<span style="color: #002200;">&#93;</span>
        initWithNibNamed<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;SecondViewController&quot;</span> bundle<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
    . . .
    controller.dataModel <span style="color: #002200;">=</span> self.dataModel;
    . . .
    <span style="color: #002200;">&#91;</span>self presentViewController<span style="color: #002200;">:</span>controller animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span> completion<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Invariably, someone asks: &#8220;Why not simply ask the AppDelegate for that data model object?&#8221;</p>
<p>They propose code such as this:</p>

<div class="wp_codebox"><table><tr id="p9488"><td class="code" id="p948code8"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Somewhere in SecondViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>someMethodThatNeedsTheDataModel
<span style="color: #002200;">&#123;</span>
    DataModel <span style="color: #002200;">*</span>dataModel <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>AppDelegate <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span>UIApplication
        sharedApplication<span style="color: #002200;">&#93;</span>.delegate<span style="color: #002200;">&#41;</span>.dataModel;
    . . .
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>That looks a bit ugly, but you can always &#8220;work around&#8221; that with a macro:</p>

<div class="wp_codebox"><table><tr id="p9489"><td class="code" id="p948code9"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// In your Prefix.pch file:</span>
<span style="color: #6e371a;">#define MY_APP_DELEGATE ((AppDelegate *)[UIApplication sharedApplication].delegate)</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// In SecondViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>someMethodThatNeedsTheDataModel
<span style="color: #002200;">&#123;</span>
    DataModel <span style="color: #002200;">*</span>dataModel <span style="color: #002200;">=</span> MY_APP_DELEGATE.dataModel;
    . . .
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>The DataModel object is now a property on the AppDelegate class, and you can &#8220;just&#8221; ask for it whenever you want. Easy right?</p>
<p>I don&#8217;t know who came up with this idea, but it seems widespread, especially among beginners. It&#8217;s also a quick fix with harmful consequences.</p>
<h3>So what is the difference?</h3>
<p>My preferred approach requires you to pass the DataModel object (or objects) from each view controller to the next, or at least to those that need it. That seems like more work, but it has an important advantage: your view controllers only depend on the objects that they directly need.</p>
<p>It is a good object-oriented design principle to limit the dependencies between your objects. The looser your objects are coupled, the better.</p>
<p>This is what the principle looks like in a picture:</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2012/02/Passing-around-DataModel.jpg"><img class="aligncenter size-full wp-image-951" title="Passing around DataModel" src="http://www.hollance.com/wp-content/uploads/2012/02/Passing-around-DataModel.jpg" alt="The view controllers pass around the DataModel object" width="550" height="290" /></a></p>
<p>However, when all your view controllers depend on the app delegate, the diagram looks like this:</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2012/02/Links-back-to-AppDelegate.jpg"><img class="aligncenter size-full wp-image-950" title="Links back to AppDelegate" src="http://www.hollance.com/wp-content/uploads/2012/02/Links-back-to-AppDelegate.jpg" alt="All the view controllers are now connected to the AppDelegate" width="550" height="279" /></a></p>
<p>The problem is this: As your app grows, it will have a lot of classes that have many interconnections between them. The greater the number of connections, the harder it is to understand what is going on in your code, and the harder it is to make changes. If you&#8217;re not careful, your code will become a big mess &#8212; and we all know where bugs love to hide.</p>
<p>By using the app delegate this way, you&#8217;re adding even more complexity to the web of connections. Each view controller now has to reach out to AppDelegate to get the data it needs to do its job.</p>
<p>You&#8217;re also giving AppDelegate too much to do. Before you know it, it has become this humongous class that is responsible for just about anything in your program.</p>
<p>Passing around objects all the time seems like a chore, but it&#8217;s the cleaner design. Consider each view controller in your app an island that can function independently of all the other view controllers, given the data model objects it needs for its calculations.</p>
<h3>What should the app delegate do?</h3>
<p>The app delegate performs an important function in your app but is not intended to be some magic singleton that holds all your data.</p>
<p>It is the place where you receive notifications that concern the application as a whole: the app is launched, the app is about to go into the background, the app has returned from the background, and so on. You should restrict the role of the app delegate to just handling those notifications.</p>
<p>The app delegate is where your app initializes itself &#8212; it creates the window and loads the initial view controller, it creates the data model objects or Core Data store &#8212; and then it passes control to that initial view controller. Beyond that, the app delegate should just handle the application-wide notifications and do nothing else.</p>
<p>So if you feel tempted to write,</p>

<div class="wp_codebox"><table><tr id="p94810"><td class="code" id="p948code10"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span>.delegate</pre></td></tr></table></div>

<p>anywhere in your code, then it&#8217;s time to rethink your class design.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2012/02/dont-abuse-the-app-delegate/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2012/02/dont-abuse-the-app-delegate/</feedburner:origLink></item>
		<item>
		<title>iOS Apprentice Tutorial 4 Available</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/EzaQyUqhl58/</link>
		<comments>http://www.hollance.com/2012/01/ios-apprentice-tutorial-4-available/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 17:15:47 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=938</guid>
		<description><![CDATA[I&#8217;m happy to announce that the latest ebook from my popular iOS Apprentice series is now available. In this tutorial you&#8217;ll build StoreSearch, an app that lets you search the iTunes store for songs, movies, books and software. You&#8217;ll learn about making your mobile apps talk to web services, iPad programming, internationalization&#8230; and lots more! [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to announce that the latest ebook from my popular iOS Apprentice series <a href="http://www.raywenderlich.com/8595/ios-apprentice-tutorial-4-now-for-sale">is now available</a>. <img src='http://www.hollance.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><a href="http://www.hollance.com/wp-content/uploads/2012/01/StoreSearch2.png"><img class="aligncenter size-full wp-image-939" title="StoreSearch" src="http://www.hollance.com/wp-content/uploads/2012/01/StoreSearch2.png" alt="The StoreSearch app" width="372" height="198" /></a></p>
<p>In this tutorial you&#8217;ll build StoreSearch, an app that lets you search the iTunes store for songs, movies, books and software. You&#8217;ll learn about making your mobile apps talk to web services, iPad programming, internationalization&#8230; and lots more!</p>
<p>You can <a href="http://e2f8cftfu-v2qzepkpolpohp65.hop.clickbank.net/">get the iOS Apprentice</a> at the Ray Wenderlich store.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2012/01/ios-apprentice-tutorial-4-available/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2012/01/ios-apprentice-tutorial-4-available/</feedburner:origLink></item>
		<item>
		<title>Freelance iPhone Developer, One Year Later</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/HxgISPzPYtk/</link>
		<comments>http://www.hollance.com/2012/01/freelance-iphone-developer-one-year-later/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 13:14:40 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Freelancing]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=884</guid>
		<description><![CDATA[A year or so ago I wrote a blog post about starting out as a freelance iOS developer. A lot has changed since then. I have no shortage of work and I was able to recently bump up my hourly rate to €150. Because of this, my fiancee and I can afford to take a [...]]]></description>
			<content:encoded><![CDATA[<p>A year or so ago I wrote <a href="http://www.hollance.com/2011/02/life-as-a-freelance-iphone-developer/">a blog post</a> about starting out as a freelance iOS developer. A lot has changed since then. I have no shortage of work and I was able to recently bump up my hourly rate to €150. Because of this, my fiancee and I can afford to take a three-month vacation in Australia soon and I don&#8217;t intend to do any work while we&#8217;re over there. Of course, I worked hard to make this possible.</p>
<h3>If you pay peanuts, you get monkeys</h3>
<p>Every day I get inquiries from potential clients, much more work than I could possibly handle. Some of these inquiries are quite unrealistic, but the 150 Euro per hour price tag is quite effective in scaring off the dreamers with a hundred bucks and an idea. (It&#8217;s also basic economics: If you can&#8217;t keep up with the demand, raise your prices.)</p>
<p>My hourly rate may seem high but one thing I learned over the past year is that I&#8217;m a really good developer and that I&#8217;m worth it. Asking for big money obviously drives away a lot of potential clients, but the clients that I do get are serious about what they want, their projects are interesting, and they understand what it takes to make a quality product.</p>
<p>As any creative professional can tell you: &#8220;The more you pay me, the more you can expect of me, and the harder I will work to make the end result really wonderful.&#8221;</p>
<p>Inspired by <a href="http://sealedabstract.com/rants/do-hard-things/">this excellent rant</a>, I also decided to take on only the really hard projects, the ones that are too hard for other developers. Simple apps are boring &#8212; I need challenges that allow me to make the most out of my skills!</p>
<h3>How to find work</h3>
<p>I received an email today from a fellow freelance developer who found himself in the same spot I was in a year ago:</p>
<blockquote><p>&#8220;I was wondering if you had any more luck finding work via internet resources since your post was written? I figured I&#8217;d look around at a couple of the big freelancing sites and see what I can find, but I think it&#8217;d be so much better if it was more personal.&#8221;</p></blockquote>
<p>There are two things I did that made all the difference. First off, I started blogging. There&#8217;s always a need for good information about any topic in your field, so if you write quality posts you&#8217;ll build up a name for yourself and people will come to regard you as an expert.</p>
<p>With a blog full of quality material, you&#8217;re no longer some anonymous developer but someone who has already demonstrated his skills. It makes it easier for clients to trust that you can actually deliver.</p>
<p>Putting some of your own code on Github is another way to pull that off. I have created some <a href="https://github.com/hollance">open source components</a> that people find useful, and that gets my name out there too.</p>
<p>The biggest thing I did, however, was to write for <a href="http://www.raywenderlich.com">www.raywenderlich.com</a>. That is a popular site with tons of great tutorials and my contributions seem to be appreciated. I also wrote a 750-page ebook called <a href="http://www.hollance.com/2011/08/free-tutorial-the-ios-apprentice-getting-started/">The iOS Apprentice</a> that is sold through Ray&#8217;s site, and contributed to the ebook <a href="http://e2f8cftfu-v2qzepkpolpohp65.hop.clickbank.net/">iOS 5 By Tutorials</a>.</p>
<p>A lot of this is hard, unpaid work, but it pays itself back in building up your reputation. I&#8217;m probably not as well known in iOS circles as Matt Gemmell or Marco Arment, but I&#8217;m working on it. <img src='http://www.hollance.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h3>Not what you know, but who you know</h3>
<p>The second thing is to get in touch with other developers. Networking is a great way to get referrals for jobs. Many developers have too much on their plate so they&#8217;d be happy to pass on work to other developers they know and trust. Some will also subcontract out certain parts of their projects.</p>
<p>There are many ways to network. You can get in touch with other developers that are local to you through groups such as CocoaHeads and meetings such as NSCoder Night. If no such group exists in your area, you might consider setting one up yourself.</p>
<p>You don&#8217;t have to restrict yourself to just meeting iOS developers, of course. Mobile developers, web developers, designers, start-up founders, these are all useful people to get to know.</p>
<p>Face-to-face networking is probably best, but on the internet there are plenty of places to get in touch with other developers as well: forums, blogs, IRC, Facebook, LinkedIn, you name it. Hanging out with your peers has never been easier&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2012/01/freelance-iphone-developer-one-year-later/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2012/01/freelance-iphone-developer-one-year-later/</feedburner:origLink></item>
		<item>
		<title>Transparent JPEG Images</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/qmGtbyJNYwU/</link>
		<comments>http://www.hollance.com/2011/11/transparent-jpeg-images/#comments</comments>
		<pubDate>Sat, 12 Nov 2011 12:24:35 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=863</guid>
		<description><![CDATA[When you distribute images with your app you usually pick the PNG or JPEG format. The advantage of JPEG is that it often compresses better &#8212; especially for photos &#8212; but unlike PNG it unfortunately does not support transparency. The transparency in a PNG file comes from the so-called &#8220;alpha channel&#8221;. For every pixel not [...]]]></description>
			<content:encoded><![CDATA[<p>When you distribute images with your app you usually pick the PNG or JPEG format. The advantage of JPEG is that it often compresses better &#8212; especially for photos &#8212; but unlike PNG it unfortunately does not support transparency.</p>
<p>The transparency in a PNG file comes from the so-called &#8220;alpha channel&#8221;. For every pixel not only red, green and blue values are stored but also an &#8220;alpha&#8221; value that determines how transparent that pixel is. A value of 255 means this pixel is fully opaque, 0 is fully transparent, and anything in between will mix the pixel&#8217;s RGB values with the underlying color.</p>
<p>This is probably an old trick, but by saving a JPEG image not as one but as two image files you can still have transparent images. The first image is the regular JPEG with as much compression as you can get away with, the second image is the alpha channel. This is a grayscale image with black representing fully transparent, white fully opaque, and gray everything in between.</p>
<p>&nbsp;</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/11/Source-and-Alpha.png"><img class="aligncenter size-full wp-image-864" title="Source-and-Alpha" src="http://www.hollance.com/wp-content/uploads/2011/11/Source-and-Alpha.png" alt="Source image and its alpha channel" width="446" height="290" /></a><br />
We can combine these two images at runtime to make the image transparent again. Because of the JPEG compression we lose a little bit of clarity but if you tweak the compression settings you can usually get away with it.</p>
<p>I wrote a <a href="https://github.com/hollance/TransparentJPEG">simple category on UIImage</a> that lets you do this.</p>
<h3>Preparing your images</h3>
<p><strong>1)</strong> Export your image from Photoshop as a PNG with transparency.</p>
<p><strong>2)</strong> Export the image again as a JPEG, using suitable compression settings. The background should have a solid color, typically white or black but any color will do.</p>
<p><strong>3)</strong> Save the alpha channel to a separate JPEG or PNG image. I couldn&#8217;t find an easy way to do this from Photoshop, but the <a href="http://www.imagemagick.org/">ImageMagick</a> tool can do it without problems.</p>
<p>If you have ImageMagick installed, open a Terminal and go to the folder that contains the exported PNG image. Then type:</p>
<pre>convert -alpha Extract -type optimize -strip -quality 60 +dither \
    Source.png Alpha.jpg</pre>
<p>This extracts the alpha channel from the PNG image and saves it as a JPEG file. You can tweak the level of compression with the -quality parameter. If you specify &#8220;Alpha.png&#8221; instead of &#8220;Alpha.jpg&#8221;, ImageMagick saves the alpha channel as a grayscale PNG-8 file. You should use whichever one makes the smallest file size.</p>
<h3>Combining the images</h3>
<p><strong>1)</strong> Add the two JPEG images (the non-transparent source image and the alpha channel) to the app.</p>
<p><strong>2)</strong> At some point, call the<strong> mh_combineWithAlphaImage:backgroundColor:</strong> method to combine these two images into a new, transparent, image.</p>
<p><strong>3)</strong> Depending on your app you may want to do this only once and then store the transparent image as a PNG in your app&#8217;s Caches folder.</p>
<p>That&#8217;s it, quite easy.</p>
<h3>Some notes</h3>
<p>The alpha image does not have to be a JPEG, it can also be a PNG file. If it is a JPEG then it can have different quality/compression settings from the main image.</p>
<p>The current implementation works well but is not as fast as it could be. It also uses more memory than is strictly necessary. I might rewrite this at some point to use the Accelerate framework or Core Image.</p>
<p>Not all images compress better as JPEG. You should use JPEG only where it makes sense.</p>
<p>Check out the <a href="https://github.com/hollance/TransparentJPEG">source code at Github</a>.</p>
<p><em>Bird image by <a href="http://www.sxc.hu/photo/1362219">Sias van Schalkwyk</a></em></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/11/transparent-jpeg-images/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/11/transparent-jpeg-images/</feedburner:origLink></item>
		<item>
		<title>MHTabBarController – A custom tab bar for iOS 5 using the new container APIs</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/sjCHqC9sbJ4/</link>
		<comments>http://www.hollance.com/2011/11/mhtabbarcontroller-a-custom-tab-bar-for-ios-5-using-the-new-container-apis/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 18:34:49 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=854</guid>
		<description><![CDATA[Creating your own container view controllers, i.e. view controllers that can contain other view controllers, used to be a pain but now iOS 5 makes it a lot easier. Especially for iPad apps that is great, because all of that screen space means you probably want to divide it up amongst more than one view [...]]]></description>
			<content:encoded><![CDATA[<p>Creating your own container view controllers, i.e. view controllers that can contain other view controllers, used to be a pain but now iOS 5 makes it a lot easier.</p>
<p>Especially for iPad apps that is great, because all of that screen space means you probably want to divide it up amongst more than one view controller.</p>
<p>Today I was messing around with these new container APIs and built my own tab bar controller. It works just like a regular UITabBarController, except the tabs look quite different and the pages slide in and out of the screen with a nice animation.</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/11/Screenshot.png"><img class="aligncenter size-full wp-image-855" title="Screenshot" src="http://www.hollance.com/wp-content/uploads/2011/11/Screenshot.png" alt="Screenshot of MHTabBarController in the demo app" width="396" height="364" /></a><br />
If you want to learn more about how to do this, then check out the <a href="https://github.com/hollance/MHTabBarController">source code</a> or get the <a href="http://e2f8cftfu-v2qzepkpolpohp65.hop.clickbank.net/">iOS 5 by Tutorials</a> ebook. It has a full chapter on these new view controller containment APIs, plus twenty or so other chapters on more iOS 5 goodness!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/11/mhtabbarcontroller-a-custom-tab-bar-for-ios-5-using-the-new-container-apis/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/11/mhtabbarcontroller-a-custom-tab-bar-for-ios-5-using-the-new-container-apis/</feedburner:origLink></item>
		<item>
		<title>Making UIBarButtonItems in Photoshop</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/n59EDOJo-_4/</link>
		<comments>http://www.hollance.com/2011/10/making-uibarbuttonitems-in-photoshop/#comments</comments>
		<pubDate>Sat, 29 Oct 2011 14:15:58 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=817</guid>
		<description><![CDATA[Recently I was working on an app that required brightly tinted tool bars and navigation bars: As you can see, the light blue color makes the bar button hard to see and its label hard to read. Changing the background color of the button is really easy on iOS 5 because its UIBarButtonItem also has [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I was working on an app that required brightly tinted tool bars and navigation bars:</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/10/LightToolbar.png"><img class="aligncenter size-full wp-image-820" title="LightToolbar" src="http://www.hollance.com/wp-content/uploads/2011/10/LightToolbar.png" alt="A UIToolBar with a light blue tint color" width="338" height="208" /></a></p>
<p>As you can see, the light blue color makes the bar button hard to see and its label hard to read. Changing the background color of the button is really easy on iOS 5 because its UIBarButtonItem also has a .tintColor property. But if you still need to support iOS 4 then you&#8217;re out of luck.</p>
<p>In that case, the only solution is to put a UIButton inside the UIBarButtonItem and give it a background image that looks like a regular bar button. It&#8217;s a roundabout way of doing things but it works.</p>
<p>Previously, I would draw these bar button-lookalike images myself in Photoshop. By setting the appropriate layer styles on a rounded rectangle vector object you can make a decent approximation of what a real bar button item looks like.</p>
<p>This time, however, I wanted to take advantage of the actual images that UIKit itself uses to compose the UIBarButtonItem when you change the tintColor of the underlying toolbar or navigation bar.</p>
<p>To pull this off, you can download <a href="https://github.com/0xced/UIKit-Artwork-Extractor">UIKit Artwork Extractor</a>. Compile the app and run it on the Simulator (or on your device). It will extract all the images that are built into the various iPhone and iPad frameworks and save them to a folder on your computer.</p>
<p>After you have extracted the images, go into the &#8220;Shared&#8221; subfolder and look for:</p>
<ul>
<li>UITintedButtonHighlight.png</li>
<li>UITintedButtonMask.png</li>
<li>UITintedButtonShadow.png</li>
</ul>
<p>You can combine these three images with a fill color to produce a tinted UIBarButtonItem background image, like this:</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/10/LayersConceptual.png"><img class="aligncenter size-full wp-image-834" title="LayersConceptual" src="http://www.hollance.com/wp-content/uploads/2011/10/LayersConceptual.png" alt="How to add the different images to produce the final bar button image" width="392" height="346" /></a></p>
<p>The actual layers pane should look like this:</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/10/Layers.png"><img class="aligncenter size-full wp-image-835" title="Layers" src="http://www.hollance.com/wp-content/uploads/2011/10/Layers.png" alt="The Layers pane in Photoshop" width="217" height="303" /></a></p>
<p>The &#8220;Fill color&#8221; layer is simply a rectangle filled with the tint color that you want the button to have. As you can see, both the fill layer and the &#8220;shadow&#8221; layer are clipped against the red &#8220;mask&#8221; layer. If you don&#8217;t do that, the button won&#8217;t have a transparent background in the corners.</p>
<p>To export the image, merge all the visible layers (but not the background!) and save the image as PNG. This gives you a 11&#215;30 pixels stretchable image.</p>
<p>You can use the following category to create the fake bar button items in your code. It requires that the image named &#8220;BarButton.png&#8221; is added to your project.</p>

<div class="wp_codebox"><table><tr id="p81712"><td class="code" id="p817code12"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@implementation</span> UIBarButtonItem <span style="color: #002200;">&#40;</span>FakeButtons<span style="color: #002200;">&#41;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>initWithTitle<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>title width<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGFloat<span style="color: #002200;">&#41;</span>width target<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>target action<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">SEL</span><span style="color: #002200;">&#41;</span>action
<span style="color: #002200;">&#123;</span>
	UIButton <span style="color: #002200;">*</span>button <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIButton buttonWithType<span style="color: #002200;">:</span>UIButtonTypeCustom<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>button setTitle<span style="color: #002200;">:</span>title forState<span style="color: #002200;">:</span>UIControlStateNormal<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>button addTarget<span style="color: #002200;">:</span>target action<span style="color: #002200;">:</span>action forControlEvents<span style="color: #002200;">:</span>UIControlEventTouchUpInside<span style="color: #002200;">&#93;</span>;
	button.titleLabel.font <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIFont boldSystemFontOfSize<span style="color: #002200;">:</span><span style="color: #2400d9;">12</span><span style="color: #002200;">&#93;</span>;
	button.titleLabel.shadowColor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIColor colorWithWhite<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span> alpha<span style="color: #002200;">:</span><span style="color: #2400d9;">0.5</span><span style="color: #002200;">&#93;</span>;
	button.titleLabel.shadowOffset <span style="color: #002200;">=</span> CGSizeMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0</span>, <span style="color: #002200;">-</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#41;</span>;
	button.frame <span style="color: #002200;">=</span> CGRectMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0</span>, <span style="color: #2400d9;">0</span>, width, <span style="color: #2400d9;">30</span><span style="color: #002200;">&#41;</span>;
&nbsp;
	UIImage <span style="color: #002200;">*</span>image <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIImage imageNamed<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;BarButton&quot;</span><span style="color: #002200;">&#93;</span> stretchableImageWithLeftCapWidth<span style="color: #002200;">:</span><span style="color: #2400d9;">5</span> topCapHeight<span style="color: #002200;">:</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>button setBackgroundImage<span style="color: #002200;">:</span>image forState<span style="color: #002200;">:</span>UIControlStateNormal<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#40;</span>self <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self initWithCustomView<span style="color: #002200;">:</span>button<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>In the &#8220;Shared&#8221; folder you will also find images for the UINavigationController back button (named UITintedBackButtonXXX.png), but be advised that bar button items with a custom view won&#8217;t work on UINavigationItem&#8217;s backBarButtonItem property. You&#8217;ll have to put your custom back button on leftBarButtonItem instead.</p>
<p>Tip: If you also want to have Retina-sized images, run Artwork Extractor on a Retina device or on the Simulator in Retina mode. It&#8217;s very enlightening to look through the rest of the extracted artwork as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/10/making-uibarbuttonitems-in-photoshop/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/10/making-uibarbuttonitems-in-photoshop/</feedburner:origLink></item>
		<item>
		<title>Get up-to-date on iOS 5 with the iOS 5 By Tutorials ebook</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/zH2xGm5vDs0/</link>
		<comments>http://www.hollance.com/2011/10/get-up-to-date-on-ios-5-with-the-ios-5-by-tutorials-ebook/#comments</comments>
		<pubDate>Wed, 12 Oct 2011 23:54:57 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=774</guid>
		<description><![CDATA[Now that iOS 5 is out and the NDA has been lifted, we can finally talk in public about all the new features in the SDK. And there is a lot to talk about! Together with the other members of the RayWenderlich.com Tutorial Team I&#8217;ve been hard at work these past weeks putting together an [...]]]></description>
			<content:encoded><![CDATA[<p>Now that iOS 5 is out and the NDA has been lifted, we can finally talk in public about all the new features in the SDK. And there is a lot to talk about!</p>
<p><a href="http://e2f8cftfu-v2qzepkpolpohp65.hop.clickbank.net/"><img class="alignleft size-full wp-image-776" title="ad_iOS5BT_125x125" src="http://www.hollance.com/wp-content/uploads/2011/10/ad_iOS5BT_125x125.jpg" alt="" width="125" height="125" /></a>Together with the other members of the RayWenderlich.com Tutorial Team I&#8217;ve been hard at work these past weeks putting together an ebook that goes in-depth on many of the new technologies in iOS 5.</p>
<p>I contributed four chapters on Automatic Reference Counting (ARC) and Storyboards, and the book is packed with other cool stuff as well.</p>
<p>Some of the topics covered: iCloud, OpenGL ES 2.0 with GLKit, Newsstand, UIKit customization, using the new integrated Twitter, Turn Based Gaming with Game Center, Core Image, and much more!</p>
<p>Because we had to rush a bit to get it out in time, the book is currently available as a beta version. It&#8217;s already 600 pages and there are many more goodies coming. If you <a href="http://e2f8cftfu-v2qzepkpolpohp65.hop.clickbank.net/">get the book now</a>, you&#8217;ll receive the new chapters as they become available.</p>
<p>I&#8217;m really excited about this ebook. It&#8217;s a goldmine of information and I can&#8217;t wait to read it myself! Check it out at <a href="http://e2f8cftfu-v2qzepkpolpohp65.hop.clickbank.net/">www.raywenderlich.com</a>.</p>
<h3>The iOS Apprentice is available too!</h3>
<p>Speaking of ebooks, I&#8217;m happy to announce that as of today the next two parts of my beginner course <a href="http://www.raywenderlich.com/store/ios-apprentice">The iOS Apprentice</a> are available as well.</p>
<p>This course is a series of epic-length tutorials that take you from zero to writing real apps for the iPhone and iPad. It&#8217;s aimed at complete beginners and people who have experience with other languages (PHP, Java, C#) but who are new to the platform.</p>
<p>If you&#8217;re confused about what a delegate or a view controller is, or if the strange syntax of Objective-C scares you, then you need to <a href="http://www.raywenderlich.com/store/ios-apprentice">get this ebook</a>!</p>
<p>You can read the first part for free when you sign up for Ray&#8217;s Monthly Newsletter at <a href="http://www.raywenderlich.com">www.raywenderlich.com</a>, so check it out and let me know what you think. If you liked the first part, you&#8217;re going to love the rest of The iOS Apprentice. <img src='http://www.hollance.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p style="text-align: center;"><a href="http://www.raywenderlich.com/store/ios-apprentice"><img class="aligncenter size-full wp-image-793" title="The iOS Apprentice preview" src="http://www.hollance.com/wp-content/uploads/2011/10/Series-preview-small.png" alt="The iOS Apprentice preview" width="500" height="238" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/10/get-up-to-date-on-ios-5-with-the-ios-5-by-tutorials-ebook/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/10/get-up-to-date-on-ios-5-with-the-ios-5-by-tutorials-ebook/</feedburner:origLink></item>
		<item>
		<title>Good Software</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/TjX39UdTFPU/</link>
		<comments>http://www.hollance.com/2011/10/good-software/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 12:21:39 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=765</guid>
		<description><![CDATA[Good Software&#8230; Is instantaneous, it doesn&#8217;t make me wait. Remembers things for me. Draws intelligent conclusions based on my past behavior and correctly predicts what I want to do next. Allows me to make mistakes and experiment. Is predictable, it should not confuse me by doing something I did not expect. Is dependable, it does [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Good Software&#8230;</strong></p>
<p>Is instantaneous, it doesn&#8217;t make me wait.</p>
<p>Remembers things for me.</p>
<p>Draws intelligent conclusions based on my past behavior and correctly predicts what I want to do next.</p>
<p>Allows me to make mistakes and experiment.</p>
<p>Is predictable, it should not confuse me by doing something I did not expect.</p>
<p>Is dependable, it does not lose or corrupt my data.</p>
<p>Is polite, it doesn&#8217;t interrupt me.</p>
<p>Gets out of my way.</p>
<p>Puts my needs first, not those of the computer or the developer (or publisher/brand/investor/sponsor).</p>
<p>Is an extension of me, not another burden to carry.</p>
<p>Makes my life easier, not more frustrating.</p>
<p>Is smart, it does not require me to hold its hand all the time.</p>
<p>Should shape itself to <em>my</em> perception of reality.</p>
<p>(We have a long way to go still!)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/10/good-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/10/good-software/</feedburner:origLink></item>
		<item>
		<title>Free tutorial, The iOS Apprentice: Getting Started</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/zNz8ydUaKIA/</link>
		<comments>http://www.hollance.com/2011/08/free-tutorial-the-ios-apprentice-getting-started/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 16:21:44 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=715</guid>
		<description><![CDATA[It&#8217;s been a while since I wrote for this blog but I had a good excuse: I&#8217;ve been working hard on my first ebook, The iOS Apprentice: iPhone and iPad Programming for Beginners. I get a fair amount of email from beginning programmers and they usually ask the same questions. They&#8217;ve read a book or [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I wrote for this blog but I had a good excuse: I&#8217;ve been working hard on my first ebook, <em>The iOS Apprentice: iPhone and iPad Programming for Beginners</em>.</p>
<p>I get a fair amount of email from beginning programmers and they usually ask the same questions. They&#8217;ve read a book or tutorial about the basics but now they&#8217;re stuck. It&#8217;s easy enough to create a simple screen with a few buttons, to show a list of items in a table view, to use the photo picker, to download something from the internet&#8230; but how do you fit all of that together? These are also the questions I keep seeing on forums and message boards. So I decided to write an ebook with the answers.</p>
<p>This ebook contains five epic-length tutorials, each of which takes you from scratch to a complete, fully-functional iPhone or iPad app, with step-by-step instructions and a ton of illustrations. There&#8217;s a big difference between building a simple sample project that focuses just on a single topic, and creating a real app that has many different features &#8212; the kind of app that you actually see in the App Store. The <em>iOS Apprentice</em> shows you how to do the latter.</p>
<p>This is what Bull&#8217;s Eye looks like, the game from the first chapter:</p>
<p>&nbsp;</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/08/The-finished-Bulls-Eye-game.png"><img class="aligncenter size-medium wp-image-719" title="The finished Bull's Eye game" src="http://www.hollance.com/wp-content/uploads/2011/08/The-finished-Bulls-Eye-game-300x193.png" alt="The finished Bull's Eye game" width="300" height="193" /></a></p>
<p>You can see this game in action for yourself because as of today the first chapter of the ebook is available for free!</p>
<p>If you&#8217;re thinking of getting started with iOS development but you have  no idea where to start, then get this ebook! No knowledge of programming  is assumed, so if you&#8217;ve never written a line of code before in your  life, you&#8217;re in good hands.</p>
<p>It is my aim that by the end of these 5 tutorials you&#8217;ll be ready to turn your own ideas into real apps. This isn&#8217;t some 20-page fluff ebook, but over 500 pages and more than 500 illustrations of hands-on practical advice.</p>
<p>I&#8217;m currently writing the final chapters. I expect the ebook to be done by the time iOS 5.0 comes out (early fall). Of course, the tutorials make good use of the new features from iOS 5 such as Automatic Reference Counting and Storyboards.</p>
<p>If this sounds like something you&#8217;d be interested in, then here&#8217;s how you can get the entire first chapter for free right now:</p>
<p>Go to <a href="http://www.raywenderlich.com">www.raywenderlich.com</a> and sign up for Ray&#8217;s Monthly Newsletter. Ray has an excellent site with many free iOS development tutorials, and he has agreed to sell <em>The iOS Apprentice</em> from his website, which makes me very happy.</p>
<p>After signing up for his newsletter &#8212; which is a very useful resource in its own right! &#8212; you&#8217;ll receive the download link for the first chapter (23 MB).</p>
<p>Enjoy the free chapter and let me know how you&#8217;re getting on! In the mean time, I have a few more pages to write&#8230; <img src='http://www.hollance.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/08/free-tutorial-the-ios-apprentice-getting-started/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/08/free-tutorial-the-ios-apprentice-getting-started/</feedburner:origLink></item>
		<item>
		<title>Just Say No to Splash Screens</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/AAXrFH58hj8/</link>
		<comments>http://www.hollance.com/2011/05/just-say-no-to-splash-screens/#comments</comments>
		<pubDate>Fri, 27 May 2011 19:31:14 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Freelancing]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=691</guid>
		<description><![CDATA[The client briefs that I receive often contain the requirement that “the app should display our logo when it starts”. In other words, a splash screen. Unless you&#8217;re making a game, I think adding a splash screen to your app is a bad idea, and here is why: Splash screens make your app appear to [...]]]></description>
			<content:encoded><![CDATA[<p>The client briefs that I receive often contain the requirement that “the app should display our logo when it starts”. In other words, a splash screen. Unless you&#8217;re making a game, I think adding a splash screen to your app is a bad idea, and here is why:</p>
<p><strong>Splash screens make your app appear to start up slower. </strong>When the user launches an app, he expects to be able to interact with it immediately. If you show a splash screen first, he has to make a context switch from what he expected to see (the actual app) to your logo and back again when the app is done loading and its real interface finally appears.</p>
<p>Instead, if you <a href="http://developer.apple.com/library/ios/documentation/userexperience/conceptual/mobilehig/IconsImages/IconsImages.html#//apple_ref/doc/uid/TP40006556-CH14-SW5">do what Apple recommends</a> in the HIG—show an empty version of your UI, without any content—then the perceived app startup time is actually shorter and users are happier as a result. Anything you can do to make your users happier is something you <em>should</em> do.</p>
<p>All iPhone and iPad apps contain a launch image, Default.png, that is shown when the app is being loaded by the operating system. Unfortunately the temptation is big to put a logo in this image. Don&#8217;t, as that is not what it&#8217;s there for.</p>
<p>Here is the launch image of an app I recently completed for a client. Boring, but effective.</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/05/Default.png"><a href="http://www.hollance.com/wp-content/uploads/2011/05/Default.png"><img class="aligncenter size-medium wp-image-695" title="Default" src="http://www.hollance.com/wp-content/uploads/2011/05/Default-300x207.png" alt="A typical Default.png launch image" width="300" height="207" /></a></a><br />
<strong>Splash screens are about you, not about the user. </strong>You probably like your logo very much and I&#8217;m sure it is pretty, but here is something you need to realize: <em>the user doesn&#8217;t particularly care about you or your logo</em>. You, on the other hand, should care very much about the user.</p>
<p>Most people just want to get on with things and if your app helps them do so, great! But if the app gets in their way, it only takes three taps to uninstall.</p>
<p>If your app is a novelty app designed to promote your brand, then remember that unless the app delivers some kind of value, people won&#8217;t be using it for very long and they won&#8217;t get much exposure to your message. Focus on the value, not on the brand.</p>
<p>Forego the splash screen and find a better way to integrate your branding in the app&#8217;s user interface. Give people a good experience to associate with your brand, rather than shoving it into their faces.</p>
<p><strong>The launch image is rarely shown anymore.</strong> Now that almost everyone has OS 4 with multitasking on their iPhone, apps resume where they left off the next time they are opened. This means the load image, i.e. your splash screen, is only shown for a brief instant the very first time the app is used.</p>
<p>The launch image also appears if your app is re-launched after it was truly terminated, which occasionally happens when there is not enough free memory to keep all suspended apps around. Most of the time, however, when the app loads the user sees a snapshot of where he last left off.</p>
<p>Showing your splash screen only now and then makes for a very inconsistent experience. Putting a logo in the launch image might have worked on the slower models when there was no multitasking yet, but no more.</p>
<p><strong>Don&#8217;t get too clever!</strong> If your app launches really quickly—and it should!—then the load image is only visible for a second or so, especially on the fast iPhone 4. Hardly long enough to make an impression.</p>
<p>To “solve” this problem, some apps use a timer that keeps the splash screen visible for a few seconds more before it fades into the main interface. How silly is that? You are not doing the user any favors by purposely slowing down the launching of the app.</p>
<p>Let me say it again: the app is not about you, your brand or your logo, it is about the user and the goal he wants to accomplish.</p>
<p>If your app is a game, then it makes sense to show a “Loading&#8230;” screen but for any other apps, do the right thing and put a blank version of your UI in the default load image.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/05/just-say-no-to-splash-screens/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/05/just-say-no-to-splash-screens/</feedburner:origLink></item>
		<item>
		<title>Developing Software is Expensive Because It is Hard</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/-p4vPffnBhk/</link>
		<comments>http://www.hollance.com/2011/05/developing-software-is-expensive-because-it-is-hard/#comments</comments>
		<pubDate>Wed, 18 May 2011 22:48:30 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Freelancing]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=636</guid>
		<description><![CDATA[If you have an idea for an app and are looking to get it developed but you have no programming experience yourself, it might be wise to learn a bit about the difficulties of developing software so you can avoid the common pitfalls: not getting the app you want, paying more than you budgeted, not [...]]]></description>
			<content:encoded><![CDATA[<p>If you have an idea for an app and are looking to get it developed but you have no programming experience yourself, it might be wise to learn a bit about the difficulties of developing software so you can avoid the common pitfalls:</p>
<ul>
<li>not getting the app you want,</li>
<li>paying more than you budgeted,</li>
<li>not getting your deliverables on time.</li>
</ul>
<p>There is a reason why software takes a long time to develop, is expensive to make, and often isn&#8217;t very good: <strong>programming computers is hard</strong>!</p>
<p>It&#8217;s easy enough to learn the basics of programming. There are only a handful of building blocks and by themselves they are easy to understand. However, knowing how to combine them into a larger application is the real trick and that takes many years to master.</p>
<p>If you&#8217;ve never programmed before, or never went beyond the trivial programs you had to write in school, the difficulty of the task may be hard to appreciate. In this article, I&#8217;ll try to give some insight into why writing software takes so much effort and why it fails so often, and some tips on how to avoid disappointment.<span id="more-636"></span></p>
<h3>Software is complex</h3>
<p>I see a lot of job postings where clients say: “I&#8217;m looking to have a simple app developed”. Great, I have nothing against simple apps but you should realize there is no such thing as a simple <em>program</em>.</p>
<p>The app itself may only have a few screens and be a breeze to use, but the underlying program code definitely won&#8217;t be simple. A program consists of many small parts that all have to work together in an intricate fashion. As they grow in number it becomes very difficult to keep track of all these parts and to see how they all fit together.</p>
<p>The human brain simply cannot handle this level of complexity. It is impossible to hold the entirety of a program in your head at once. In fact, it is common to make a change to one part of the program and &#8212; without realizing it &#8212; break something else in another part.</p>
<p>Good software developers use tools and techniques that help them structure their programs in ways that minimize these issues. This is where hiring an experienced developer pays off. But even for a veteran, complexity remains a significant obstacle.</p>
<h3>Software is brittle</h3>
<p>Computers do exactly what you tell them to, no more, no less. This   means the developer needs to be very specific in the commands he gives   the computer, or he&#8217;ll get different results than he was expecting (i.e.  bugs).  Programming is a very delicate and time-consuming art.</p>
<p>All the parts in a program are tightly connected. As I said, a change to one part has consequences for the other parts. A program is like a house of cards; take out the wrong card and the house collapses.</p>
<p>Because everything fits together exactly, a change to one piece means that other pieces may have to be modified too. Of course, those additional changes have an impact of their own.</p>
<p>A change that may appear small – “just move this button to the next screen” – can create ripples that have a huge impact on the underlying code. Large chunks of the code may need to be rewritten to accommodate your changes.</p>
<p>You as the client don&#8217;t see this but it is work that needs to happen and you will be paying for it, in time and in money (or bugs).</p>
<h3>All change has a cost</h3>
<p>The cost of making changes increases over time. Early on in the project, the codebase is still small and changes do not yet have much impact, so they are relatively cheap. If you&#8217;re unsure about certain features of your app, this is the best time for experimentation.</p>
<p>However, as time goes on, the codebase grows and grows and with it complexity increases. The code becomes more and more tightly interwoven. A big change in functionality will require large portions of the code to be rewritten.</p>
<p>At this point, even a small change can have adverse effects. The programmer may decide that properly restructuring the code to facilitate this small change it is not worth his time (a deadline may be looming) or the money you&#8217;re paying him, so instead he will devise a clever workaround.</p>
<p>Unfortunately, clever workarounds will only make the code more complex and harder to understand. If enough of these workarounds accumulate, the code will become unmaintainable and you will be forced to start all over with a complete rewrite.</p>
<p>So what can you do?</p>
<h3>Educate yourself</h3>
<p>The more you can do ahead of time, before development starts, the better. Get an iPhone or iPad and play with the popular apps. Read the <a href="http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/mobilehig/Introduction/Introduction.html">HIG</a>. Devour <a href="http://www.amazon.com/gp/product/1449381650/ref=as_li_ss_tl?ie=UTF8&amp;tag=natuhabi-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399349&amp;creativeASIN=1449381650">Tapworthy</a>. Get the <a href="http://www.happytapper.com/ebooks/">Happy Tapper</a> e-book.</p>
<p>You don&#8217;t need to become a developer or UI designer yourself, but at least get some idea of what goes into building an app. This will make it easier for you to talk to and understand your developer.</p>
<p>Decide exactly what app you want before you hire a developer. The better you know what you want, and can explain what you want, the less room there is for misinterpretations and the less need there is for changes while programming is underway.</p>
<p>Write down your wishes. Be specific and complete. A good developer will work with you to round out this specification, but the more you can do by yourself in advance, the more money (and frustration!) you save.</p>
<h3>Iterate, iterate, iterate</h3>
<p>Even though I just said that you should make your mind up on exactly what you want before programming begins, in practice you will find that things that look good on paper do not always work so well when you actually try them on the phone.</p>
<p>It&#8217;s simply impossible to do everything right from the start. Revisions are inevitable. The trick is to prepare for this fact and to be flexible enough to handle these changes.</p>
<p>There is nothing more aggravating for a developer than spending several months on an app only to have the client say: “Yeah, that&#8217;s not really how we wanted it,” even though the developer built exactly what was agreed upon.</p>
<p>Avoid this by working in short iterations. Split up the project into milestones that each last no more than a few weeks. After each milestone is complete, re-evaluate the project &#8212; are you still getting what you want? – and change course if necessary.</p>
<h3>Be available for feedback</h3>
<p>In the course of writing the program, the programmer needs make a lot of decisions. Most of the time these concern implementation details that you could care less about, but things always come up that will  impact the way the app functions. In other words, they expose design issues.</p>
<p>You need to be prepared to come up  with solutions to these problems or the programmer will have to make  those decisions for you and you may end up with something you did not  want. Reversing such a decision is costly for you and frustrating for the developer.</p>
<p>Having an app developed requires constant interaction between the both of you. You can&#8217;t simply hand off a stack of specs and expect the developer to re-emerge a month later from his cave with a finished app in his hand. That&#8217;s not how it works!</p>
<p>You will need to put in as least as much effort as the developer. This does not mean you need to micro-manage, but you should be available to deal with design issues. It&#8217;s <em>your </em>app, after all.</p>
<h3>There is more to it than programming</h3>
<p>Of course, the programming is only one part of the app development process. Designing the user interaction experience is at least as important and just as difficult. Designing an attractive visual experience is not small feat either.</p>
<p>Some developers can also handle these design tasks but just because someone is a good programmer, doesn&#8217;t mean they are also good interaction designers or graphics artists. Chances are you need to hire an UI designer and a graphics artist in addition to a developer, but that&#8217;s a topic for another article.</p>
<p>I hope this article gave you some insight into the difficulties of software development. It&#8217;s hard because it&#8217;s complex and us humans are operating at the limits of our capacity for dealing with this kind of complexity.</p>
<p>Be prepared and increase your chances of success!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/05/developing-software-is-expensive-because-it-is-hard/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/05/developing-software-is-expensive-because-it-is-hard/</feedburner:origLink></item>
		<item>
		<title>Apple Push Notification Services Tutorial</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/wlwUYdx4XS0/</link>
		<comments>http://www.hollance.com/2011/05/apple-push-notification-services-tutorial/#comments</comments>
		<pubDate>Fri, 13 May 2011 10:36:44 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=626</guid>
		<description><![CDATA[If you&#8217;re an iOS developer you probably know about Ray Wenderlich and his awesome tutorial site. A few weeks ago Ray mentioned he was looking for people to help him write more tutorials. That sounded like fun, so I signed up immediately. I am now a proud member of Ray&#8217;s iOS Tutorial Team! My first [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re an iOS developer you probably know about Ray Wenderlich and his <a href="http://www.raywenderlich.com">awesome tutorial site</a>. A few weeks ago Ray mentioned he was looking for people to help him write more tutorials. That sounded like fun, so I signed up immediately. I am now a proud member of Ray&#8217;s iOS Tutorial Team! <img src='http://www.hollance.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align: center;"><a href="http://www.hollance.com/wp-content/uploads/2011/05/I-am-Push.png"><img class="size-medium wp-image-629 aligncenter" title="A push notification" src="http://www.hollance.com/wp-content/uploads/2011/05/I-am-Push-300x159.png" alt="A push notification" width="180" height="95" /></a></p>
<p style="text-align: left;">My first tutorial is now up on his site: <a href="http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12">Apple Push Notification Services Tutorial: Part 1/2</a>. Because it&#8217;s very long we split it up into two parts.</p>
<p>Part 1 introduces the Apple Push Notification Service (APNS), explains how to make the required SSL certificate and provisioning profile, and shows how to send push notifications to a very simple app.</p>
<p>Part 2, which should be published next week, takes it a step further and creates a chat app that uses push notifications to deliver the messages.</p>
<p>I hope you like the tutorial! If you have any questions about push or the tutorial, then let me know in <a href="http://www.raywenderlich.com/forums//viewtopic.php?f=2&amp;t=380">Ray&#8217;s forums</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/05/apple-push-notification-services-tutorial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/05/apple-push-notification-services-tutorial/</feedburner:origLink></item>
		<item>
		<title>Making Your Classes Talk to Each Other, Part 3</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/3PMomo0infQ/</link>
		<comments>http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-3/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 15:02:44 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=600</guid>
		<description><![CDATA[This is the third part of a three-part tutorial for beginning iOS programmers on how to make classes, especially view controllers, communicate with each other. See also Part 1 and Part 2. Version 7: Refinements In this chapter we&#8217;ll make some refinements to the code and implement missing features. First, I will show you a [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the third part of a three-part tutorial for beginning iOS programmers on how to make classes, especially view controllers, communicate with each other. See also <a href="http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-1/">Part 1</a> and <a href="http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-2/">Part 2</a>.</em></p>
<h3>Version 7: Refinements</h3>
<p>In this chapter we&#8217;ll make some refinements to the code and implement missing features.</p>
<p>First, I will show you a little trick. Did you know you can create objects of any kind using Interface Builder, not just views? We can use that to our advantage and save on some code in the application delegate. In the last chapter we added several new properties in order to be able to hook up the <code>DataModel</code> object to both our view controllers. Well, we can do all of that inside Interface Builder without having to write any code!<span id="more-600"></span></p>
<p>Let&#8217;s strip out the soon-to-be-unnecessary stuff from <code>SmoothieAppDelegate.h</code>:</p>

<div class="wp_codebox"><table><tr id="p60033"><td class="code" id="p600code33"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">//@class DataModel;</span>
<span style="color: #11740a; font-style: italic;">//@class SmoothiesViewController;</span>
<span style="color: #11740a; font-style: italic;">//@class FavoritesViewController;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> SmoothiesAppDelegate <span style="color: #002200;">:</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/"><span style="color: #400080;">NSObject</span></a> 
<span style="color: #002200;">&#123;</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> IBOutlet UIWindow<span style="color: #002200;">*</span> window;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> IBOutlet UITabBarController<span style="color: #002200;">*</span> tabBarController;
<span style="color: #11740a; font-style: italic;">//@property (nonatomic, retain) IBOutlet SmoothiesViewController* smoothiesViewController;</span>
<span style="color: #11740a; font-style: italic;">//@property (nonatomic, retain) IBOutlet FavoritesViewController* favoritesViewController;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">//@property (nonatomic, retain) DataModel* dataModel;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>That&#8217;s right, we&#8217;re changing it back to what it was before. Likewise for <code>SmoothieAppDelegate.m</code>.</p>
<p>Now open up <code>MainWindow.xib</code> and drag an Object from the library into the Objects list. We are putting it at the top level; it is not a subview of our Tab Bar Controller. Then we change its class name to <code>DataModel</code>. That&#8217;s it, a new <code>DataModel</code> instance will now be created when the main window&#8217;s nib is loaded.</p>
<p>We connect this <code>DataModel</code> object to the outlets of both <code>SmoothiesViewController</code> and <code>FavoritesViewController</code>. This will only work if we declare those properties as <code>IBOutlets</code>, otherwise Interface Builder will not recognize them.</p>

<div class="wp_codebox"><table><tr id="p60034"><td class="code" id="p600code34"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in SmoothiesViewController.h and FavoritesViewController.h:</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, assign<span style="color: #002200;">&#41;</span> IBOutlet DataModel<span style="color: #002200;">*</span> dataModel;</pre></td></tr></table></div>

<p>The nib looks like this:</p>
<div id="attachment_605" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-7-1-MainWindow-nib.png"><img class="size-medium wp-image-605" title="Figure 7-1 MainWindow nib" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-7-1-MainWindow-nib-300x187.png" alt="Figure 7.1. The DataModel object is now part of the nib." width="300" height="187" /></a><p class="wp-caption-text">Figure 7.1. The DataModel object is now part of the nib.</p></div>
<p>You may be wondering which object now owns the <code>DataModel</code> instance. After all, both <code>SmoothiesViewController</code> and <code>FavoritesViewController</code> have an “assign” property, not “retain”, and we don&#8217;t retain the object anywhere else.</p>
<p>We&#8217;re relying on the fact that when a nib is loaded, all its objects are automatically instantiated and retained. Because the main window will be around as long as the app is running, so will the objects from this nib. So in effect, the File&#8217;s Owner of the <code>MainWindow.nib</code>, <code>UIApplication</code>, is now the owner of <code>DataModel</code>.</p>
<p>Interface Builder is essentially just a tool that allows you to create and configure objects and then freeze them. When the nib is loaded into the app, the objects are “unfrozen” and become alive again. It saves a bunch of typing, so I like to use it for this purpose as much as possible, even with objects that aren&#8217;t really part of the user interface.</p>
<h3>Improving the Favorites screen</h3>
<p>There are a fewer other things in our app that bug me. The Favorites screen always reloads the contents of its table when its view is about to appear. I&#8217;d like to get rid of this code:</p>

<div class="wp_codebox"><table><tr id="p60035"><td class="code" id="p600code35"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>viewWillAppear<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>animated
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>super viewWillAppear<span style="color: #002200;">:</span>animated<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self.tableView reloadData<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>It works, but it&#8217;s not very subtle. Instead, I&#8217;d like to reload the table only when something has actually changed. Currently that is when the user marks or unmarks a recipe as a favorite from the Recipe Details screen.</p>
<p>So we have to find some way to make the Recipe Details screen communicate with the <code>FavoritesViewController</code>. There are several ways to do this. We could give the <code>RecipeDetailsViewController</code> a reference to the <code>FavoritesViewController</code>, but that introduces a tight coupling between two classes that aren&#8217;t really related to each other. So let&#8217;s find a better way.</p>
<p>We could make a delegate like this:</p>

<div class="wp_codebox"><table><tr id="p60036"><td class="code" id="p600code36"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@protocol</span> RecipeDetailsDelegate 
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>addedToFavorites<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Recipe<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>recipe;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>removedFromFavorites<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Recipe<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>recipe;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p><code>FavoritesViewController</code> could implement this delegate. Now <code>RecipeDetailsViewController</code> invokes the <code>addedToFavorites</code> or <code>removedFromFavorites</code> methods on that delegate whenever the user taps the “Favorite” button for a recipe.</p>
<p>This is a better approach because the Recipe Details screen no longer directly needs to know about the <code>FavoritesViewController</code>, just that it has “some” delegate, but the <code>FavoritesViewController</code> still needs to know about the Recipe Details screen because it implements its delegate protocol. So this is not an ideal solution either.</p>
<p>Maybe you&#8217;re thinking we could make a <code>DataModelDelegate</code> instead. Because the data model is ultimately responsible for adding and removing the favorites, it could notify a delegate about about these changes. Possible, but what if we have more than one screen that needs to be notified when a recipe is added to the favorites? <code>DataModel</code> would then need to keep a list of delegate objects and notify them all.</p>
<p>There is a way to completely decouple the sending of notifications when something changes and listening for such notifications, and that is to use <code>NSNotificationCenter</code>.</p>
<p>Add the following to <code>DataModel.h</code>:</p>

<div class="wp_codebox"><table><tr id="p60037"><td class="code" id="p600code37"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">extern</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> <span style="color: #a61390;">const</span> FavoritesChangedNotification;</pre></td></tr></table></div>

<p>This lets any users of the <code>DataModel</code> class know there is now a global string constant named <code>FavoritesChangedNotification</code>. They don&#8217;t care what the actual value of the string is, just that they can subscribe to a notification with this identifier.</p>
<p>In <code>DataModel.m</code>, we add the actual definition:</p>

<div class="wp_codebox"><table><tr id="p60038"><td class="code" id="p600code38"><pre class="objc" style="font-family:monospace;"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> <span style="color: #a61390;">const</span> FavoritesChangedNotification <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Smoothies-FavoritesChanged&quot;</span>;</pre></td></tr></table></div>

<p>We will send this notification whenever a recipe is added or removed:</p>

<div class="wp_codebox"><table><tr id="p60039"><td class="code" id="p600code39"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in DataModel.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>addToFavorites<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Recipe<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>recipe
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>self.favorites addObject<span style="color: #002200;">:</span>recipe.name<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> setObject<span style="color: #002200;">:</span>self.favorites forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Favorites&quot;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> synchronize<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Let any listeners know the list of favorites has changed</span>
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/"><span style="color: #400080;">NSNotificationCenter</span></a> defaultCenter<span style="color: #002200;">&#93;</span> postNotificationName<span style="color: #002200;">:</span>FavoritesChangedNotification object<span style="color: #002200;">:</span>self<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>removeFromFavorites<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Recipe<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>recipe
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>self.favorites removeObject<span style="color: #002200;">:</span>recipe.name<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> setObject<span style="color: #002200;">:</span>self.favorites forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Favorites&quot;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> synchronize<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Let any listeners know the list of favorites has changed</span>
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/"><span style="color: #400080;">NSNotificationCenter</span></a> defaultCenter<span style="color: #002200;">&#93;</span> postNotificationName<span style="color: #002200;">:</span>FavoritesChangedNotification object<span style="color: #002200;">:</span>self<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Because this is only a simple app, this notification doesn&#8217;t provide much more information than “the list of favorites has changed”. We don&#8217;t say how it has changed, i.e. what was added or removed. This simple notification is sufficient for our purposes, but for a more complex app you may want to send more detailed information along with your notifications. There is a version of <code>postNotification</code> that allows you to add an <code>NSDictionary</code> with any additional data you want.</p>
<p>Now, whenever the user taps the Favorite button in the Recipe Details screen, the <code>DataModel</code> sends out a notification. It doesn&#8217;t care who receives that notification. It just broadcasts a message that says: “Something happened to my list of favorites. Do with it what you want. Or not. It&#8217;s up to you.”</p>
<p>Of course, this won&#8217;t do us much good if we&#8217;re not listening for this message, so add the following to <code>FavoritesViewController.m</code>:</p>

<div class="wp_codebox"><table><tr id="p60040"><td class="code" id="p600code40"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>viewDidLoad
<span style="color: #002200;">&#123;</span>
	...
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Start listening for notifications</span>
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/"><span style="color: #400080;">NSNotificationCenter</span></a> defaultCenter<span style="color: #002200;">&#93;</span> addObserver<span style="color: #002200;">:</span>self
		selector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>favoritesChanged<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span>
		name<span style="color: #002200;">:</span>FavoritesChangedNotification
		object<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>viewDidUnload
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>super viewDidUnload<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Stop listening for notifications</span>
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/"><span style="color: #400080;">NSNotificationCenter</span></a> defaultCenter<span style="color: #002200;">&#93;</span> removeObserver<span style="color: #002200;">:</span>self
		name<span style="color: #002200;">:</span>FavoritesChangedNotification
		object<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>dealloc
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Stop listening for notifications</span>
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/"><span style="color: #400080;">NSNotificationCenter</span></a> defaultCenter<span style="color: #002200;">&#93;</span> removeObserver<span style="color: #002200;">:</span>self
		name<span style="color: #002200;">:</span>FavoritesChangedNotification
		object<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #002200;">&#91;</span>super dealloc<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>As soon as our view is loaded, we tell the <code>NSNotificationCenter</code> that we are interested in the <code>FavoriteChangedNotification</code> message and that it should call our <code>favoritesChanged:</code> method whenever such a notification is received.</p>
<p>Because we are good citizens, we also tell the <code>NSNotificationCenter</code> when we no longer wish to receive those notifications. Otherwise it might send a notification to a deallocated object and that will crash the app. (Although in our app the <code>FavoritesViewController</code> is never actually deallocated; it sticks around for as long as the app runs.)</p>
<p>That leaves us to implement the <code>favoritesChanged</code> method. It is really simple:</p>

<div class="wp_codebox"><table><tr id="p60041"><td class="code" id="p600code41"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in FavoritesViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>favoritesChanged<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNotification_Class/"><span style="color: #400080;">NSNotification</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>notification
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>self.tableView reloadData<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>When you run the app and mark a recipe as favorite, then the Favorites list should immediately update to reflect this change.</p>
<h3>A bug!</h3>
<p>The changes we&#8217;ve made so far have actually introduced a bug into our app. What happens when you delete a smoothie that is also a favorite? Previously, the Favorites screen would always reload its contents when you switched to it, so any deleted smoothies would simply no longer show up. Now, however, we only refresh the Favorites screen when a recipe is “favorited” or “unfavorited”, but not when it is removed.</p>
<p>The solution is to also remove the recipe from the list of favorites, which will send a <code>FavoritesChangedNotification</code> and neatly solve the problem for us.</p>

<div class="wp_codebox"><table><tr id="p60042"><td class="code" id="p600code42"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in DataModel.m</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>removeRecipeAtIndex<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>index
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Also remove the recipe from the list of favorites</span>
	Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self recipeAtIndex<span style="color: #002200;">:</span>index<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self removeFromFavorites<span style="color: #002200;">:</span>recipe<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #002200;">&#91;</span>self.recipes removeObjectAtIndex<span style="color: #002200;">:</span>index<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<h3>Sorting the favorites</h3>
<p>There is one more tweak I would like to make. So far the favorites screen has listed the smoothies in the order that you clicked on their &#8220;Favorite&#8221; button. For some apps that might make sense, but for our app it&#8217;s nicer if we sort them alphabetically.</p>
<p>Since we store the names of the recipes in the favorites array, we can simply sort this array before we store it in <code>NSUserDefaults</code>. Change <code>DataModel</code>&#8216;s <code>addToFavorites</code> to:</p>

<div class="wp_codebox"><table><tr id="p60043"><td class="code" id="p600code43"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in DataModel.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>addToFavorites<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Recipe<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>recipe
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>self.favorites addObject<span style="color: #002200;">:</span>recipe.name<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Sort the list by recipe name</span>
	<span style="color: #002200;">&#91;</span>self.favorites sortUsingSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>localizedCaseInsensitiveCompare<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> setObject<span style="color: #002200;">:</span>self.favorites forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Favorites&quot;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> synchronize<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Let any listeners know the list of favorites has changed</span>
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/"><span style="color: #400080;">NSNotificationCenter</span></a> defaultCenter<span style="color: #002200;">&#93;</span> postNotificationName<span style="color: #002200;">:</span>FavoritesChangedNotification object<span style="color: #002200;">:</span>self<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Every time a recipe is added, we sort the list with <code>sortUsingSelector</code>. This takes a selector as its argument, which is a method on the <code>NSString</code> class because our list of favorites contains string objects. That&#8217;s all we have to do to sort the list.</p>
<p>We&#8217;ve seen how you can use notifications to communicate between controllers. Notifications are great for when you want to keep the different parts of your code completely isolated from each other (a good practice to strive for). Sometimes, however, a tighter coupling using delegates is unavoidable and we&#8217;ll see how that works in the next chapter.</p>
<p><a href="https://github.com/hollance/Smoothies/tree/master/Version%207">Download the source code for version 7</a></p>
<h3>Version 8: Adding and editing recipes</h3>
<p>This chapter introduces the last piece of functionality that I want to add to this app: the ability to add new recipes and edit existing ones. We will use a single view controller for both tasks, <code>EditRecipeViewController</code>. Adding a new recipe and editing an existing recipe are so similar that we only have to write the code once.</p>
<p>Let&#8217;s build the screen in Interface Builder:</p>
<div id="attachment_606" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-8-2-EditRecipeViewController-nib.png"><img class="size-medium wp-image-606" title="Figure 8-1 EditRecipeViewController nib" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-8-2-EditRecipeViewController-nib-300x187.png" alt="Figure 8.1. The EditRecipeViewController.xib design." width="300" height="187" /></a><p class="wp-caption-text">Figure 8.1. The EditRecipeViewController.xib design.</p></div>
<p>This screen has a navigation bar with two buttons: Cancel and Save. These buttons are hooked up to actions that will dismiss the screen. More about these later.</p>
<p>I only added a text field for the name and a button that lets you choose a photo, but no entry box for the instructions. The reason for this is that I wanted to keep this tutorial focused on how this new view controller interacts with the rest of our classes, not turn it into a tutorial on how to actually build these screens.</p>
<p>The problem is that we would place the text view for the instructions at the bottom of the screen. When you tap into this text view, the keyboard slides on top of it and then you can no longer see what you&#8217;re typing. There are several ways to solve this issue, but that&#8217;s the topic for another tutorial. So for now I&#8217;ve kept it simple and simply left out this text view.</p>
<p>In Interface Builder, the title of the navigation bar is “Add Recipe”. When we&#8217;re editing an existing recipe, we&#8217;ll change that to “Edit Recipe”, but we do that in code. That is one of the very few differences between adding new recipes and editing existing ones, and it&#8217;s not worth building a totally new class for. From now on, I&#8217;ll simply refer to this screen as the Edit Recipe screen, whether we&#8217;re adding a new recipe or editing an existing one.</p>
<p>To allow the user to add new recipes, I have added a “+” button to the navigation bar of the Smoothies screen, and hooked it up to the <code>addRecipe</code> action:</p>

<div class="wp_codebox"><table><tr id="p60044"><td class="code" id="p600code44"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in SmoothiesViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>addRecipe
<span style="color: #002200;">&#123;</span>
	EditRecipeViewController<span style="color: #002200;">*</span> controller <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>EditRecipeViewController alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self presentModalViewController<span style="color: #002200;">:</span>controller animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>controller release<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Here we create the controller and then present it modally so it will cover the whole screen. As long as the user is interacting with this screen, the rest of the app is inaccessible. The user must press Cancel or Save to close this modal screen and return to the app.</p>
<p>We do something similar in the <code>RecipeDetailsViewController</code>. Its navigation bar now has an Edit button that is hooked up to an <code>IBAction</code> that opens the Edit Recipe screen. (Open <code>RecipeDetailsViewController.xib</code> to see how I added this Edit button.)</p>
<p>I won&#8217;t explain everything that <code>EditRecipeViewController</code> does. Suffice it to say that it opens a <code>UIImagePickerController</code> that lets you choose a photo from the phone&#8217;s photo library, and that it presents a keyboard that lets you type a name for the recipe.</p>
<h3>Our own delegate</h3>
<p>The interesting question is, how can we get the new recipe into our list of smoothies? The answer: using a delegate. The Edit Recipe screen works totally by itself. It is not dependent on any other part of our program, and that is done on purpose.</p>
<p>As I have explained several times before in this tutorial, it is good design to structure each of your classes so they can work in isolation. This keeps the implementation details of that class limited to itself, which avoids your code from becoming a tangled up mess.</p>
<p>No one else should care about how Edit Recipe does its job. We give it some data to work on, and we either get notified through the delegate that the user made changes and tapped Save, or tapped Cancel.</p>
<p>The delegate protocol for <code>EditRecipeViewController</code> looks like this:</p>

<div class="wp_codebox"><table><tr id="p60045"><td class="code" id="p600code45"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in EditRecipeViewController.h:</span>
<span style="color: #a61390;">@protocol</span> EditRecipeDelegate 
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>editRecipeDidSave<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>EditRecipeViewController<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>controller;
@optional
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>editRecipeDidCancel<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>EditRecipeViewController<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>controller;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>When the user taps Save, we call the delegate&#8217;s <code>editRecipeDidSave:</code> method. When the user taps Cancel, we call the delegate&#8217;s <code>editRecipeDidCancel:</code> method. This last method is optional, which means the delegate does not have to implement it. This is all <code>EditRecipeViewController</code> knows about the outside world; there is some object that is its delegate, and it will call that delegate to inform it about changes.</p>
<p>When we&#8217;re adding a new recipe, the delegate is <code>SmoothiesViewController</code>, because that is the screen that we launch the Edit Recipe screen from. The <code>addRecipe</code> action now looks like this:</p>

<div class="wp_codebox"><table><tr id="p60046"><td class="code" id="p600code46"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in SmoothiesViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>addRecipe
<span style="color: #002200;">&#123;</span>
	EditRecipeViewController<span style="color: #002200;">*</span> controller <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>EditRecipeViewController alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	controller.delegate <span style="color: #002200;">=</span> self;
	<span style="color: #002200;">&#91;</span>self presentModalViewController<span style="color: #002200;">:</span>controller animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>controller release<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>The line <code>controller.delegate = self;</code> is new. It lets the <code>EditRecipeViewController know</code> that we&#8217;re now going to want to receive the “didSave” and (optionally) “didCancel” messages.</p>
<p>When we&#8217;re editing an existing recipe, the delegate will be the <code>RecipeDetailsViewController</code>. So here we have two completely different controllers, but because they both adhere to the <code>EditRecipeDelegate</code> protocol the Edit Recipe screen can talk to them both, without having to know anything else about them.</p>
<h3>Data in and out</h3>
<p>The other part of the puzzle is getting data into and out of <code>EditRecipeViewController</code>. To achieve this, I have added two properties to this class:</p>

<div class="wp_codebox"><table><tr id="p60047"><td class="code" id="p600code47"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in EditRecipeViewController.h:</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, copy<span style="color: #002200;">&#41;</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> name;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, copy<span style="color: #002200;">&#41;</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> instructions;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIImage<span style="color: #002200;">*</span> image;</pre></td></tr></table></div>

<p>These correspond to the attributes of the <code>Recipe</code> we&#8217;re editing. If we are adding a new recipe, then these are left to their default nil values. But when editing an existing recipe, we copy the <code>Recipe</code>&#8216;s name, instructions and image into these properties, like so:</p>

<div class="wp_codebox"><table><tr id="p60048"><td class="code" id="p600code48"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in RecipeDetailsViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>editRecipe
<span style="color: #002200;">&#123;</span>
	EditRecipeViewController<span style="color: #002200;">*</span> controller <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>EditRecipeViewController alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	controller.delegate <span style="color: #002200;">=</span> self;
	controller.name <span style="color: #002200;">=</span> self.recipe.name;
	controller.instructions <span style="color: #002200;">=</span> self.recipe.instructions;
	controller.image <span style="color: #002200;">=</span> self.recipe.image;
	<span style="color: #002200;">&#91;</span>self presentModalViewController<span style="color: #002200;">:</span>controller animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>controller release<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>When you press Save on the Edit Recipe screen, the <code>editRecipeDidSave:</code> method is called on the delegate. The delegate can now look at <code>controller.name</code>, <code>controller.instructions</code> and <code>controller.image</code> to get the new values of the recipe.</p>
<p>That&#8217;s exactly what we do in both <code>SmoothiesViewController</code> and <code>RecipeDetailsViewController</code>, although in the former we add a completely new <code>Recipe</code> object to the <code>DataModel</code> while in the latter we just change the properties of the existing object.</p>

<div class="wp_codebox"><table><tr id="p60049"><td class="code" id="p600code49"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in SmoothiesViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>editRecipeDidSave<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>EditRecipeViewController<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>controller
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Create a new Recipe object with the values from the controller</span>
	<span style="color: #11740a; font-style: italic;">// and add it to the data model</span>
	Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>Recipe alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	recipe.name <span style="color: #002200;">=</span> controller.name;
	recipe.instructions <span style="color: #002200;">=</span> controller.instructions;
	recipe.image <span style="color: #002200;">=</span> controller.image;
	<span style="color: #002200;">&#91;</span>self.dataModel addRecipe<span style="color: #002200;">:</span>recipe<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>recipe release<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Refresh the table</span>
	<span style="color: #002200;">&#91;</span>self.tableView reloadData<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// in RecipeDetailsViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>editRecipeDidSave<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>EditRecipeViewController<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>controller
<span style="color: #002200;">&#123;</span>
	self.recipe.name <span style="color: #002200;">=</span> controller.name;
	self.recipe.instructions <span style="color: #002200;">=</span> controller.instructions;
	self.recipe.image <span style="color: #002200;">=</span> controller.image;
	<span style="color: #002200;">&#91;</span>self updateControls<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>The call to <code>[self updateControls]</code> will update the label and button with the new name and image of the recipe. And that&#8217;s the way we do it.</p>
<p>Now, why don&#8217;t I simply pass a <code>Recipe</code> object to <code>EditRecipeViewController</code>? That is after all what we do with <code>RecipeDetailsViewController</code></p>
<p>Think about this: If you pass in a <code>Recipe</code> object and the user changes the name, then the name of the <code>Recipe</code> is immediately updated. But what if the user cancels? Then we have to find some way to put back the original name in the <code>Recipe</code> object, so either we have to keep a copy of the original values around or do our modifications in a copy of the actual <code>Recipe</code> object. Too much hassle for my taste.</p>
<h3>Propagating the changes</h3>
<p>One more thing to cover: if you rename a recipe, then any screen that displays that recipe also has to be updated. So far we&#8217;ve only updated the controls in the Recipe Details screen, but we also need to update the Smoothies screen and maybe also the Favorites screen. Despair not, we&#8217;ve faced a similar situation before and dealt with it using a notification.</p>
<p>This, however, highlights another problem. Because we store favorites by name, changing the name of a recipe messes up our favorites because one of them now refers to a recipe that no longer exists. Yikes. It gets worse, what will happen when the user gives two smoothies the same name?</p>
<p>It is probably a good idea to reconsider using the recipe names as their unique identifier, now that the names can be changed by the user. Fortunately, because we have hidden how favorites are implemented inside of <code>DataModel</code>, we only have to change the <code>DataModel</code> class. None of our other classes is impacted by this change.</p>
<p>You can see in the code what I changed, but to summarize I added a <code>recipeId</code> property to the <code>Recipe</code> class. This is an integer. We now store those integers instead of the recipe names in the <code>NSUserDefaults</code>. (I changed the key under which they are stored to @”Favorites2” so the app won&#8217;t crash if you&#8217;re installing it on top of one of the previous versions.) The only tricky thing is assigning an ID to new recipes, but that&#8217;s something we can neatly tuck away inside <code>DataModel</code>.</p>
<p>Finally, we tell <code>DataModel</code> that the recipe was updated. It will send out the new <code>RecipesChangedNotification</code>. Both the <code>SmoothiesViewController</code> and <code>FavoritesViewController</code> listen for this notification and reload their tables in response.</p>

<div class="wp_codebox"><table><tr id="p60050"><td class="code" id="p600code50"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in RecipeDetailsViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>editRecipeDidSave<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>EditRecipeViewController<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>controller
<span style="color: #002200;">&#123;</span>
	self.recipe.name <span style="color: #002200;">=</span> controller.name;
	self.recipe.instructions <span style="color: #002200;">=</span> controller.instructions;
	self.recipe.image <span style="color: #002200;">=</span> controller.image;
	<span style="color: #002200;">&#91;</span>self updateControls<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self.dataModel didChangeRecipe<span style="color: #002200;">:</span>self.recipe<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<h3>A new way to sort</h3>
<p>Because we no longer store favorites by name, we cannot sort the favorites list by name any more either. Let&#8217;s change the way <code>DataModel</code> exposes the favorites list to the outside:</p>

<div class="wp_codebox"><table><tr id="p60051"><td class="code" id="p600code51"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in DataModel.h:</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, readonly, retain<span style="color: #002200;">&#41;</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a><span style="color: #002200;">*</span> sortedFavorites;
&nbsp;
<span style="color: #11740a; font-style: italic;">//- (Recipe*)favoriteAtIndex:(int)index;</span></pre></td></tr></table></div>

<p>We added a property and got rid of the <code>favoriteAtIndex:</code> method. Any class that wishes to use the list of favorites can now only get an immutable array using the <code>sortedFavorites</code> property that is guaranteed to be sorted by name.</p>
<p>Inside <code>DataModel.m</code> it works like this:</p>

<div class="wp_codebox"><table><tr id="p60052"><td class="code" id="p600code52"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>sortedFavorites
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>sortedFavorites <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>  <span style="color: #11740a; font-style: italic;">// lazy loading</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #11740a; font-style: italic;">// Add the Recipe objects to a new list</span>
		self.sortedFavorites <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/"><span style="color: #400080;">NSMutableArray</span></a> arrayWithCapacity<span style="color: #002200;">:</span>favorites.count<span style="color: #002200;">&#93;</span>;
		<span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a><span style="color: #002200;">*</span> number <span style="color: #a61390;">in</span> self.favorites<span style="color: #002200;">&#41;</span>
		<span style="color: #002200;">&#123;</span>
			<span style="color: #a61390;">int</span> recipeId <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>number intValue<span style="color: #002200;">&#93;</span>;
			Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self findRecipeWithId<span style="color: #002200;">:</span>recipeId<span style="color: #002200;">&#93;</span>;
			<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>recipe <span style="color: #002200;">!=</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>
			<span style="color: #002200;">&#123;</span>
				<span style="color: #002200;">&#91;</span>sortedFavorites addObject<span style="color: #002200;">:</span>recipe<span style="color: #002200;">&#93;</span>;
			<span style="color: #002200;">&#125;</span>
		<span style="color: #002200;">&#125;</span>
&nbsp;
		<span style="color: #11740a; font-style: italic;">// Sort the list by last name</span>
		<span style="color: #002200;">&#91;</span>sortedFavorites sortUsingSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>compareName<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
	<span style="color: #a61390;">return</span> sortedFavorites;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>We use a technique called “lazy loading” to make this as efficient as possible. The very first time this method is called, we make a new <code>NSMutableArray</code> array object and fill it up with the <code>Recipe</code> objects whose ID&#8217;s are in the favorites list. Then we sort that array (the selector <code>compareName:</code> is a method that I added to <code>Recipe</code>). From then on, we always return a reference to that array.</p>
<p>The trick is that we set <code>sortedFavorites</code> to nil whenever we change the recipes list or the favorites list. The next time this method is called, the sorted array will be generated anew. There are other ways to accomplish the same thing (directly changing <code>sortedFavorites</code> when we add or remove a favorite may be faster), but I wanted to illustrate how to use lazy loading in this context.</p>
<p>I&#8217;ll leave re-sorting the list in the main Smoothies screen as an exercise for the reader. <img src='http://www.hollance.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>As you can tell, our code has become complex rather quickly. We now have several different screens that all influence each other. By keeping them as self-contained as possible, we can keep our code manageable. But we cannot escape the use of some kind of notification mechanism to update everyone when things change.</p>
<p>Our final class structure looks like this:</p>
<div id="attachment_607" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-8-3-Class-structure.png"><img class="size-medium wp-image-607" title="Figure 8-2 Class structure" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-8-3-Class-structure-300x126.png" alt="Figure 8.2. We added the EditRecipeViewController." width="300" height="126" /></a><p class="wp-caption-text">Figure 8.2. We added the EditRecipeViewController.</p></div>
<p>That&#8217;s it for this tutorial. I might do another chapter later that illustrates how to use Core Data as your data model instead of rolling your own like we did.</p>
<p><a href="https://github.com/hollance/Smoothies/tree/master/Version%208">Download the source code for version 8</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-3/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-3/</feedburner:origLink></item>
		<item>
		<title>Making Your Classes Talk to Each Other, Part 2</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/LeGjoN-MRvo/</link>
		<comments>http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-2/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 13:43:02 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=580</guid>
		<description><![CDATA[This is the second part of a three-part tutorial for beginning iOS programmers on how to make classes, especially view controllers, communicate with each other. See also Part 1 and Part 3. Version 4: Deleting smoothies Often in a screen that has a table view, you are able to delete items by swiping a row [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the second part of a three-part tutorial for beginning iOS programmers on how to make classes, especially view controllers, communicate with each other. See also <a href="http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-1/">Part 1</a> and <a href="http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-3/">Part 3</a>.</em></p>
<h3>Version 4: Deleting smoothies</h3>
<p>Often in a screen that has a table view, you are able to delete items by swiping a row or by tapping an Edit button in the navigation bar. Let&#8217;s add “swipe to delete” to our list of smoothies. (In a later chapter we&#8217;ll also add a way to create new smoothies.)</p>
<p>Swipe-to-delete is activated by a <code>UITableViewDataSource</code> method:</p>

<div class="wp_codebox"><table><tr id="p58085"><td class="code" id="p580code85"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theTableView
	commitEditingStyle<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableViewCellEditingStyle<span style="color: #002200;">&#41;</span>editingStyle
	forRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>If you just add this method to <code>SmoothiesViewController.m</code>, even though it doesn&#8217;t do anything yet, then swiping the row in the table will make the red Delete button appear.<span id="more-580"></span></p>
<div id="attachment_586" class="wp-caption aligncenter" style="width: 169px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-4-1-Swipe-to-delete.png"><img class="size-medium wp-image-586" title="Figure 4-1 Swipe-to-delete" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-4-1-Swipe-to-delete-159x300.png" alt="Figure 4.1. Swipe-to-delete in action." width="159" height="300" /></a><p class="wp-caption-text">Figure 4.1. Swipe-to-delete in action.</p></div>
<p>The <code>commitEditingStyle</code> method is called when the user actually presses the Delete button. Two things need to happen then: 1) we must remove the <code>Recipe</code> in question from our data model; 2) we must tell the table view to remove the row.</p>
<p>This is how we do that:</p>

<div class="wp_codebox"><table><tr id="p58086"><td class="code" id="p580code86"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in SmoothiesViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theTableView
	commitEditingStyle<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableViewCellEditingStyle<span style="color: #002200;">&#41;</span>editingStyle
	forRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Remove the Recipe from our data model (the list of recipes)</span>
	<span style="color: #002200;">&#91;</span>self.recipes removeObjectAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Remove the row from the table with an animation</span>
	<span style="color: #002200;">&#91;</span>theTableView deleteRowsAtIndexPaths<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a> arrayWithObject<span style="color: #002200;">:</span>indexPath<span style="color: #002200;">&#93;</span> withRowAnimation<span style="color: #002200;">:</span>UITableViewRowAnimationFade<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Very simple and it looks pretty good too. Note that the recipes aren&#8217;t gone forever. The next time you start the app, they are back again. That is because we always create a new list of recipes when the <code>SmoothiesViewController</code> is loaded.</p>
<h3>The DataModel class</h3>
<p>I want to make a fundamental change now to the app. So far when we&#8217;ve talked about the data model, it concerned two items: the <code>Recipe</code> class, which describes a single recipe, and the <code>NSMutableArray</code> that contains a list of those <code>Recipe</code> objects.</p>
<p>In <code>SmoothiesViewController</code>, we often use <code>self.recipes</code> directly: when the controller is loaded, we add several <code>Recipe</code> objects into this list; the table view data source loads the cells from this list; and now the swipe-to-delete method removes items directly from this list.</p>
<p>So far it has been manageable, but now I want to abstract away these operations and hide the list. To that end, we&#8217;ll make a new class named <code>DataModel</code>. This is our top-level data model class. For the time being it will just have the list of recipes, but in later chapters we&#8217;ll give it more responsibilities.</p>
<p>What should the DataModel class do?</p>
<ul>
<li>It owns the list of recipes.</li>
<li>It is able to tell how many recipes are in the list. We need this for the table view data source so it knows how many rows there are in the table.</li>
<li>It can return a <code>Recipe</code> object at a specific position in the list. Also needed for the table view.</li>
<li>It can delete a <code>Recipe</code> from the list.</li>
</ul>
<p>I used Xcode&#8217;s New File wizard to create an Objective-C class that is a subclass of <code>NSObject</code> and named it <code>DataModel</code>. In <code>DataModel.h</code>, I added methods for the tasks we outlined above:</p>

<div class="wp_codebox"><table><tr id="p58087"><td class="code" id="p580code87"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@class</span> Recipe;
&nbsp;
<span style="color: #a61390;">@interface</span> DataModel <span style="color: #002200;">:</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/"><span style="color: #400080;">NSObject</span></a>
<span style="color: #002200;">&#123;</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Returns how many recipes are in the list.</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>recipeCount;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Returns the Recipe object at the specified position in the list.</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>Recipe<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>recipeAtIndex<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>index;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Deletes a Recipe object from the list.</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>removeRecipeAtIndex<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>index;
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>We already have the code for these methods because <code>SmoothiesViewController</code> already does these things. So I was able to cut-and-paste a bunch of code from <code>SmoothiesViewController</code> to <code>DataModel.m</code>.</p>
<p>At this point, <code>DataModel</code> does no more than what <code>NSMutableArray</code> does. The advantage is that it hides from <code>SmoothiesViewController</code> (and anyone else) the fact that it uses an <code>NSMutableArray</code> underneath. In fact, it does a lot less than <code>NSMutableArray</code> and that&#8217;s exactly what we want. You can&#8217;t modify the list of recipes unless <code>DataModel</code> has a method for it. This encapsulation and abstraction makes our code more robust. We already talked a bit about this in the previous chapter.</p>
<p>That <code>DataModel</code> uses an <code>NSMutableArray</code> is a so-called “implementation detail”. It&#8217;s important to the implementation of <code>DataModel</code>, but not to anyone who uses <code>DataModel</code>. It&#8217;s a good strategy to hide implementation details from the rest of your code. Always ask yourself: is this something I can hide in my class because no one needs to know about it?</p>
<h3>Private properties</h3>
<p>Note that <code>DataModel</code>&#8216;s <code>@interface</code> does not have an <code>NSMutableArray</code> property or even instance variable. Then where do we keep the list of recipes? I used a trick called a “class extension” for this.</p>
<p>Maybe you&#8217;re familiar with the concept of Objective-C&#8217;s categories. A category lets you add new methods to an existing class, which can be very convenient. A class extension is like that, although you use it in your .m file only and it allows you to add properties. Because this property is not in your .h file, it&#8217;s private.</p>
<p>Since we don&#8217;t want anyone to know that we use an <code>NSMutableArray</code> to store the list of recipes – or depend on this – we declare it as such a private property at the top of <code>DataModel.m</code>:</p>

<div class="wp_codebox"><table><tr id="p58088"><td class="code" id="p580code88"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Yes, this goes into DataModel.m:</span>
<span style="color: #a61390;">@interface</span> DataModel <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// The list of Recipe objects</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/"><span style="color: #400080;">NSMutableArray</span></a><span style="color: #002200;">*</span> recipes;
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<h3>Simplifying SmoothiesViewController</h3>
<p>If you compare <code>SmoothiesViewController</code> to the previous versions, it&#8217;s now a lot simpler. We moved a lot of the logic into <code>DataModel</code>. Instead of a list of recipes, it now just has a <code>dataModel</code> property.</p>
<p>Where previously we did:</p>

<div class="wp_codebox"><table><tr id="p58089"><td class="code" id="p580code89"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theTableView numberOfRowsInSection<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>section
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Return the number of recipes in our list</span>
	<span style="color: #a61390;">return</span> self.recipes.count;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>We now do:</p>

<div class="wp_codebox"><table><tr id="p58090"><td class="code" id="p580code90"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theTableView numberOfRowsInSection<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>section
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Return the number of recipes in our list</span>
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>self.dataModel recipeCount<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Likewise, swipe-to-delete now becomes:</p>

<div class="wp_codebox"><table><tr id="p58091"><td class="code" id="p580code91"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theTableView commitEditingStyle<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableViewCellEditingStyle<span style="color: #002200;">&#41;</span>editingStyle forRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Remove the Recipe from our data model</span>
	<span style="color: #002200;">&#91;</span>self.dataModel removeRecipeAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Remove the row from the table with an animation</span>
	<span style="color: #002200;">&#91;</span>theTableView deleteRowsAtIndexPaths<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a> arrayWithObject<span style="color: #002200;">:</span>indexPath<span style="color: #002200;">&#93;</span> withRowAnimation<span style="color: #002200;">:</span>UITableViewRowAnimationFade<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>The reason for making this change is that a view controller&#8217;s job isn&#8217;t to manage the data, that is really the job for a separate data model object. The view controller also doesn&#8217;t draw directly on the screen; that is the job for a view. The actual job of the controller is to let the view and the data model talk to each other. That&#8217;s why it is better to separate these jobs into different classes. This keeps everything well-organized.</p>
<p>If this is all our app would do, then using a separate <code>DataModel</code> class instead of managing the list ourselves would be overkill. But we&#8217;ll be adding a whole bunch of new features soon that make having this class indispensable.</p>
<p>The class structure now looks like this:</p>
<div id="attachment_587" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-4-2-Class-structure.png"><img class="size-medium wp-image-587" title="Figure 4-2 Class structure" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-4-2-Class-structure-300x101.png" alt="Figure 4.2. The DataModel class has replaced NSMutableArray. It still uses an NSMutableArray internally to store the Recipe objects, but that is of no concern to the rest of the app." width="300" height="101" /></a><p class="wp-caption-text">Figure 4.2. The DataModel class has replaced NSMutableArray. It still uses an NSMutableArray internally to store the Recipe objects, but that is of no concern to the rest of the app.</p></div>
<p><a href="https://github.com/hollance/Smoothies/tree/master/Version%204">Download the source code for version 4</a></p>
<h3>Version 5: Favorites!</h3>
<p>Let&#8217;s make the app a little more interesting and add a Favorites screen. Even though the current app only has three smoothies and thus hardly needs a new screen to help you keep track of your favorites, this exercise will illustrate a number of important concepts that you&#8217;ll see over and over again in real apps.</p>
<p>When we&#8217;re done the app will look like this:</p>
<div id="attachment_588" class="wp-caption aligncenter" style="width: 169px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-5-1-Tab-Bar.png"><img class="size-medium wp-image-588" title="Figure 5-1 Tab Bar" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-5-1-Tab-Bar-159x300.png" alt="Figure 5.1. We've added a tab bar and a Favorites screen." width="159" height="300" /></a><p class="wp-caption-text">Figure 5.1. We&#39;ve added a tab bar and a Favorites screen.</p></div>
<p>I decided to add a tab bar to the app because that makes it easy to switch between the main list of smoothies and the Favorites screen, and because it&#8217;s a common design for iPhone apps.</p>
<p>Previously, the top-level controller in our window was the navigation controller that held <code>SmoothiesViewController</code>. Now we have to restructure this a little. I added a tab bar controller to the nib and connected that to the <code>SmoothiesAppDelegate</code> (and thus, the window) instead. The navigation controller is then added to the tab bar controller.</p>
<div id="attachment_589" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-5-2-MainWindow-nib.png"><img class="size-medium wp-image-589" title="Figure 5-2 MainWindow nib" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-5-2-MainWindow-nib-300x187.png" alt="Figure 5.2. The new MainWindow.xib" width="300" height="187" /></a><p class="wp-caption-text">Figure 5.2. The new MainWindow.xib</p></div>
<p>The second tab has a navigation controller of its own, which in turn contains the <code>FavoritesViewController</code>. Just like the main Smoothies screen, the Favorites screen is also a list of smoothies, so it also extends from <code>UITableViewController</code>.</p>
<p>There is another user interface problem to solve: how do we let users mark a smoothie as a favorite? For this, I added a button on the Recipe Details screen:</p>
<div id="attachment_590" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-5-3-RecipeDetailsViewController-nib.png"><img class="size-medium wp-image-590" title="Figure 5-3 RecipeDetailsViewController nib" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-5-3-RecipeDetailsViewController-nib-300x187.png" alt="Figure 5.3. The Recipe Details screen now has a “Favorite” toggle button." width="300" height="187" /></a><p class="wp-caption-text">Figure 5.3. The Recipe Details screen now has a “Favorite” toggle button.</p></div>
<p>It will work as a toggle button. Tap it once to mark the recipe as a favorite, tap it again to remove it from the favorites. When the user taps this button, the smoothie will immediately appear in the Favorites screen. If the user changes his mind and taps the button again, the smoothie disappears from the Favorites screen.</p>
<h3>Saving the favorites</h3>
<p>Where and how do we store which smoothies are favorites? There are several ways we could do this. We want to remember these favorites even after the user quits the app, so we must store it in a file somehow and then load the file back in when the app starts again. We could use an XML file, a Plist file, or even an SQLite database. However, there is also the very handy <code>NSUserDefaults</code> class. This class is often used to store user settings and is very convenient to use. It works like a dictionary.</p>
<p>In <code>RecipeDetailsViewController.m</code>, we add the following method:</p>

<div class="wp_codebox"><table><tr id="p58092"><td class="code" id="p580code92"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>favoriteTapped
<span style="color: #002200;">&#123;</span>
	<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a><span style="color: #002200;">*</span> favorites <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Favorites&quot;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>favorites containsObject<span style="color: #002200;">:</span>self.recipe.name<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #11740a; font-style: italic;">// un-favorite this recipe</span>
	<span style="color: #002200;">&#125;</span>
	<span style="color: #a61390;">else</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #11740a; font-style: italic;">// add this recipe to the favorites</span>
	<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>This asks the <code>NSUserDefaults</code> for an object named “Favorites”. That&#8217;s just a name I picked. Because <code>NSUserDefaults</code> works as a dictionary, it stores each object under a key and “Favorites” will be the key for our object. The type of our object is <code>NSArray</code> because it makes sense to store the favorites as an array of names.</p>
<p>After we&#8217;ve obtained our <code>NSArray</code> from <code>NSUserDefaults</code>, the code looks if the name of the current recipe (<code>self.recipe.name</code>) is already in this list. If yes, then we have to un-favorite this recipe. If the recipe wasn&#8217;t in the favorites yet, then we add it.</p>
<p>Hold on a minute&#8230; why do we store a list with just the names of the recipes here and not the entire <code>Recipe</code> object? First of all, we can&#8217;t store our own classes in <code>NSUserDefaults</code>, only standard objects such as arrays and strings. But more importantly, if we stored an entire <code>Recipe</code> object then we would be saving a copy of the object, not the object itself.</p>
<p>Instead, it is better to store something that lets us refer to a <code>Recipe</code> object from the main data model, because that&#8217;s what is being used in the Recipe Details screen. If your data objects have an unique ID, then you could use that. Our recipes don&#8217;t have an ID, but their name is going to be unique so that will work just as well.</p>
<p>You might be tempted to store the pointer to the <code>Recipe</code> object instead. After all, that is going to be unique too and it makes it really easy to find the corresponding <code>Recipe</code> object. But consider what happens when the app exits and is started again. We will have completely new <code>Recipe</code> instances, with new pointers. The pointers that you stored in <code>NSUserDefaults</code> will no longer point to the correct <code>Recipes</code> and your app will most likely crash hard.</p>
<p>So the main data model stores a list of <code>Recipe</code> objects, while the favorites are stored as a list of recipe names. We can use these names to find the corresponding <code>Recipe</code> objects.</p>
<h3>Defaults for the defaults</h3>
<p>There is something else we need to do before we can use the above method. The very first time the app is run, <code>NSUserDefaults</code> does not have anything stored under the key “Favorites” yet. The above code assumes there is always an <code>NSArray</code> there, which is currently not guaranteed. We could solve this problem by checking if the value is nil and then create the array and add it, but there is an easier method.</p>
<p>Add the following to <code>SmoothieAppDelegate.m</code>:</p>

<div class="wp_codebox"><table><tr id="p58093"><td class="code" id="p580code93"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>initialize
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>self class<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> <span style="color: #002200;">&#91;</span>SmoothiesAppDelegate class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/"><span style="color: #400080;">NSDictionary</span></a><span style="color: #002200;">*</span> dict <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/"><span style="color: #400080;">NSDictionary</span></a> dictionaryWithObjectsAndKeys<span style="color: #002200;">:</span>
			<span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a> array<span style="color: #002200;">&#93;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Favorites&quot;</span>,
			<span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
&nbsp;
		<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> registerDefaults<span style="color: #002200;">:</span>dict<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>The initialize method is called when the class is first used. We take advantage of this to set defaults on <code>NSUserDefaults</code>; in this case an empty <code>NSArray</code> for the key “Favorites”. This default value will be used if <code>NSUserDefaults</code> does not contain the key “Favorites” yet. Now we are guaranteed that <code>[objectForKey:@"Favorites"]</code> will return a valid <code>NSArray</code> object.</p>
<p>To add a recipe to the list of favorites, we do:</p>

<div class="wp_codebox"><table><tr id="p58094"><td class="code" id="p580code94"><pre class="objc" style="font-family:monospace;"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/"><span style="color: #400080;">NSMutableArray</span></a><span style="color: #002200;">*</span> newArray <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/"><span style="color: #400080;">NSMutableArray</span></a> arrayWithArray<span style="color: #002200;">:</span>favorites<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>newArray addObject<span style="color: #002200;">:</span>self.recipe.name<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> setObject<span style="color: #002200;">:</span>newArray forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Favorites&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> synchronize<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>

<p>Because the array we received from <code>NSUserDefaults</code> is immutable, we have to create a new array with the contents of the old one and add the recipe&#8217;s name to it. Finally, we put the new array in <code>NSUserDefaults</code>.</p>
<p>Just for good measure, we “synchronize” the <code>NSUserDefaults</code>. This causes the new settings to be written to disk immediately. Calling <code>synchronize</code> isn&#8217;t strictly necessary because <code>NSUserDefaults</code> will sync itself periodically and when the app exits or goes to the background, but not when you exit the app from within Xcode.</p>
<p>Removing a recipe from the favorites works similarly.</p>
<p>Let&#8217;s display the favorites in the Favorites screen, as that&#8217;s what it is there for. In the next chapter we&#8217;ll look at a better solution but for now we&#8217;ll simply read the list of recipe names from <code>NSUserDefaults</code> and show them in the table.</p>
<p>In <code>FavoritesViewController.m</code>:</p>

<div class="wp_codebox"><table><tr id="p58095"><td class="code" id="p580code95"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theTableView numberOfRowsInSection<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>section
<span style="color: #002200;">&#123;</span>
	<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a><span style="color: #002200;">*</span> favorites <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Favorites&quot;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">return</span> favorites.count;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>UITableViewCell<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView cellForRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	...
&nbsp;
	<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a><span style="color: #002200;">*</span> favorites <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Favorites&quot;</span><span style="color: #002200;">&#93;</span>;
	<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> recipeName <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>favorites objectAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>;
&nbsp;
	cell.textLabel.text <span style="color: #002200;">=</span> recipeName;
	<span style="color: #a61390;">return</span> cell;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>We&#8217;ll refresh the table whenever the Favorites screen becomes visible, so if you click the “Favorite” button in the Recipe Details screen and then switch to the Favorites tab, the list is immediately updated with any changes.</p>
<p>Again in <code>FavoritesViewController.m</code>:</p>

<div class="wp_codebox"><table><tr id="p58096"><td class="code" id="p580code96"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>viewWillAppear<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>animated
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>super viewWillAppear<span style="color: #002200;">:</span>animated<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self.tableView reloadData<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>There is one more thing to do. In the Recipe Details screen it would be nice to show whether the recipe is currently a favorite. If it is, we add a checkmark in front of the title, like so:</p>

<div class="wp_codebox"><table><tr id="p58097"><td class="code" id="p580code97"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in RecipeDetailsViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>updateFavoriteButton
<span style="color: #002200;">&#123;</span>
	<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> title;
	<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a><span style="color: #002200;">*</span> favorites <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/"><span style="color: #400080;">NSUserDefaults</span></a> standardUserDefaults<span style="color: #002200;">&#93;</span> objectForKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Favorites&quot;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>favorites containsObject<span style="color: #002200;">:</span>self.recipe.name<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
		title <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;√ Favorite&quot;</span>;
	<span style="color: #a61390;">else</span>
		title <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Favorite&quot;</span>;
&nbsp;
	<span style="color: #002200;">&#91;</span>self.favoriteButton setTitle<span style="color: #002200;">:</span>title forState<span style="color: #002200;">:</span>UIControlStateNormal<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>This method is called whenever we press the button (in <code>favoriteTapped</code>) but also when the Recipe Details screen is loaded, so we set the button in the proper initial state.</p>
<p>The class diagram has become a little bigger now:</p>
<div id="attachment_595" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-5-4-Class-structure.png"><img class="size-medium wp-image-595" title="Figure 5-4 Class structure" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-5-4-Class-structure-300x161.png" alt="Figure 5.4. We've added a tab bar controller and the Favorites view controller." width="300" height="161" /></a><p class="wp-caption-text">Figure 5.4. We&#39;ve added a tab bar controller and the Favorites view controller.</p></div>
<p>To be honest, the implementation of how we store favorites is a little messy. <code>NSUserDefaults</code> really is part of the data model, so in the next chapter we&#8217;ll abstract it away in the <code>DataModel</code> class.</p>
<p><a href="https://github.com/hollance/Smoothies/tree/master/Version%205">Download the source code for version 5</a></p>
<h3>Version 6: Putting the favorites in the data model</h3>
<p>You probably wondered why on earth we were storing stuff directly in <code>NSUserDefaults</code> in the previous chapter. That became kind of messy really quickly. Indeed, a better place to do this is&#8230; in the <code>DataModel</code> class. That is exactly why we have that class. Favorites certainly count as data objects, so their proper place is in <code>DataModel</code>.</p>
<p>These are the tasks that we need to do with our favorites:</p>
<ul>
<li>We need to know how many there are. This is required by the Favorite screen&#8217;s table view.</li>
<li>We need to retrieve the <code>Recipe</code> objects that are marked as favorite. Also for the table view.</li>
<li>Determine whether a <code>Recipe</code> is currently favorite.</li>
<li>Add a new <code>Recipe</code> to the favorites.</li>
<li>Remove a <code>Recipe</code> from the favorites.</li>
</ul>
<p>Let&#8217;s add a method for each of these tasks to <code>DataModel</code>:</p>

<div class="wp_codebox"><table><tr id="p58098"><td class="code" id="p580code98"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>favoritesCount;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>Recipe<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>favoriteAtIndex<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>index;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>isFavorite<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Recipe<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>recipe;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>addToFavorites<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Recipe<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>recipe;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>removeFromFavorites<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>Recipe<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>recipe;</pre></td></tr></table></div>

<p>In order for <code>RecipeDetailsViewController</code> to be able to use this, it needs to know about the <code>DataModel</code> class. So we add a property:</p>

<div class="wp_codebox"><table><tr id="p58099"><td class="code" id="p580code99"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in RecipeDetailsViewController.h:</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, assign<span style="color: #002200;">&#41;</span> DataModel<span style="color: #002200;">*</span> dataModel;</pre></td></tr></table></div>

<p>Now when <code>SmoothiesViewController</code> creates the <code>RecipeDetailsViewController</code> in response to a tap on a row in the table, we assign the data model object to it:</p>

<div class="wp_codebox"><table><tr id="p580100"><td class="code" id="p580code100"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in SmoothiesViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView didSelectRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	RecipeDetailsViewController<span style="color: #002200;">*</span> controller <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>RecipeDetailsViewController alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Assign the data model object to the controller</span>
	controller.dataModel <span style="color: #002200;">=</span> self.dataModel;
&nbsp;
	Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dataModel recipeAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>;
	controller.recipe <span style="color: #002200;">=</span> recipe;
&nbsp;
	<span style="color: #002200;">&#91;</span>self.navigationController pushViewController<span style="color: #002200;">:</span>controller animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>controller release<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>The code for <code>RecipeDetailsViewController</code> is updated to look as follows:</p>

<div class="wp_codebox"><table><tr id="p580101"><td class="code" id="p580code101"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in RecipeDetailsViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>favoriteTapped
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>self.dataModel isFavorite<span style="color: #002200;">:</span>self.recipe<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #002200;">&#91;</span>self.dataModel removeFromFavorites<span style="color: #002200;">:</span>self.recipe<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
	<span style="color: #a61390;">else</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #002200;">&#91;</span>self.dataModel addToFavorites<span style="color: #002200;">:</span>self.recipe<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
	<span style="color: #002200;">&#91;</span>self updateFavoriteButton<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>That is a lot cleaner than what we had before! All the hassle of dealing with <code>NSUserDefaults</code> is now hidden away in <code>DataModel</code>.</p>
<h3>Weak and strong references</h3>
<p>Note that we declared the <code>dataModel</code> property in <code>RecipeDetailsViewController</code> &#8220;assign&#8221; instead of &#8220;retain&#8221;. If you&#8217;ve done any iOS programming you should be aware of <code>retain</code> and the <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH">memory management rules</a>.</p>
<p>In short: the owner of an object will retain that object and is ultimately responsible for releasing it when it no longer uses that object. When an object is retained, this is called a strong reference. <code>SmoothieViewController</code> has a strong reference to <code>DataModel</code>, because it created that object. <code>SmoothieViewController</code> owns the <code>DataModel</code> for as long as it is alive (which is until this app exits) and will release it in its <code>dealloc</code>.</p>
<p>When we pass the <code>DataModel</code> instance to <code>RecipeDetailsViewController</code>, we make it a so-called weak reference; <code>RecipeDetailsViewController</code> does not own the object and therefore does not retain it. Because <code>RecipeDetailsViewController</code> is guaranteed that the <code>DataModel</code> instance will be around for at least as long as it is (i.e. until the user exits the app), it has no need to retain it.</p>
<p>In general, if you pass along pointers to objects you should make them weak references (using the “assign” property semantics), to signify that the object you are giving it to does not assume ownership. You only use “retain” or “copy” when you are not guaranteed that the object may stick around, in which case you become responsible for releasing it when the time comes.</p>
<h3>Where do we put DataModel?</h3>
<p>The other place that used <code>NSUserDefaults</code> directly is <code>FavoritesViewController</code>. So let&#8217;s change that. But wait a minute&#8230; <code>DataModel</code> is currently created and owned by <code>SmoothiesViewController</code> but now <code>FavoritesViewController</code> also needs to use it. The problem is that these classes don&#8217;t know anything about each other. And preferably I would like to keep it that way (separation of concerns, remember?). So how can we make <code>FavoritesViewController</code> use the <code>DataModel</code>?</p>
<p>Obviously <code>SmoothiesViewController</code> is no longer the proper place to create the <code>DataModel</code>. I did that before because it was our only view controller, so it made sense. But now that we have another view controller that also needs to use the <code>DataModel</code> object, we have to refactor this code a little.</p>
<p>There are generally four ways to share your data model code among your controllers:</p>
<ol>
<li>Make the shared data a global variable</li>
<li>Make the shared data a singleton</li>
<li>Put the shared data in your application delegate</li>
<li>Make one class the owner of the object and pass a (weak) reference to any other class that needs to use the object</li>
</ol>
<p>The first three are variations on the same theme and I&#8217;ll explain below how to do that but also why you really shouldn&#8217;t.</p>
<h3>Global variables</h3>
<p>A global variable is a variable that can be accessed from anywhere in your code. We can make our <code>DataModel</code> object a global by making these changes:</p>
<p>In <code>DataModel.h</code>, below the interface definition:</p>

<div class="wp_codebox"><table><tr id="p580102"><td class="code" id="p580code102"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> DataModel <span style="color: #002200;">:</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/"><span style="color: #400080;">NSObject</span></a>
...
<span style="color: #a61390;">@end</span>
&nbsp;
<span style="color: #a61390;">extern</span> DataModel<span style="color: #002200;">*</span> dataModel;</pre></td></tr></table></div>

<p>The “extern” line tells any code that #imports <code>DataModel.h</code> that there is a global variable named <code>dataModel</code> that points to an instance of a <code>DataModel</code> object.</p>
<p>The <code>extern</code> declaration just said that there was a <code>dataModel</code> variable defined somewhere, but it didn&#8217;t actually define it yet. We do that in <code>DataModel.m</code>, near the top:</p>

<div class="wp_codebox"><table><tr id="p580103"><td class="code" id="p580code103"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;DataModel.h&quot;</span>
&nbsp;
DataModel<span style="color: #002200;">*</span> dataModel <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
&nbsp;
<span style="color: #a61390;">@implementation</span> DataModel
...
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>We still need to create the instance of <code>DataModel</code> and put it into that variable because currently it is nil. The app delegate is a logical place for that:</p>

<div class="wp_codebox"><table><tr id="p580104"><td class="code" id="p580code104"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in SmoothieAppDelegate.m:</span>
<span style="color: #6e371a;">#import &quot;DataModel.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> SmoothieAppDelegate
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>initialize
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>self class<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> <span style="color: #002200;">&#91;</span>SmoothiesAppDelegate class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		...
&nbsp;
		dataModel <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DataModel alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Because we #import <code>DataModel.h</code>, our app delegate knows about the global variable <code>dataModel</code> and can put values into it.</p>
<p>Now in <code>FavoritesViewController</code>&#8216;s table data source we do:</p>

<div class="wp_codebox"><table><tr id="p580105"><td class="code" id="p580code105"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theTableView numberOfRowsInSection<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>section
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Return the number of favorites</span>
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>dataModel favoritesCount<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>UITableViewCell<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView cellForRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	... make a UITableViewCell ...
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Get the favorite Recipe from the list</span>
	Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dataModel favoriteAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>; 
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Put the Recipe data into the cell</span>
	cell.textLabel.text <span style="color: #002200;">=</span> recipe.name;
	cell.imageView.image <span style="color: #002200;">=</span> recipe.image;
&nbsp;
	<span style="color: #a61390;">return</span> cell;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Note that the <code>favoriteAtIndex:</code> method now returns a <code>Recipe</code> object, not just the name of the <code>Recipe</code>. This lets us put the recipe&#8217;s image into the cell as well.</p>
<p>Pretty sweet, right? Well, there is a problem: using globals is considered bad programming practice. It generally makes programs harder to understand. The value of <code>dataModel</code> can be changed at any point in the program, and then any other objects that depend on <code>dataModel</code> might start to behave strangely if they did not expect that change. In our small app that doesn&#8217;t happen but when a program grows larger and starts to use more and more globals, it becomes a lot harder to keep track of what is going on.</p>
<p>Now, I admit that I use global variables from time to time. Occasionally they are the best way to solve a certain problem. Most of the time, however, they aren&#8217;t. Whenever you are tempted to use a global variable, try to find a cleaner solution first.</p>
<p>You can find the source code for this solution in <a href="https://github.com/hollance/Smoothies/tree/master/Version%206A">Version 6A</a>.</p>
<h3>Singleton</h3>
<p>The singleton is a controversial design pattern because it is basically a global variable hidden in a class. The iOS API uses singletons in various places. We&#8217;ve already seen one when we used <code>NSUserDefaults</code>.</p>
<p>There are two ways to make singletons:</p>
<ol>
<li>Use only class methods. This class will not have an instance. This method isn&#8217;t very common as it is a little cumbersome to use.</li>
<li>Make a single instance of the class behind the scenes and use a class method that gives access to it. This is what <code>[NSUserDefaults standardUserDefaults]</code> does.</li>
</ol>
<p>I&#8217;ll demonstrate how to do the latter. Add the following method to <code>DataModel.m</code>:</p>

<div class="wp_codebox"><table><tr id="p580106"><td class="code" id="p580code106"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sharedInstance
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">static</span> DataModel<span style="color: #002200;">*</span> instance <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>instance <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		instance <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>self alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
	<span style="color: #a61390;">return</span> instance;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>If you want to use <code>DataModel</code> anywhere, you use <code>[DataModel sharedInstance]</code>. This only creates a new <code>DataModel</code> instance once, the first time you call it.</p>
<p><code>FavoritesController</code>&#8216;s data source method now becomes:</p>

<div class="wp_codebox"><table><tr id="p580107"><td class="code" id="p580code107"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theTableView numberOfRowsInSection<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>section
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Return the number of favorites</span>
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DataModel sharedInstance<span style="color: #002200;">&#93;</span> favoritesCount<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>UITableViewCell<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView cellForRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	... make a UITableViewCell ...
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Get the favorite Recipe from the list</span>
	Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DataModel sharedInstance<span style="color: #002200;">&#93;</span> favoriteAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>; 
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Put the Recipe data into the cell</span>
	cell.textLabel.text <span style="color: #002200;">=</span> recipe.name;
	cell.imageView.image <span style="color: #002200;">=</span> recipe.image;
&nbsp;
	<span style="color: #a61390;">return</span> cell;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Similar changes were made to <code>SmoothiesViewController</code>.</p>
<p>This is only a simple implementation of the singleton pattern. There is nothing stopping you from doing:</p>

<div class="wp_codebox"><table><tr id="p580108"><td class="code" id="p580code108"><pre class="objc" style="font-family:monospace;">DataModel<span style="color: #002200;">*</span> anotherDataModel <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DataModel alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>

<p>Apple has some <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32">sample code</a> that can help prevent this, but I never find that worth implementing. Just stick to the convention that your code has to use this class through the <code>+sharedInstance</code> method.</p>
<p>The main problem with singletons is that, just like global variables, they make it harder to isolate parts of the code. It is often desirable to keep the scope of objects as small as possible, i.e. to restrict the use and visibility of an object to only the portion of the code that depends on it. But a global as well as a singleton are visible anywhere in the code. This increases the general complexity of the code and thus makes it harder to understand. Again, for a small app such as this using a singleton won&#8217;t get you into trouble, but there is a better way that I will be showing you soon. First, however, a worse way.</p>
<p>You can find the singleton source code in <a href="https://github.com/hollance/Smoothies/tree/master/Version%206B">Version 6B</a>.</p>
<h3>Application delegate</h3>
<p>As I said, iOS itself uses singletons in various places and one of these is <code>UIApplication</code>. Because <code>UIApplication</code> has a delegate that you already have to write a class for, many people treat their app delegate as a kind of singleton too. They like to put shared data in their app delegate class, simply because it is convenient.</p>
<p>Here is how that works. We add <code>DataModel</code> as a property to <code>SmoothieAppDelegate</code>, and create the instance when the app starts up:</p>

<div class="wp_codebox"><table><tr id="p580109"><td class="code" id="p580code109"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>application<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIApplication<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>application didFinishLaunchingWithOptions<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/"><span style="color: #400080;">NSDictionary</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>launchOptions
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Create the Data Model object</span>
	self.dataModel <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DataModel alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span> autorelease<span style="color: #002200;">&#93;</span>;
&nbsp;
	...
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Then to use this shared <code>DataModel</code> object in our code, we do:</p>

<div class="wp_codebox"><table><tr id="p580110"><td class="code" id="p580code110"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theTableView numberOfRowsInSection<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>section
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Return the number of favorites</span>
	DataModel<span style="color: #002200;">*</span> dataModel <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>SmoothieAppDelegate<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span> delegate<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>dataModel favoritesCount<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>UITableViewCell<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView cellForRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	... make a UITableViewCell ...
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Get the favorite Recipe from the list</span>
	DataModel<span style="color: #002200;">*</span> dataModel <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>SmoothieAppDelegate<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span> delegate<span style="color: #002200;">&#93;</span>;
	Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dataModel favoriteAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>; 
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Put the Recipe data into the cell</span>
	cell.textLabel.text <span style="color: #002200;">=</span> recipe.name;
	cell.imageView.image <span style="color: #002200;">=</span> recipe.image;
&nbsp;
	<span style="color: #a61390;">return</span> cell;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Everywhere we want to use the data model, we now have to do this first:</p>

<div class="wp_codebox"><table><tr id="p580111"><td class="code" id="p580code111"><pre class="objc" style="font-family:monospace;">DataModel<span style="color: #002200;">*</span> dataModel <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>SmoothieAppDelegate<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span> delegate<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>

<p>And we have to <code>#import “SmoothieAppDelegate.h”</code> in every file where we want to use DataModel.</p>
<p>Yuck. Because that is ugly, some people even go as far as this:</p>

<div class="wp_codebox"><table><tr id="p580112"><td class="code" id="p580code112"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define AD ((SmoothieAppDelegate*)[[UIApplication sharedApplication] delegate])</span>
&nbsp;
Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>AD.dataModel favoriteAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>

<p>Please, don&#8217;t resort to such atrocities! It makes me sad to see code like that. <img src='http://www.hollance.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>Just because you already have an <code>AppDelegate</code> class and that you can access it more or less as a singleton, doesn&#8217;t mean that this is the proper place for your data model code.</p>
<p>I did not make a source code example for this, because this approach is horrible! I really want to dissuade you from using it. On to the proper solution&#8230;</p>
<h3>Passing references</h3>
<p>The idea is simple: there will be one owner of <code>DataModel</code>. In our case, we&#8217;ll make our app delegate the owner. There is nothing wrong with that. But instead of always asking the app delegate for what the data model is, the app delegate will pass a reference to the data model to any class that needs to use it. We already did something similar before when <code>SmoothieViewController</code> passed its <code>DataModel</code> reference on to <code>RecipeDetailsViewController</code>.</p>
<p>In <code>SmoothieAppDelegate.h</code> we add the following:</p>

<div class="wp_codebox"><table><tr id="p580113"><td class="code" id="p580code113"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@class</span> DataModel;
<span style="color: #a61390;">@class</span> SmoothiesViewController;
<span style="color: #a61390;">@class</span> FavoritesViewController;
&nbsp;
<span style="color: #a61390;">@interface</span> SmoothiesAppDelegate <span style="color: #002200;">:</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/"><span style="color: #400080;">NSObject</span></a> 
&nbsp;
...
&nbsp;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> IBOutlet SmoothiesViewController<span style="color: #002200;">*</span> smoothiesViewController;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> IBOutlet FavoritesViewController<span style="color: #002200;">*</span> favoritesViewController;
&nbsp;
<span style="color: #11740a; font-style: italic;">// The shared Data Model object</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> DataModel<span style="color: #002200;">*</span> dataModel;
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>We added the <code>DataModel</code> as a retained property, and we added two new <code>IBOutlets</code> so we can refer to the <code>SmoothiesViewController</code> and <code>FavoritesViewController</code> from the app delegate. I connected these outlets in Interface Builder.</p>
<p>We need those outlets because that is how we pass the <code>DataModel</code> reference around:</p>

<div class="wp_codebox"><table><tr id="p580114"><td class="code" id="p580code114"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in SmoothieAppDelegate.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>application<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIApplication<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>application didFinishLaunchingWithOptions<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/"><span style="color: #400080;">NSDictionary</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>launchOptions
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Create the Data Model object</span>
	self.dataModel <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DataModel alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span> autorelease<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Tell the view controllers about the Data Model</span>
	self.smoothiesViewController.dataModel <span style="color: #002200;">=</span> self.dataModel;
	self.favoritesViewController.dataModel <span style="color: #002200;">=</span> self.dataModel;
&nbsp;
	<span style="color: #002200;">&#91;</span>self.window addSubview<span style="color: #002200;">:</span>self.tabBarController.view<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self.window makeKeyAndVisible<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Both <code>SmoothiesViewController</code> and <code>FavoritesViewController</code> now have a property for the data model:</p>

<div class="wp_codebox"><table><tr id="p580115"><td class="code" id="p580code115"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in SmoothiesViewController.h and FavoritesViewController.h:</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, assign<span style="color: #002200;">&#41;</span> DataModel<span style="color: #002200;">*</span> dataModel;</pre></td></tr></table></div>

<p>This is a weak reference because these objects don&#8217;t own the data model instance; they just use it. Because the app delegate class will be around until the app exits, so will the data model object.</p>
<p>As you can see, this approach requires that you make a few more properties than if you were to use a global variable or singleton, but it&#8217;s a cleaner solution. The Smoothies and Favorites view controllers don&#8217;t care where the data model object comes from; they just know that it&#8217;s there when they need it and that they can access it through their <code>self.dataModel</code> property:</p>

<div class="wp_codebox"><table><tr id="p580116"><td class="code" id="p580code116"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theTableView numberOfRowsInSection<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>section
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// Return the number of favorites</span>
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>self.dataModel favoritesCount<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>UITableViewCell<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView cellForRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	... make a UITableViewCell ...
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Get the favorite Recipe from the list</span>
	Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self.dataModel favoriteAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>; 
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Put the Recipe data into the cell</span>
	cell.textLabel.text <span style="color: #002200;">=</span> recipe.name;
	cell.imageView.image <span style="color: #002200;">=</span> recipe.image;
&nbsp;
	<span style="color: #a61390;">return</span> cell;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>So it&#8217;s a little harder to set up in the <code>AppDelegate</code>, but it&#8217;s easier to use after that.</p>
<p>You only pass the data model to objects that need it. Those objects now don&#8217;t depend on any other part of the code to do their job. That&#8217;s an approach I have been using throughout this tutorial series. For example, when we open the Recipe Details screen, we give that view controller all the data it needs to use and nothing more. The view controller is completely self-contained; it does not depend on any other classes or global variables to do its job. Once we&#8217;ve created it and filled in its properties, it is good to go.</p>
<p>We could put the Recipe Details screen in a totally different part of the app if we wished, as long as we have a <code>DataModel</code> and <code>Recipe</code> object to give it. You should strive to design your view controllers (and any other classes) that way, with a little dependencies on external state as possible.</p>
<p>You can find the source code for the final solution in <a href="https://github.com/hollance/Smoothies/tree/master/Version%206C">Version 6C</a>.</p>
<p>Our class diagram now looks like this:</p>
<div id="attachment_593" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-6-1-Class-structure.png"><img class="size-medium wp-image-593" title="Figure 6-1 Class structure" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-6-1-Class-structure-300x99.png" alt="Figure 6.1. The DataModel is now shared among the view controllers." width="300" height="99" /></a><p class="wp-caption-text">Figure 6.1. The DataModel is now shared among the view controllers.</p></div>
<p>In this chapter, we hid the fact that favorites are stored with <code>NSUserDefaults</code>. If we want to change how we store the favorites &#8212; maybe a PList file or JSON would be better – then we can do that without having to change anything besides <code>DataModel</code>. It is <code>DataModel</code>&#8216;s responsibility (and <code>DataModel</code> alone) to store and retrieve this data. None of your other classes should have to care about that. All they care about is that they can ask the <code>DataModel</code> for how many favorites there are, and what they are. It&#8217;s up to <code>DataModel</code> to make sure it does that properly, but how it does that is an implementation detail as far as anyone else is concerned.</p>
<p>Note: We could have stored the fact whether a recipe is a favorite or not directly into the <code>Recipe</code> object instead of <code>DataModel</code>. Sometimes it&#8217;s obvious where a piece of data or logic goes, but often it&#8217;s a matter of taste and personal preference. There is usually more than one way to do it. And if you find in the course of developing your app that your initial choice is no longer the best choice, then ruthlessly refactor your code until its structure is good again. It doesn&#8217;t really matter to me, as long as your code is clean!</p>
<p>In <a href="http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-3/">part 3</a> of this tutorial, we&#8217;ll finish the app.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-2/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-2/</feedburner:origLink></item>
		<item>
		<title>Making Your Classes Talk to Each Other, Part 1</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/36LebJn2gAE/</link>
		<comments>http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-1/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 12:43:54 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=557</guid>
		<description><![CDATA[This is the first part of a three-part tutorial for beginning iOS programmers on how to make classes, especially view controllers, communicate with each other. See also Part 2 and Part 3. One question that I see a lot on developer forums is: “How do I use a variable from one class in another?” Or [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is the first part of a three-part tutorial for beginning iOS programmers on how to make classes, especially view controllers, communicate with each other. See also <a href="http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-2/">Part 2</a> and <a href="http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-3/">Part 3</a>.</em></p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/04/Icon@2x.png"><img class="size-full wp-image-613 alignright" title="Icon" src="http://www.hollance.com/wp-content/uploads/2011/04/Icon@2x.png" alt="" width="114" height="114" /></a>One question that I see a lot on developer forums is: “How do I use a variable from one class in another?” Or related: “How does my class call a method from another class?” Or: “How do I send my data from view controller A to view controller B?”</p>
<p>Obviously these are newbie questions, and a typical answer is: go read a book on programming. While I certainly recommend that beginners get a <a href="http://www.amazon.com/gp/product/0321566157/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=natuhabi-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321566157">good book on Objective-C</a> and a <a href="http://www.amazon.com/gp/product/B004M8T01Q/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=natuhabi-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B004M8T01Q">book on developing for iOS</a>, I may be able to offer some tips on how to structure your programs.</p>
<p>There are several approaches you can use and I&#8217;ll highlight the most common ones. I will also point out bad practices that you should avoid in your own apps.</p>
<p>I always put a lot of effort into keeping my code as clean as possible. I will often rewrite large sections of my app when they have become too messy. If you let the source become too complex, then fixing bugs or adding new features will be a nightmare. Knowing a handful of best practices for structuring your code will help you to stay sane and it will also make your apps better.</p>
<p>Hopefully my explanations will be clear enough to understand, even if you&#8217;re just getting started developing for the iPhone or iPad. Let me know in the comments how you&#8217;re getting along!<span id="more-557"></span></p>
<h3>Model-View-Controller</h3>
<p>Much of UIKit is built around the idea of Model-View-Controller, or MVC for short. You will get the most out of working with UIKit if you split up your code into three different parts:</p>
<p><strong>The models.</strong> These classes contain your data and any operations on the data. For example, if you are writing a cookbook app, the model would consist of the recipes. You should be able to take this code and port it to a completely different platform (such as Mac OS X or Android) without too many modifications (although you may need to switch programming languages). Your model code will be dependent on Objective-C and Foundation, but not on UIKit.</p>
<p><strong>The views.</strong> These form the visual part of the app: images, buttons, labels, text fields, and so on. A view can draw itself and respond to user input, but it typically does not handle any application logic. Most views can be re-used in many different applications because they are not tied to a specific data model. To show a list of recipes, we could use a standard <code>UITableView</code>. To show a single recipe in more detail, we would also use standard controls: a label for the title of the recipe, an image view for a photo, and a text view for the cooking instructions.</p>
<p><strong>The controllers.</strong> Simply put, each screen in your application will have its own controller. The main list of recipes sits in a <code>UITableViewController</code>, which is a subclass of <code>UIViewController</code> that works with a dedicated table view. If you tap on a row in that list, the details screen for that recipe should open. That screen is also a subclass of <code>UIViewController</code>. The controller is what connects your data model to your views. The view controller has a view that shows the contents of the screen, which it loads from your data model.</p>
<p>Conceptually, this is how it fits together:</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/04/Model-View-Controller.png"><img class="aligncenter size-full wp-image-564" title="Model View Controller" src="http://www.hollance.com/wp-content/uploads/2011/04/Model-View-Controller.png" alt="Model View Controller" width="540" height="109" /></a>The trick is splitting up our app&#8217;s functionality into such models, views and controllers, and making all these different classes talk to each other. That&#8217;s exactly what this tutorial is about.</p>
<p>All this talk of recipes makes me hungry. Let&#8217;s do something about that!</p>
<h3>Smoothies!</h3>
<p>To illustrate these concepts, I have made a simple but complete app, named Smoothies. As you can guess from the name, it&#8217;s a smoothie recipe app. In its finished state it looks like this:</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/04/Smoothies.png"><img class="aligncenter size-medium wp-image-565" title="The final Smoothies app" src="http://www.hollance.com/wp-content/uploads/2011/04/Smoothies-300x187.png" alt="The final Smoothies app" width="300" height="187" /></a></p>
<p>In this article series we will build the app step-by-step. We will begin with the most basic of features and with every new version we add features and refactor the code to keep it clean and well-organized. By the end of this article you should have a good idea of the different approaches to organizing your classes and what are the pros and cons of each approach. But let&#8217;s begin with the very basics.</p>
<h3>Version 1: Building the skeleton</h3>
<p>This first version of the app will look like this:</p>
<div id="attachment_566" class="wp-caption aligncenter" style="width: 169px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-1-1-First-version.png"><img class="size-medium wp-image-566" title="Figure 1-1 First version" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-1-1-First-version-159x300.png" alt="Figure 1.1. The very basic first version of our smoothie recipes app." width="159" height="300" /></a><p class="wp-caption-text">Figure 1.1. The very basic first version of our smoothie recipes app.</p></div>
<p>It&#8217;s just an empty table view with a title bar on top. The table view sits in a <code>UITableViewController</code>, which in turn belongs to a <code>UINavigationController</code>. This is a standard design for many iPhone apps. I&#8217;m sure you will have seen it before.</p>
<p>You can view and download the <a href="https://github.com/hollance/Smoothies/tree/master/Version%201">source code for Version 1</a> from github.</p>
<p>I used Xcode&#8217;s “View-based Application” template to create a new project. Then I reorganized the files a bit because I don&#8217;t like where the standard template puts them.</p>
<p>The template makes an application delegate, <code>SmoothiesAppDelegate</code>, and a view controller, <code>SmoothiesViewController</code>. I cleaned up the app delegate a bit and changed <code>SmoothiesViewController</code> from a basic <code>UIViewController</code> into a <code>UITableViewController</code>. We want to display a list of smoothies and a table view is ideal for that.</p>
<p>I also made some changes to the nib files. I removed <code>SmoothiesViewController.xib</code> because we no longer need it now that we&#8217;re using a table view controller. In <code>MainWindow.xib</code> I added a navigation controller and put the <code>SmoothiesViewController</code> inside that. The navigation controller provides the title bar at the top of the screen, and we&#8217;ll use it later to present a details screen when you tap the name of a recipe.</p>
<div id="attachment_567" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-1-2-MainWindow-nib.png"><img class="size-medium wp-image-567" title="Figure 1-2 MainWindow nib" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-1-2-MainWindow-nib-300x198.png" alt="Figure 1.2. The MainWindow.xib in Interface Builder." width="300" height="198" /></a><p class="wp-caption-text">Figure 1.2. The MainWindow.xib in Interface Builder.</p></div>
<p>The application delegate has a <code>navigationController</code> outlet, which I connected to our <code>UINavigationController</code> (see under “Referencing Outlets” in the right side bar in figure 1.2). When the app starts up, the delegate adds this controller&#8217;s view to the window and makes it visible. Because we set the <code>SmoothiesViewController</code> as the root of the navigation controller, it shows up in the window as well.</p>
<p>This should be familiar to you if you&#8217;ve done any iOS programming before. Having an app delegate and a view controller are the basics of any app.</p>
<p>Our class structure currently looks like this:</p>
<div id="attachment_568" class="wp-caption aligncenter" style="width: 550px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-1-3-Class-structure.png"><img class="size-full wp-image-568" title="Figure 1-3 Class structure" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-1-3-Class-structure.png" alt="Figure 1.3. We have three classes that are connected together." width="540" height="111" /></a><p class="wp-caption-text">Figure 1.3. We have three classes that are connected together.</p></div>
<p>Notice that nowhere in our code do we use the <code>UINavigationController</code> class directly. It is instantiated for us when <code>MainWindow.xib</code> is loaded during app startup, and we only need it to hold our <code>SmoothiesViewController</code>.</p>
<p>Take a quick peek at the <a href="https://github.com/hollance/Smoothies/tree/master/Version%201">source</a> and build and run the project. It doesn&#8217;t do much yet, but we&#8217;re off to a good start!</p>
<h3>Version 2: Adding a Recipe class</h3>
<p>Let&#8217;s put some recipes on the screen. First, we need to decide exactly what constitutes a recipe. To keep things simple we&#8217;ll just give each recipe three attributes: a name, the preparation instructions, and an image. We&#8217;ll show the name and image in the table view on the app&#8217;s main screen. To see the entire recipe in detail you&#8217;ll have to tap on it, but that is for the next version.</p>
<div id="attachment_571" class="wp-caption aligncenter" style="width: 169px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-2-1-The-app.png"><img class="size-medium wp-image-571" title="Figure 2-1 The app" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-2-1-The-app-159x300.png" alt="Figure 2.1. What the app will look like at the end of this chapter." width="159" height="300" /></a><p class="wp-caption-text">Figure 2.1. What the app will look like at the end of this chapter.</p></div>
<p>Since a recipe is a separate entity in our app, it makes sense to give it its own class. It shouldn&#8217;t surprise you that I named it <code>Recipe</code>. In this case it was easy to name our class, but it isn&#8217;t always so. Finding good names for your classes is an important part of writing clear and maintainable code, so don&#8217;t skimp on it!</p>
<p><code>Recipe</code> is a so-called data model class. Its purpose is to describe what a recipe is, nothing more. In a little while we will also need write some logic to display the recipes on the screen, but that logic will not be part of the <code>Recipe</code> class.</p>
<p>This the Model-View-Controller separation that I talked about earlier. It makes sense to organize your classes by the principle that anything that can be considered pure data goes into its own set of classes. Any calculations on that data (often called the “business logic” or “domain logic”) also goes into these classes. In our case, the topic of our app is recipes, so it makes sense to consider recipes to be part of our app&#8217;s data model.</p>
<p>The data model classes are separate from the controllers and views. Recall that the views are used to display the items from the data model on the screen. Their function isn&#8217;t to store data or perform calculations on it; views just know how to draw stuff. Examples of views are labels, sliders, buttons, and so on. The task of the controller is to connect the two together.</p>
<p>For the moment, we won&#8217;t do much with recipes except show them in a table, so the <code>Recipe</code> class will be very simple.</p>
<p>I used Xcode&#8217;s New File assistant to create the <code>Recipe</code> class, which extends from <code>NSObject</code>. The assistant created two files, <code>Recipe.h</code> and <code>Recipe.m</code>, and this is what they look like after I added my data model code to them.</p>
<p>Here is <code>Recipe.h</code>, the interface of the <code>Recipe</code> class:</p>

<div class="wp_codebox"><table><tr id="p557133"><td class="code" id="p557code133"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> Recipe <span style="color: #002200;">:</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/"><span style="color: #400080;">NSObject</span></a>
<span style="color: #002200;">&#123;</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, copy<span style="color: #002200;">&#41;</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> name;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, copy<span style="color: #002200;">&#41;</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> instructions;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIImage<span style="color: #002200;">*</span> image;
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>It&#8217;s very simple. I subclassed <code>NSObject</code> and added properties for the recipe&#8217;s name, instructions and image.</p>
<h3>Copy vs retain</h3>
<p>Notice that the name and instructions properties are declared with “copy” semantics. This is a good idea for properties of type <code>NSString</code>, <code>NSArray</code>, <code>NSSet</code>, and a few others.</p>
<p>Let me briefly explain. <code>NSString</code> has a subclass <code>NSMutableString</code>, which means you can use an <code>NSMutableString</code> instance anywhere you can use an <code>NSString</code>. The following code is perfectly valid, but it produces different rules if the name property is declared with <code>retain</code> or <code>copy</code>:</p>

<div class="wp_codebox"><table><tr id="p557134"><td class="code" id="p557code134"><pre class="objc" style="font-family:monospace;"><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableString_Class/"><span style="color: #400080;">NSMutableString</span></a><span style="color: #002200;">*</span> str <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableString_Class/"><span style="color: #400080;">NSMutableString</span></a> stringWithString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Raspberry Smoothie&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>Recipe alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span> autorelease<span style="color: #002200;">&#93;</span>;
recipe.name <span style="color: #002200;">=</span> str;
&nbsp;
NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Recipe name is now: %@&quot;</span>, recipe.name<span style="color: #002200;">&#41;</span>;
<span style="color: #11740a; font-style: italic;">// This outputs &quot;Raspberry Smoothie&quot;</span>
&nbsp;
<span style="color: #002200;">&#91;</span>str appendString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot; with Chocolate&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Recipe name is now: %@&quot;</span>, recipe.name<span style="color: #002200;">&#41;</span>;
<span style="color: #11740a; font-style: italic;">// This should still output &quot;Raspberry Smoothie&quot;</span>
<span style="color: #11740a; font-style: italic;">// and not &quot;Raspberry Smoothie with Chocolate&quot;</span></pre></td></tr></table></div>

<p>In this example, we assign the <code>NSMutableString</code> object to recipe&#8217;s <code>name</code> parameter. No problem here, but then we change that mutable string object. If <code>name</code> was declared as <code>retain</code> instead of <code>copy</code>, then the <code>Recipe</code>&#8216;s name would be changed out from under it. Since you usually do not want that to happen, specify <code>copy</code> for any property whose type also has a mutable subclass. If you&#8217;re not very familiar with the various classes in the Foundation framework yet, then just remember to do this for <code>NSString</code> and <code>NSArray</code>.</p>
<p>By the way, if you haven&#8217;t seen <code>NSLog()</code> before, this function writes text to the console window. It&#8217;s very handy for debugging and for figuring out what is going on in your app.</p>
<h3>The implementation of Recipe</h3>
<p>On to the implementation inside <code>Recipe.m</code>:</p>

<div class="wp_codebox"><table><tr id="p557135"><td class="code" id="p557code135"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;Recipe.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> Recipe
&nbsp;
<span style="color: #a61390;">@synthesize</span> name, instructions, image;
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>dealloc
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>name release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>instructions release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>image release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>super dealloc<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>description
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@ %@&quot;</span>, <span style="color: #002200;">&#91;</span>super description<span style="color: #002200;">&#93;</span>, self.name<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>There is not much special in the .m file, except maybe for the <code>description</code> method. This method is defined by <code>NSObject</code> and we override it here with our own version. The purpose of <code>description</code> is to help with debugging. When we now do:</p>

<div class="wp_codebox"><table><tr id="p557136"><td class="code" id="p557code136"><pre class="objc" style="font-family:monospace;">NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Recipe name is now: %@&quot;</span>, recipe<span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>

<p>the console will show something like this:</p>

<div class="wp_codebox"><table><tr id="p557137"><td class="code" id="p557code137"><pre class="objc" style="font-family:monospace;">Recipe name is now<span style="color: #002200;">:</span>  Raspberry Smoothie</pre></td></tr></table></div>

<p>Note that we did not call <code>[recipe description]</code>. <code>NSLog()</code> will automatically call <code>description</code> for us, so that saves some typing. The bit between the brackets is the name of the class and its memory pointer. This is done by <code>NSObject</code>, thanks to our call to <code>[super description]</code>.</p>
<p>Our own version of <code>description</code> added the name of the smoothie to the output. If our app now crashes on something that has to do with a recipe, this makes it a little easier for us to determine which particular <code>Recipe</code> object is the culprit.</p>
<h3>Filling up the table</h3>
<p>A <code>UITableView</code> needs a data source and a delegate to provide it with the entries it needs to display and other information. If you recall, our <code>SmoothiesViewController</code> is actually a subclass of <code>UITableViewController</code>, and a table view controller automatically serves as both the delegate and data source for the table. That&#8217;s very handy! Now we simply have to add a few methods to our <code>SmoothiesViewController</code> to make this all work.</p>
<p>Let&#8217;s create a list of recipes first. Add the following to <code>SmoothiesViewController.h</code>:</p>

<div class="wp_codebox"><table><tr id="p557138"><td class="code" id="p557code138"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// The list of Recipe objects</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/"><span style="color: #400080;">NSMutableArray</span></a><span style="color: #002200;">*</span> recipes;</pre></td></tr></table></div>

<p>And to <code>SmoothiesViewController.m</code>:</p>

<div class="wp_codebox"><table><tr id="p557139"><td class="code" id="p557code139"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@synthesize</span> recipes;
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>dealloc
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>recipes release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>super dealloc<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>All we did here was add a property <code>recipes</code> of type <code>NSMutableArray</code>. This list will hold our <code>Recipe</code> objects. You always have to do this sort of housekeeping when you want to add a property: declare the <code>@property</code> in your .h, add a <code>@synthesize</code> in your .m, and release it in your <code>dealloc</code> if the property is of type “copy” or “retain”.</p>
<p>Now we can create the recipes list and fill it up with some tasty recipes. In <code>SmoothiesViewController.m</code> add:</p>

<div class="wp_codebox"><table><tr id="p557140"><td class="code" id="p557code140"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>initWithCoder<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSCoder_Class/"><span style="color: #400080;">NSCoder</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>aDecoder
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>self <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>super initWithCoder<span style="color: #002200;">:</span>aDecoder<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #11740a; font-style: italic;">// Create the recipe list object</span>
		recipes <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/"><span style="color: #400080;">NSMutableArray</span></a> arrayWithCapacity<span style="color: #002200;">:</span><span style="color: #2400d9;">10</span><span style="color: #002200;">&#93;</span> retain<span style="color: #002200;">&#93;</span>;
&nbsp;
		<span style="color: #11740a; font-style: italic;">// And add a few recipes to it</span>
		Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>Recipe alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
		recipe.name <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Banana Shake&quot;</span>;
		recipe.instructions <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;...&quot;</span>;
		recipe.image <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIImage imageNamed<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Banana Shake.png&quot;</span><span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#91;</span>recipes addObject<span style="color: #002200;">:</span>recipe<span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#91;</span>recipe release<span style="color: #002200;">&#93;</span>;
&nbsp;
		... we add more recipes here ...
	<span style="color: #002200;">&#125;</span>
	<span style="color: #a61390;">return</span> self;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>The <code>initWithCoder</code> method is called when the view controller is loaded from the nib. We use it to allocate and initialize the recipes array, and then we create several new <code>Recipe</code> objects and add them to that array.</p>
<p>We&#8217;re not done yet. We still have to tell the table view to display the entries from this array. Add the following methods to <code>SmoothiesViewController.m</code>:</p>

<div class="wp_codebox"><table><tr id="p557141"><td class="code" id="p557code141"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView numberOfRowsInSection<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>section
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">return</span> self.recipes.count;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>UITableViewCell<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView cellForRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">static</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a><span style="color: #002200;">*</span> CellIdentifier <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;RecipeCellIdentifier&quot;</span>;
&nbsp;
	UITableViewCell<span style="color: #002200;">*</span> cell <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>tableView dequeueReusableCellWithIdentifier<span style="color: #002200;">:</span>CellIdentifier<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>cell <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>
		cell <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UITableViewCell alloc<span style="color: #002200;">&#93;</span> initWithStyle<span style="color: #002200;">:</span>UITableViewCellStyleDefault reuseIdentifier<span style="color: #002200;">:</span>CellIdentifier<span style="color: #002200;">&#93;</span> autorelease<span style="color: #002200;">&#93;</span>;
&nbsp;
	Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self.recipes objectAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>;
	cell.textLabel.text <span style="color: #002200;">=</span> recipe.name;
	cell.imageView.image <span style="color: #002200;">=</span> recipe.image;
	<span style="color: #a61390;">return</span> cell;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>This should be old-hat for anyone who has used a <code>UITableView</code> before. In <code>numberOfRowsInSection:</code>, we simply return the number of recipes in our list. In <code>cellForRowAtIndexPath:</code> we first obtain a <code>UITableViewCell</code> and then set the cell&#8217;s text label and image with the properties from the <code>Recipe</code> at the specified row.</p>
<p>You can run the app now and you&#8217;ll see a list of recipe names, each of which has a small thumbnail image to the left. There is one more tweak I&#8217;d like to make. The standard height of table view rows is 44 points, which is a little small for our thumbnails. So we&#8217;ll set it to 66 points instead.</p>
<p>Add the following snippet to <code>SmoothiesViewController.m</code>:</p>

<div class="wp_codebox"><table><tr id="p557142"><td class="code" id="p557code142"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>viewDidLoad
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>super viewDidLoad<span style="color: #002200;">&#93;</span>;
	self.tableView.rowHeight <span style="color: #002200;">=</span> <span style="color: #2400d9;">66</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>As its name implies, this method is called after the view controller&#8217;s view is loaded. We want to set the <code>rowHeight</code> property of the table view, and this is the ideal place to do it. We cannot do this in <code>initWithCoder</code> because that is too early; by then the table view is not created yet and <code>self.tableView</code> is still nil.</p>
<h3>The class structure</h3>
<p>To recap, we added a <code>Recipe</code> class and modified the <code>SmoothiesViewController</code> class to hold an array of those <code>Recipe</code> objects. The class structure is now as follows:</p>
<div id="attachment_572" class="wp-caption aligncenter" style="width: 550px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-2-2-Class-structure.png"><img class="size-full wp-image-572" title="Figure 2-2 Class structure" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-2-2-Class-structure.png" alt="Figure 2.2. We added a list of Recipe objects to the SmoothiesViewController." width="540" height="255" /></a><p class="wp-caption-text">Figure 2.2. We added a list of Recipe objects to the SmoothiesViewController.</p></div>
<p>I have encircled the classes that form our data model. It consists not just of the <code>Recipe</code> objects, but also of the <code>NSMutableArray</code> that contains them.</p>
<p>We also wrote code to display these <code>Recipe</code> objects on the screen. For every <code>Recipe</code>, we made a <code>UITableViewCell</code> and set its text label and image to the data from the recipe. The <code>UITableViewCell</code> serves as the “view” for the recipe. The <code>SmoothiesViewController</code> ties both of them together in the table view&#8217;s data source methods. There you have Model-View-Controller in action!</p>
<p>This concludes version 2 of the app. You can get the <a href="https://github.com/hollance/Smoothies/tree/master/Version%202">full source code</a> from github. Next, we&#8217;re going to add the Recipe Details screen, which shows up when you tap on a recipe.</p>
<h3>Version 3: Recipe details</h3>
<p>So far we&#8217;ve just shown the names of the recipes and a thumbnail image. I would really like to go make a smoothie now, so it&#8217;s time to add some functionality to the app that lets us see the actual recipes. We&#8217;re going to add the Recipe Details screen that shows up when you tap a smoothie in the table view. It will show the title of the smoothie, a photo (a bigger version of the thumbnail), and the recipe instructions.</p>
<p>This is what it will look like:</p>
<div id="attachment_573" class="wp-caption aligncenter" style="width: 169px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-3-1-Recipe-details.png"><img class="size-medium wp-image-573" title="Figure 3-1 Recipe details" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-3-1-Recipe-details-159x300.png" alt="Figure 3.1. That looks delicious!" width="159" height="300" /></a><p class="wp-caption-text">Figure 3.1. That looks delicious!</p></div>
<p>A new screen means a new view controller. Basically, every screen in your app uses its own <code>UIViewController</code> subclass (such as <code>UITableViewController</code> or a subclass of your own). Sometimes you can re-use the same view controller class for different screens if those screens are similar, and we&#8217;ll see an example of that later in this tutorial.</p>
<p>For the Recipe Details screen we will make our own subclass, <code>RecipeDetailsViewController</code>, that extends directly from <code>UIViewController</code>. It will be loaded from a nib file, so we can make the UI in Interface Builder.</p>
<p>I used Xcode&#8217;s New File wizard and chose “UIViewController subclass” and checked “With XIB for user interface”. I opened the nib in Interface Builder and added an image view for the photo and a text view for the instructions. We&#8217;re going to display the recipe&#8217;s name in the navigation bar, so we don&#8217;t need to add a label for that.</p>
<p>Then I connected these new subviews to outlets in the source file. In Xcode 4 that is really easy to do. Hold down Ctrl and drag from a subview into the .h file. This will automatically insert the <code>@property</code> statement for you, as well as <code>@synthesize</code> and <code>release</code> statements in the .m file.</p>
<div id="attachment_574" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-3-2-RecipeDetailsViewController-nib.png"><img class="size-medium wp-image-574" title="Figure 3-2 RecipeDetailsViewController nib" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-3-2-RecipeDetailsViewController-nib-300x174.png" alt="Figure 3.2. The new view controller in Interface Builder." width="300" height="174" /></a><p class="wp-caption-text">Figure 3.2. The new view controller in Interface Builder.</p></div>
<p>Let&#8217;s connect this new screen to our table view. Add the following code to <code>SmoothiesViewController.m</code>:</p>

<div class="wp_codebox"><table><tr id="p557143"><td class="code" id="p557code143"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView didSelectRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	RecipeDetailsViewController<span style="color: #002200;">*</span> controller <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>RecipeDetailsViewController alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>self.navigationController pushViewController<span style="color: #002200;">:</span>controller animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>controller release<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>This is a method from the <code>UITableViewDelegate</code> protocol. It is called when the user taps one of the rows in the table. We create a new instance of the <code>RecipeDetailsViewController</code> (this will automatically load the nib file) and then push it on the navigation stack. Try it out. You can now tap on the name of a smoothie and in response the Recipe Details screen will appear. Because we pushed this screen onto the navigation controller, you can close it again by pressing the back button in the top left.</p>
<h3>Displaying the recipe</h3>
<p>At this point, the Recipe Details screen doesn&#8217;t do much yet. We still have to tell it which <code>Recipe</code> object to display. So how do we get the recipe to show up in this screen? First, we add a <code>@property</code> to the interface of the view controller in <code>RecipeDetailsViewController.h</code>:</p>

<div class="wp_codebox"><table><tr id="p557144"><td class="code" id="p557code144"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@class</span> Recipe;
&nbsp;
<span style="color: #a61390;">@interface</span> RecipeDetailsViewController <span style="color: #002200;">:</span> UIViewController
<span style="color: #002200;">&#123;</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> IBOutlet UIImageView<span style="color: #002200;">*</span> imageView;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> IBOutlet UITextView<span style="color: #002200;">*</span> instructionsTextView;
&nbsp;
<span style="color: #11740a; font-style: italic;">// This is the new property</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> Recipe<span style="color: #002200;">*</span> recipe;
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>Then we change the table view delegate method to:</p>

<div class="wp_codebox"><table><tr id="p557145"><td class="code" id="p557code145"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in SmoothiesViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView didSelectRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	RecipeDetailsViewController<span style="color: #002200;">*</span> controller <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>RecipeDetailsViewController alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// Pass the Recipe object to the controller</span>
	Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self.recipes objectAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>;
	controller.recipe <span style="color: #002200;">=</span> recipe;
&nbsp;
	<span style="color: #002200;">&#91;</span>self.navigationController pushViewController<span style="color: #002200;">:</span>controller animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>controller release<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>After we have instantiated the controller, we look up the <code>Recipe</code> object in our data model and then pass it on to the new controller. This gives the controller everything it needs to know about the recipe.</p>
<p>We&#8217;re not done yet. In the implementation of <code>RecipeDetailsViewController</code>, we add the <code>viewDidLoad</code> method:</p>

<div class="wp_codebox"><table><tr id="p557146"><td class="code" id="p557code146"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// in RecipeDetailsViewController.m:</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>viewDidLoad
<span style="color: #002200;">&#123;</span>
	<span style="color: #002200;">&#91;</span>super viewDidLoad<span style="color: #002200;">&#93;</span>;
	self.title <span style="color: #002200;">=</span> self.recipe.name;
	self.imageView.image <span style="color: #002200;">=</span> self.recipe.image;
	self.instructionsTextView.text <span style="color: #002200;">=</span> self.recipe.instructions;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Here, we take the <code>Recipe</code>&#8216;s attributes and use them to configure our subviews. We set <code>self.title</code> to the recipe&#8217;s name; the navigation bar will use this as its own title. We set the recipe&#8217;s image on the image view and the instructions on the text view.</p>
<p>This approach works because we assigned the recipe to the view controller before we did <code>pushViewController</code>. If we had done it in the order below, it would not have worked because <code>viewDidLoad</code> would have been called while the <code>recipe</code> property was still nil:</p>

<div class="wp_codebox"><table><tr id="p557147"><td class="code" id="p557code147"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// This is the wrong order!</span>
<span style="color: #002200;">&#91;</span>self.navigationController pushViewController<span style="color: #002200;">:</span>controller animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
controller.recipe <span style="color: #002200;">=</span> recipe;</pre></td></tr></table></div>

<h3>Classes are black boxes</h3>
<p>Maybe you&#8217;re wondering why we&#8217;re giving a <code>Recipe</code> object to the <code>RecipeDetailsViewController</code> when we could have done it as follows:</p>

<div class="wp_codebox"><table><tr id="p557148"><td class="code" id="p557code148"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView didSelectRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	RecipeDetailsViewController<span style="color: #002200;">*</span> controller <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>RecipeDetailsViewController alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
	Recipe<span style="color: #002200;">*</span> recipe <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self.recipes objectAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>;
	controller.title <span style="color: #002200;">=</span> recipe.name;
	controller.imageView.image <span style="color: #002200;">=</span> recipe.image;
	controller.instructionsTextView.text <span style="color: #002200;">=</span> recipe.instructions;
&nbsp;
	<span style="color: #002200;">&#91;</span>self.navigationController pushViewController<span style="color: #002200;">:</span>controller animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>controller release<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>After all, <code>imageView</code> and <code>instructionsTextView</code> are properties on the view controller, so we can access them from outside the class. I advise against doing it like this. It exposes the internal details of <code>RecipeDetailsViewController</code> and it is better to keep those hidden.</p>
<p>This is one of the main principles of object-oriented programming. Each class performs a certain job but from the point of view of someone using that class, it acts as a “black box”. You know what goes into it and you can see what comes out of it, but you have no idea what it does on the inside. And that&#8217;s great, because that is one less thing to worry about (as long as you are guaranteed that the class does its job properly and is fast enough).</p>
<p>Hiding away the details of how a class works helps to reduce the complexity of your program. That makes it easier to understand how all the classes in your program work together, without getting lost in unnecessary details. It also helps to reduce “side effects”, where a change in the implementation of one class causes an unwanted change (usually a bug!) somewhere else in the code. So in short: make your classes as independent from each other as possible!</p>
<p>In our app, the subviews of <code>RecipeDetailsViewController</code> are its own business. The <code>SmoothiesViewController</code> shouldn&#8217;t have to know whether the name of the recipe goes into the Recipe Details screen&#8217;s title bar or in a UILabel, for example. It should just say to the <code>RecipeDetailsViewController</code>, “Here is the name of the recipe. Do with it what you want. I trust you will put it in the right place.”</p>
<p>It is then the responsibility of <code>RecipeDetailsViewController</code> to set the content of its subviews. The <code>SmoothiesViewController</code> doesn&#8217;t need to know how <code>RecipeDetailsViewController</code> does its thing; it just gives it a <code>Recipe</code> object and that&#8217;s it.</p>
<p>Likewise, the <code>RecipeDetailsViewController</code> does not have to be concerned with the list of all the recipes, it just needs to know about a single one. When you tap on another smoothie, we create a new <code>RecipeDetailsViewController</code> and assign it the <code>Recipe</code> object for that particular smoothie. This “separation of concerns” helps to keep the design of your apps simple and clean.</p>
<p>That&#8217;s it. In this chapter you&#8217;ve seen how you can pass data from one view controller to another, and we&#8217;ll be doing this again and again in next chapters.</p>
<p>Our class structure now looks like this:</p>
<div id="attachment_575" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.hollance.com/wp-content/uploads/2011/04/Figure-3-3-Class-structure.png"><img class="size-medium wp-image-575" title="Figure 3-3 Class structure" src="http://www.hollance.com/wp-content/uploads/2011/04/Figure-3-3-Class-structure-300x105.png" alt="Figure 3.3. We added a view controller for the Recipe Details screen." width="300" height="105" /></a><p class="wp-caption-text">Figure 3.3. We added a view controller for the Recipe Details screen.</p></div>
<p><a href="https://github.com/hollance/Smoothies/tree/master/Version%203">Download the source code for this version</a></p>
<p>If you&#8217;re ready for more, head on over to <a href="http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-2/">part 2</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-1/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/04/making-your-classes-talk-to-each-other-part-1/</feedburner:origLink></item>
		<item>
		<title>Drawing Retina Graphics</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/jJzW2wdri4k/</link>
		<comments>http://www.hollance.com/2011/04/drawing-retina-graphics/#comments</comments>
		<pubDate>Fri, 15 Apr 2011 20:32:39 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=536</guid>
		<description><![CDATA[Since the arrival of the iPhone 4, developers need to put two versions of each image into their apps: a low-resolution “Image.png” for all previous iPhone models and a high-resolution “Image@2x.png” for the iPhone 4&#8242;s Retina screen. There are several strategies for creating these higher-resolution images: Draw the image using vectors at 1x scale and [...]]]></description>
			<content:encoded><![CDATA[<p>Since the arrival of the iPhone 4, developers need to put two versions of each image into their apps: a low-resolution “Image.png” for all previous iPhone models and a high-resolution “Image@2x.png” for the iPhone 4&#8242;s Retina screen.</p>
<p>There are several strategies for creating these higher-resolution images:</p>
<ol>
<li>Draw the image using vectors at 1x scale and scale up 200% to get the Retina image.</li>
<li>Draw the image using vectors at 2x scale and scale down 50% to get the low-res image.</li>
<li>Draw the image using pixels at 2x scale and scale down. You can also combine pixels and vectors.</li>
<li>Draw the 1x and 2x images separately, either as vectors or bitmaps.</li>
</ol>
<p>Ideally, you&#8217;d use vectors for everything because they scale better than bitmaps. Vector graphics can scale up or down without quality loss. However, if your image includes a texture background then you&#8217;ll need to use a bitmap anyway. Just never scale bitmaps up, only down.<span id="more-536"></span></p>
<h3>Don&#8217;t use Photoshop to scale down bitmaps</h3>
<p>Scaling down bitmaps in Photoshop is problematic because the various scaling filters (bicubic, nearest neighbor, etc) introduce artifacts. They are designed for scaling photos, not application graphics.</p>
<p>I found the best way to scale down is to take each group of 2&#215;2 pixels and average them into a single pixel. If you observe a few rules when drawing the Retina image, then this type of scaling is comparable to vector scaling</p>
<p>The rules are: snap everything to a 2&#215;2 grid and make all your stroke widths multiples of two. A crisp 3-pixel stroke at high resolution turns into a blurry 2-pixel stroke when scaled down (because you can&#8217;t have 1.5 pixels).</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/04/ScaledDown.png"><img class="aligncenter size-full wp-image-538" title="ScaledDown" src="http://www.hollance.com/wp-content/uploads/2011/04/ScaledDown.png" alt="Different ways of scaling down an @2x image" width="440" height="190" /></a>I wrote a simple command-line utility, <a href="http://www.hollance.com/downloads/ShrinkPng.zip">ShrinkPng</a>, that takes a @2x.png file and halves its dimensions the way I just described. It scales with higher fidelity than Photoshop, so if you&#8217;ve been frustrated by the way Photoshop scales down your high-res images, give this tool a shot.</p>
<p>You run ShrinkPng from the Terminal, like so:</p>
<pre>ShrinkPng Image@2x.png</pre>
<p>It outputs “Image.png”, overwriting any existing file with that name. I only wrote this quickly, so there is no nice user interface. I found that it works best when the input PNG does not have an embedded color profile. You can strip color profiles from PNG files using the <a href="http://pmt.sourceforge.net/pngcrush/">pngcrush</a> tool:</p>
<pre>pngcrush -rem gAMA -rem cHRM -rem iCCP -rem sRGB in.png out.png</pre>
<p>Note that scaling down bitmap text is a bad idea. Fonts are  vector graphics that have embedded hints for drawing at small sizes,  which will generally produce better results than rasterizing a font at  high-resolution and scaling it down by hand, no matter which scaling  algorithm you use.</p>
<h3>Draw your images twice</h3>
<p>Even though it is double the work, I tend to favor the “draw the 1x and 2x images separately” method. A Retina image is more than just the low-resolution image at twice the size. You can see this in the standard navigation bar buttons:</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/04/LowresVsRetina.png"><img class="aligncenter size-full wp-image-539" title="LowresVsRetina" src="http://www.hollance.com/wp-content/uploads/2011/04/LowresVsRetina.png" alt="Low-resolution vs Retina navigation bar button" width="542" height="232" /></a>The strokes in the Retina version are not simply doubled but have additional detail. They look more like a 1.5 pixel stroke than a 2 pixel stroke, which makes the edges slightly softer. Compare also the drop shadow at the bottom of the button.</p>
<p>My current approach goes like this:</p>
<ol>
<li>First draw at 1x, using vectors where possible.</li>
<li>Scale up to 2x. Replace any pixel artwork, such as textures, with a higher resolution version.</li>
<li>Add subtle details to the 2x image.</li>
<li>Export the images separately.</li>
</ol>
<p>The appeal of first drawing the 1x size is that it gives you a good  idea of the limits of your image. If you start out at 2x then you might  be tempted to put in too much detail that will not only get lost when  you scale down, but will also muddy up the low-res image.</p>
<h3>Good tools are hard to find</h3>
<p>As for the actual drawing of the images, I&#8217;m a little disappointed by Photoshop&#8217;s drawing functions. Layer styles are great, but its vector drawing tools leave much to be desired. For anything beyond simple button shapes you have to use a true vector drawing application such as Illustrator.</p>
<p>For the past few years, <a href="http://www.gimp.org/">GIMP</a> has been my image editor of choice. It is open source, has a ton of features and you can&#8217;t beat the price. However, since starting as a freelance iOS developer I&#8217;ve had to bite the bullet and buy Photoshop.</p>
<p>There is no way around it, Photoshop simply is the de facto standard for image work. Clients like to send .psd files and the only reliable way to open them is to have a copy of Photoshop. (You can also view PSD files in QuickTime Player, but that is useless if you need to cut up the design into separate images.)</p>
<p>Photoshop could actually learn a thing or two from GIMP. For example, GIMP lets you easily tweak a marquee selection after you&#8217;ve made it, using a set of dragging handles. You can also alter the radius of rounded rects after the fact. In Photoshop you always have to eye things just right the first time or do it all over again. Very frustrating. (Other wish: snap-to-pixel for everything.)</p>
<p>If not for the fact that I spent a lot of money on it and invested quite a bit of time to learn how to use it, I&#8217;d probably swap Photoshop for the recently released <a href="http://flyingmeat.com/acorn/">Acorn 3.0</a>. It seems to have about the same kind of functionality as far as drawing is concerned and it&#8217;s a lot cheaper!</p>
<p>Acorn also claims to import PSD files, but in my experience you can only trust Photoshop to read PSD files correctly, especially if they contain Smart Objects and vector layers. If you&#8217;re doubting whether to get Photoshop, give Acorn a try first!</p>
<p>As for vector drawing apps, I&#8217;m considering forking over even more cash to Adobe for a copy of Illustrator, but for the time being I&#8217;ll stick to <a href="http://inkscape.org/">Inkscape</a>. This is GIMP&#8217;s little vector brother. It&#8217;s a little less stable than GIMP and it has a number of annoying user interface quirks, but it&#8217;s a pretty good application otherwise.</p>
<p>Unfortunately you can&#8217;t paste an Inkscape drawing as a vector object into Photoshop; that only seems to work with Illustrator.</p>
<p>There is also <a href="http://likethought.com/opacity/">Opacity</a>, but I found its vector drawing tools too limited for my use.</p>
<p>Are there any other, relatively inexpensive, Mac OS X vector drawing tools out there that I may have missed? If you know any, let me know in the comments. Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/04/drawing-retina-graphics/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/04/drawing-retina-graphics/</feedburner:origLink></item>
		<item>
		<title>Promo Codes for Reverse Chord Finder Pro</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/Kb9TynQZ6bU/</link>
		<comments>http://www.hollance.com/2011/04/promo-codes-for-reverse-chord-finder-pro/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 22:50:04 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=530</guid>
		<description><![CDATA[Besides doing contract work, I also have a few apps of my own in the App Store. The one I am most proud of is Reverse Chord Finder Pro, a cool utility app for musicians. It lets you choose notes on an instrument &#8212; piano, guitar, music staff &#8212; and then it tells you what [...]]]></description>
			<content:encoded><![CDATA[<p>Besides doing <a href="http://www.hollance.com/freelance">contract work</a>, I also have a few apps of my own in the App Store. The one I am most proud of is <a href="http://www.reversechord.com">Reverse Chord Finder Pro</a>, a cool utility app for musicians. It lets you choose notes on an instrument &#8212; piano, guitar, music staff &#8212; and then it tells you what the name of the chord is that you are playing. Very handy if you&#8217;re a songwriter or a music student.</p>
<p>I have a few promo codes left over and I thought it would be nice to give them away to the readers of my blog before they expire. It&#8217;s first come, first serve, so be quick if you want one.</p>
<p>Here are the codes:</p>
<p>FETMJYPHETJF<br />
R7FHFA3L3KWX<br />
9L7K4P4NJ6TN<br />
KPA6XRTKLETX<br />
KJ6PJ63XR6FH</p>
<p>To redeem the promo code, go to the iTunes Store in iTunes and click Redeem. Enter the code and iTunes should start downloading the app. If it doesn&#8217;t work, then you were too late. <img src='http://www.hollance.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>For the lucky few who manage to get their hands on a code, enjoy the app! (And if you like it, I&#8217;d appreciate it if you left a review in the App Store. Thanks!)</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/04/promo-codes-for-reverse-chord-finder-pro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/04/promo-codes-for-reverse-chord-finder-pro/</feedburner:origLink></item>
		<item>
		<title>MHLazyTableImages – Efficiently Load Images for Large Tables</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/JfsJ5aF_HAw/</link>
		<comments>http://www.hollance.com/2011/03/mhlazytableimages-efficiently-load-images-for-large-tables/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 16:53:17 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=495</guid>
		<description><![CDATA[The iOS Developer Library has a sample project named LazyTableImages that demonstrates how to load images asynchronously for a table with many rows. The app first downloads the list of top paid apps from iTunes (this is an XML file) and shows the list of apps in a UITableView. Then it downloads the icons for [...]]]></description>
			<content:encoded><![CDATA[<p>The iOS Developer Library has a sample project named <a href="http://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html">LazyTableImages</a> that demonstrates how to load images asynchronously for a table with many rows.</p>
<p>The app first downloads the list of top paid apps from iTunes (this is an XML file) and shows the list of apps in a <code>UITableView</code>. Then it downloads the icons for the apps in the background and displays them as they become available. Until the icon is loaded, a placeholder image is visible instead.</p>
<p>Only the icons for the visible rows are downloaded; when you scroll the table to make new rows visible, it downloads the icons for these new rows (but only when you are done scrolling).</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/03/MHLazyTableImages-Screenshot.png"><img class="size-medium wp-image-500 alignright" title="MHLazyTableImages Screenshot" src="http://www.hollance.com/wp-content/uploads/2011/03/MHLazyTableImages-Screenshot-159x300.png" alt="Screenshot of the MHLazyTableImages demo project" width="159" height="300" /></a></p>
<p>For a recent client project, I needed to do something similar on several different screens. I took the code from this sample project and rewrote it so it was more generic and could be reused among my different view controllers. Today I decided to refactor this some more and make the code available as an open source component. That component is named <code>MHLazyTableImages</code> and you can <a href="https://github.com/hollance/MHLazyTableImages">download it at github</a>.</p>
<p>To demonstrate how to use this class, I modified Apple&#8217;s original LazyTableImages sample. The logic for downloading the images is now handled by the <code>MHLazyTableImages</code> and <code>MHImageCache</code> classes. The table view controller only has to create an instance of <code>MHLazyTableImages</code> and connect its data model and table view to it.</p>
<p>To put an image into a table view cell, you simply call <code>-addLazyImageForCell:withIndexPath:</code>. This will first see if the image is already present in the cache and will download it if not.</p>

<div class="wp_codebox"><table><tr id="p495151"><td class="code" id="p495code151"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>UITableViewCell<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UITableView<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>tableView cellForRowAtIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	UITableViewCell<span style="color: #002200;">*</span> cell <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>tableView dequeueReusableCellWithIdentifier<span style="color: #002200;">:</span>...<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>cell <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span>
		cell <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UITableViewCell alloc<span style="color: #002200;">&#93;</span> initWithStyle<span style="color: #002200;">:</span>...<span style="color: #002200;">&#93;</span>;
&nbsp;
	cell.textLabel.text <span style="color: #002200;">=</span> ...;
	<span style="color: #002200;">&#91;</span>lazyImages addLazyImageForCell<span style="color: #002200;">:</span>cell withIndexPath<span style="color: #002200;">:</span>indexPath<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Of course, you need to tell <code>MHLazyTableImages</code> about the URL for the image. That happens in a delegate callback method:</p>

<div class="wp_codebox"><table><tr id="p495152"><td class="code" id="p495code152"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/"><span style="color: #400080;">NSURL</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>lazyImageURLForIndexPath<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/"><span style="color: #400080;">NSIndexPath</span></a><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>indexPath
<span style="color: #002200;">&#123;</span>
	AppRecord<span style="color: #002200;">*</span> appRecord <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self.entries objectAtIndex<span style="color: #002200;">:</span>indexPath.row<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/"><span style="color: #400080;">NSURL</span></a> URLWithString<span style="color: #002200;">:</span>appRecord.imageURLString<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>I used a delegate &#8212; rather than telling <code>MHLazyTableImages</code> directly what the URL should be for the cell &#8212; in order to accommodate scrolling. While scrolling, we don&#8217;t want the images to load yet. We will defer downloading until the user stops scrolling. What that happens, <code>-lazyImageURLForIndexPath:</code> is automatically called for the newly visible rows.</p>
<p>There are a few more things that need to happen to make it all work, but that is the gist of it.</p>
<p>Just for fun, I also replaced the original networking code with <a href="http://allseeing-i.com/ASIHTTPRequest/">ASIHTTPRequest</a>. I was already using this class in <code>MHImageCache</code>, and it allowed me to use blocks instead of delegates. That means the demo project will work only on OS 4 and up.</p>
<p><a href="https://github.com/hollance/MHLazyTableImages">Check out the demo project</a> (<code>RootViewController</code> in particular) to see how everything works in detail.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/03/mhlazytableimages-efficiently-load-images-for-large-tables/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/03/mhlazytableimages-efficiently-load-images-for-large-tables/</feedburner:origLink></item>
		<item>
		<title>Design Idea: A Better Touch Screen</title>
		<link>http://feedproxy.google.com/~r/hollance/~3/GeG7gQNRrJU/</link>
		<comments>http://www.hollance.com/2011/03/design-idea-a-better-touch-screen/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 20:33:45 +0000</pubDate>
		<dc:creator>Matthijs</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://www.hollance.com/?p=475</guid>
		<description><![CDATA[I think tablets such as the iPad are great! They are getting really close to replacing desktop computers and laptops for a lot of people. I expect that in a year or two, many home users will not upgrade to a new PC but will get a tablet instead. The average user browses the internet, [...]]]></description>
			<content:encoded><![CDATA[<p>I think tablets such as the iPad are great! They are getting really close to replacing desktop computers and laptops for a lot of people. I expect that in a year or two, many home users will not upgrade to a new PC but will get a tablet instead.</p>
<p>The average user browses the internet, sends email, and occasionally writes something in Word. The iPad is already capable of handling these tasks and many more; it just needs to be able to print wirelessly to any printer and you&#8217;re all set.</p>
<p>The iPhone and iPad have proven that touch as the primary mode of interaction works wonderfully well. The problem with today&#8217;s touch screens, however, is that there really isn&#8217;t much to touch. They are completely flat and smooth. Our fingers deserve more than that!</p>
<p><a href="http://www.hollance.com/wp-content/uploads/2011/03/ipad.jpg"><img class="aligncenter size-full wp-image-476" title="iPad with raised buttons" src="http://www.hollance.com/wp-content/uploads/2011/03/ipad.jpg" alt="iPad with raised buttons" width="450" height="336" /></a><br />
I imagine a touch screen where the outer glass layer consists of a matrix of squares that can be configured, electronically, to go up and down. This layer allows the programmer to create a terrain of bumps and holes on top of the pixels that make up the visual display.</p>
<p>When the app shows an on-screen keyboard, for example, it will also send signals to this tactile feedback layer to form actual button shapes on top of the pixel buttons. Tap one of those button shapes and the software will make it sink into the screen, giving the user the impression that he is tapping an actual button. If the refresh speed is quick enough, say 1/10th of a second, then this effect will be believable to the user.</p>
<p>Not every pixel needs to have a “bump”. I&#8217;m thinking that one bump per group of 4 pixels will be sufficient to make this work, with each bump having three possible positions: flat, raised or lowered. The raised position would be half a millimeter or so above the surface. Likewise, the lowered position would sink that same distance into the screen.</p>
<p>Seen from the side, it might look something like this:<br />
<a href="http://www.hollance.com/wp-content/uploads/2011/03/display.jpg"><img class="aligncenter size-full wp-image-477" title="Diagram of how the tactile layer works" src="http://www.hollance.com/wp-content/uploads/2011/03/display.jpg" alt="Diagram of how the tactile layer works" width="450" height="270" /></a>Maybe if this technology becomes sufficiently advanced, several heights could be possible instead of just raised/flat/lowered. Ideally, there would be at least one bump per pixel. With this kind of configuration, the feel of real textures such as wood can be emulated. If the refresh speed is quick enough, even moving things such as a vibrating guitar string could be reproduced. Blind people could read braille straight from the device.</p>
<p>Of course this is wishful thinking. I doubt the technology to do anything remotely like this exists today and I don&#8217;t have a clue how one would go ahead and build it. Nanotechnology maybe &#8212; you don&#8217;t want any wires to be visible on top of the display &#8212; but that&#8217;s something of the far-away future. Also, because the glass is now no longer flat, care would need to be taken that the underlying picture does not get distorted.</p>
<p>Still, it&#8217;s fun to think of these things. Anyone already working on tech like this? <img src='http://www.hollance.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.hollance.com/2011/03/design-idea-a-better-touch-screen/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.hollance.com/2011/03/design-idea-a-better-touch-screen/</feedburner:origLink></item>
	</channel>
</rss>

