<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
> <channel><title>akosma software &#187; Tech</title> <atom:link href="http://akosma.com/category/tech/feed/" rel="self" type="application/rss+xml" /><link>http://akosma.com</link> <description>Leading international provider of cross-platform and multilingual software solutions, for iPhone, iPad, Mac, Windows, Linux, Android, and the web.</description> <lastBuildDate>Thu, 17 May 2012 15:41:30 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.2</generator> <item><title>Our Open Source Projects</title><link>http://akosma.com/2012/04/24/our-open-source-projects/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=our-open-source-projects</link> <comments>http://akosma.com/2012/04/24/our-open-source-projects/#comments</comments> <pubDate>Tue, 24 Apr 2012 17:34:03 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[Open Source]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[code]]></category> <category><![CDATA[Github]]></category> <category><![CDATA[open source]]></category> <category><![CDATA[projects]]></category> <guid
isPermaLink="false">http://akosma.com/?p=3444</guid> <description><![CDATA[A quick reminder of our most popular open source projects on Github: bluewoki Cortito CoreTextWrapper dotfiles eBook-Template iPhoneWebServicesClient nib2objc Senbei Teaching Editor Feel free to fork and enjoy! Similar Posts: A nicer cortito, courtesy of Zerofee Senbei 1.3 hits the App Store! Introducing the Teaching Editor More nib2objc fun bluewoki 2.0 Hits the App Store!]]></description> <content:encoded><![CDATA[<p>A quick reminder of our most popular open source projects on Github:</p><ul><li><a
href="http://bluewoki.com/">bluewoki</a></li><li><a
href="http://akosma.github.com/cortito/">Cortito</a></li><li><a
href="http://akosma.github.com/CoreTextWrapper/">CoreTextWrapper</a></li><li><a
href="http://akosmasoftware.github.com/dotfiles/">dotfiles</a></li><li><a
href="http://akosmasoftware.github.com/eBook-Template/">eBook-Template</a></li><li><a
href="http://akosma.github.com/iPhoneWebServicesClient/">iPhoneWebServicesClient</a></li><li><a
href="http://akosma.github.com/nib2objc/">nib2objc</a></li><li><a
href="http://akosmasoftware.github.com/Senbei/">Senbei</a></li><li><a
href="http://akosmasoftware.github.com/TeachingEditor/">Teaching Editor</a></li></ul><p>Feel free to fork and enjoy!</p><p><strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2010/07/22/a-nicer-cortito-courtesy-of-zerofee/" rel="bookmark" title="July 22, 2010">A nicer cortito, courtesy of Zerofee</a></li><li><a
href="http://akosma.com/2011/09/27/senbei-1-3-hits-the-app-store/" rel="bookmark" title="September 27, 2011">Senbei 1.3 hits the App Store!</a></li><li><a
href="http://akosma.com/2012/04/23/introducing-the-teaching-editor/" rel="bookmark" title="April 23, 2012">Introducing the Teaching Editor</a></li><li><a
href="http://akosma.com/2010/07/18/more-nib2objc-fun/" rel="bookmark" title="July 18, 2010">More nib2objc fun</a></li><li><a
href="http://akosma.com/2011/09/15/bluewoki-2-0-hits-the-app-store/" rel="bookmark" title="September 15, 2011">bluewoki 2.0 Hits the App Store!</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2012/04/24/our-open-source-projects/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Introducing the Teaching Editor</title><link>http://akosma.com/2012/04/23/introducing-the-teaching-editor/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introducing-the-teaching-editor</link> <comments>http://akosma.com/2012/04/23/introducing-the-teaching-editor/#comments</comments> <pubDate>Mon, 23 Apr 2012 10:02:56 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[Mobile Web]]></category> <category><![CDATA[Open Source]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[Ext.js]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[jQuery Mobile]]></category> <category><![CDATA[Node.js]]></category> <category><![CDATA[Sencha Touch]]></category> <category><![CDATA[TeachingEditor]]></category> <category><![CDATA[tool]]></category> <category><![CDATA[training]]></category> <guid
isPermaLink="false">http://akosma.com/?p=3440</guid> <description><![CDATA[We are very happy to introduce our latest open source project: the [Teaching Editor][13]. This project provides an online editor that automatically reloads the contents of an iPhone-sized frame. It also provides students with a read-only mode, allowing them to follow in real time whatever code is written in the screen of the teacher, and [...]]]></description> <content:encoded><![CDATA[<p>We are very happy to introduce our latest open source project: the
[Teaching Editor][13]. This project provides an online editor that
automatically reloads the contents of an iPhone-sized frame. It also
provides students with a read-only mode, allowing them to follow in real
time whatever code is written in the screen of the teacher, and they can
also download the current state of the code at any moment.</p><p>It is built exclusively in JavaScript, using the following libraries:</p><ul><li><a
href="http://ace.ajax.org/">Ace</a></li><li><a
href="http://www.sencha.com/products/extjs/">Ext.js</a></li><li><a
href="http://nodejs.org/">Node.js</a></li><li><a
href="http://expressjs.com/">Express</a></li></ul><p><img
src="https://github.com/akosmasoftware/TeachingEditor/raw/master/screenshot.png" alt="" border="0" width="440" class="alignnone size-medium" /></p><h2>Requirements</h2><h3>Server</h3><p>Use <a
href="http://mxcl.github.com/homebrew/">Homebrew</a> to install <a
href="http://nodejs.org/">Node.js</a> in your system. Also, install <a
href="http://npmjs.org/">npm</a> and install <a
href="http://expressjs.com/">Express</a> and <a
href="http://socket.io/">Socket.IO</a> with npm.</p><p>The <code>install.sh</code> script performs all the required operations to install
external dependencies in your system.</p><h3>Client</h3><p>The client has been tested successfully on several combinations of
operating systems and browsers:</p><ul><li>Cross-platform browsers:<ul><li>Firefox 10</li><li>Chrome 17</li><li>Opera 11</li></ul></li><li>OS X &#8220;Lion&#8221;<ul><li>Safari 5.1</li></ul></li><li>Windows 7<ul><li>Internet Explorer 9</li></ul></li><li>iOS<ul><li>Mobile Safari for iOS 5.1 on the iPad (in this case, however,
scrolling is not possible)</li></ul></li></ul><p>Pay attention to the fact that the mobile libraries themselves might not
be compatible with some of these browsers (in particular, Sencha Touch
only works on Webkit-based browsers).</p><h2>How to Use</h2><ul><li><code>./install.sh</code> (this will download the required libraries, only
required once)</li><li><code>./launch.js</code> (this launches the Node.js app and opens a browser
window)</li><li>Students can browse to the IP shown in the dialog of the &#8220;Project /
Show Share URL&#8221; menu entry.</li></ul><h2>License</h2><p>This project is released under the GPLv3 license. Please check the <a
href="https://github.com/akosmasoftware/TeachingEditor/blob/master/LICENSE">LICENSE</a> file for details.</p><p>[13]:http://akosmasoftware.github.com/TeachingEditor<strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2011/10/19/attending-senchacon-2011/" rel="bookmark" title="October 19, 2011">Attending SenchaCon 2011</a></li><li><a
href="http://akosma.com/2012/04/24/our-open-source-projects/" rel="bookmark" title="April 24, 2012">Our Open Source Projects</a></li><li><a
href="http://akosma.com/2012/03/13/mobile-web-training-in-zurich/" rel="bookmark" title="March 13, 2012">Mobile Web Training in Zürich!</a></li><li><a
href="http://akosma.com/2011/12/20/announcing-eerv-cal-an-iphone-android-and-web-application/" rel="bookmark" title="December 20, 2011">Announcing EERV cal, an iPhone, Android and Web Application!</a></li><li><a
href="http://akosma.com/2010/10/04/integrating-ios-applications-with-backend-rest-services/" rel="bookmark" title="October 4, 2010">Integrating iOS Applications with Backend REST Services</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2012/04/23/introducing-the-teaching-editor/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Getting the Next and the Previous NSIndexPath Instances</title><link>http://akosma.com/2012/04/20/getting-the-next-and-the-previous-nsindexpath-instances/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=getting-the-next-and-the-previous-nsindexpath-instances</link> <comments>http://akosma.com/2012/04/20/getting-the-next-and-the-previous-nsindexpath-instances/#comments</comments> <pubDate>Fri, 20 Apr 2012 10:33:42 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[Tech]]></category> <category><![CDATA[code]]></category> <category><![CDATA[Education]]></category> <category><![CDATA[iOS]]></category> <guid
isPermaLink="false">http://akosma.com/?p=3436</guid> <description><![CDATA[Very often, when you work with UITableViewControllers driven by NSFetchedResultsControllers, that you want to get the &#8220;previous&#8221; or the &#8220;next&#8221; elements in the results controller. Visually, this operation corresponds, from the point of view of the user, to select the cell that sits immediately above or below from the currently selected one. Of course, you [...]]]></description> <content:encoded><![CDATA[<p>Very often, when you work with <code>UITableViewController</code>s driven by <code>NSFetchedResultsController</code>s, that you want to get the &#8220;previous&#8221; or
the &#8220;next&#8221; elements in the results controller. Visually, this operation
corresponds, from the point of view of the user, to select the cell that
sits immediately above or below from the currently selected one.</p><p>Of course, you can&#8217;t just <code>++</code> on the current <code>NSIndexPath</code>, because
these objects have both a <code>section</code> and a <code>row</code> component, and the math
required to jump from one to the other can be quite cumbersome; instead,
it would be useful to have a reusable set of methods, and avoid the
clutter in our controllers.</p><p>I have created a very simple category on the NSFetchedResultsController
class that retrieves the &#8220;next&#8221; and the &#8220;last&#8221; <code>NSIndexPath</code> given any
other <code>NSIndexPath</code>; this can be dropped and reused in your projects and
is very simple to use.</p><p><span
id="more-3436"></span></p><h2>Interface</h2><pre><code>#import &lt;CoreData/CoreData.h&gt;
@interface NSFetchedResultsController (AKOLibrary)
- (NSIndexPath *)ako_incrementIndexPath:(NSIndexPath *)oldIndexPath;
- (NSIndexPath *)ako_decrementIndexPath:(NSIndexPath *)oldIndexPath;
@end
</code></pre><h2>Implementation</h2><pre><code>#import "NSFetchedResultsController+AKOLibrary.h"
@implementation NSFetchedResultsController (AKOLibrary)
- (NSIndexPath *)ako_incrementIndexPath:(NSIndexPath *)oldIndexPath
{
    NSIndexPath *nextIndexPath = nil;
    id &lt;NSFetchedResultsSectionInfo&gt; sectionInfo = [[self sections] objectAtIndex:oldIndexPath.section];
    NSInteger rowCount = [sectionInfo numberOfObjects];
    NSInteger nextRow = oldIndexPath.row + 1;
    NSInteger currentSection = oldIndexPath.section;
    if (nextRow &lt; rowCount)
    {
        nextIndexPath = [NSIndexPath indexPathForRow:nextRow inSection:currentSection];
    }
    else
    {
        NSInteger sectionCount = [[self sections] count];
        NSInteger nextSection = currentSection + 1;
        if (nextSection &lt; sectionCount)
        {
            nextIndexPath = [NSIndexPath indexPathForRow:0 inSection:nextSection];
        }
    }
    return nextIndexPath;
}
- (NSIndexPath *)ako_decrementIndexPath:(NSIndexPath *)oldIndexPath
{
    NSIndexPath *previousIndexPath = nil;
    NSInteger nextRow = oldIndexPath.row - 1;
    NSInteger currentSection = oldIndexPath.section;
    if (nextRow &gt;= 0)
    {
        previousIndexPath = [NSIndexPath indexPathForRow:nextRow inSection:currentSection];
    }
    else
    {
        NSInteger nextSection = currentSection - 1;
        if (nextSection &gt;= 0)
        {
            previousIndexPath = [NSIndexPath indexPathForRow:0 inSection:nextSection];
        }
    }
    return previousIndexPath;
}
@end
</code></pre><h2>How to use</h2><p>To use this class, just do the following:</p><pre><code>NSIndexPath *indexPath = [NSIndexPath indexPathForRow:19 inSection:4];
NSIndexPath *next = [controller ako_incrementIndexPath:indexPath];
NSIndexPath *previous = [controller ako_decrementIndexPath:indexPath];
</code></pre><p>If the <code>NSIndexPath</code> (19,4) was the last of whole table, <code>next</code> would be <code>nil</code>. The same, if <code>NSIndexPath</code> was the first (0, 0), then <code>previous</code> would be <code>nil</code>. In all other situations, the <code>next</code> and <code>previous</code> index
paths will correspond to the cells immediately above or below from the
current table.</p><p>Hope this helps!<strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/" rel="bookmark" title="June 3, 2010">Objective-C Categories as Stylesheets</a></li><li><a
href="http://akosma.com/2012/01/31/determining-delegate-object-method-call-in-objective-c-with-nsproxy/" rel="bookmark" title="January 31, 2012">Determining Delegate Object Method Call Order in Objective-C with NSProxy</a></li><li><a
href="http://akosma.com/2011/03/28/smart-pointers-in-objective-c/" rel="bookmark" title="March 28, 2011">Smart Pointers in Objective-C++</a></li><li><a
href="http://akosma.com/2011/01/21/advanced-ios-4-2-training-course-zurich-february-7th-and-8th-2011-enroll-now/" rel="bookmark" title="January 21, 2011">Advanced iOS 4.2 Training Course &#8211; Zürich, February 7th and 8th 2011 &#8211; Enroll now!</a></li><li><a
href="http://akosma.com/2011/02/17/nib2objc-featured-on-the-changelog/" rel="bookmark" title="February 17, 2011">nib2objc Featured on The Changelog</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2012/04/20/getting-the-next-and-the-previous-nsindexpath-instances/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Determining Delegate Object Method Call Order in Objective-C with NSProxy</title><link>http://akosma.com/2012/01/31/determining-delegate-object-method-call-in-objective-c-with-nsproxy/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=determining-delegate-object-method-call-in-objective-c-with-nsproxy</link> <comments>http://akosma.com/2012/01/31/determining-delegate-object-method-call-in-objective-c-with-nsproxy/#comments</comments> <pubDate>Tue, 31 Jan 2012 10:50:53 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[Tech]]></category> <category><![CDATA[code]]></category> <category><![CDATA[Education]]></category> <category><![CDATA[iOS]]></category> <guid
isPermaLink="false">http://akosma.com/?p=3364</guid> <description><![CDATA[This is a guest post + code, wrote together with Joe D&#8217;Andrea from LiquidJoe LLC! Many developers new to the iOS platform have trouble understanding the delegate architecture, in the sense that many other OO toolkits use properties to configure the characteristics of UI elements, instead of having a separate object doing the job. When [...]]]></description> <content:encoded><![CDATA[<p>This is a guest post + code, wrote together with <a
href="https://github.com/jdandrea">Joe
D&#8217;Andrea</a> from <a
href="http://www.liquidjoe.biz/">LiquidJoe
LLC</a>!</p><p>Many developers new to the iOS platform have trouble understanding the
delegate architecture, in the sense that many other OO toolkits use
properties to configure the characteristics of UI elements, instead of
having a separate object doing the job.</p><p>When using delegates, the sequence of calls for each method is
important: most Cocoa developers know that UITableView instances call
delegate and data source methods roughly in this order:</p><ul><li>numberOfSections:</li><li>numberOfRows:inSection:</li><li>cellForRowAtIndexPath:</li><li>configureCellAtIndexPath:</li></ul><p>&#8230;mixing up in the middle some calls to headers and footers and cell
sizes as well. Which prompts the following question: <strong>what is really
going on behind the scenes? Can we know exactly the order in which those
delegate methods are called?</strong></p><p>To answer that question, here&#8217;s a <a
href="https://github.com/akosma/DelegateOrder">small project in
Github</a> that uses all the
delegate and datasource methods in the same project, and that uses NSLog
to show which calls happen first, and when.</p><p><span
id="more-3364"></span></p><h2>Delegate Methods</h2><p>But first, a quick recap on delegate methods in Objective-C.</p><p>In many (if not most) object oriented toolkits, properties tend to be
used when setting up an object such as a table view, for instance in
.NET, as shown in this example from <a
href="http://support.microsoft.com/kb/307860">Microsoft</a></p><pre><code>&lt;%@ Page language="c#" %&gt;
&lt;%@ Import Namespace="System.Data" %&gt;
&lt;%@ Import Namespace="System.Data.SqlClient" %&gt;
&lt;script runat="server"&gt;
void Page_Load(Object sender, EventArgs e)
{
   SqlConnection cnn = new
       SqlConnection("server=(local);database=pubs;Integrated Security=SSPI");
   SqlDataAdapter da = new SqlDataAdapter("select * from authors", cnn);
   DataSet ds = new DataSet();
   da.Fill(ds, "authors");
   Repeater1.DataSource = ds.Tables["authors"];
   Repeater1.DataBind();
}
&lt;/script&gt;
&lt;html&gt;
&lt;body&gt;
   &lt;form id="WebForm2" method="post" runat="server"&gt;
      &lt;asp:Repeater id="Repeater1" runat="server"&gt;
         &lt;ItemTemplate&gt;
         &lt;%# DataBinder.Eval(Container.DataItem,"au_id") %&gt;&lt;br&gt;
         &lt;/ItemTemplate&gt;
      &lt;/asp:Repeater&gt;
   &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre><p>In the code above (a classic ASP.NET page) the <code>Repeater1</code> instance (of
the <code>Repeater</code> class, which is a view component) is &#8220;bound&#8221; (a classic
example of &#8220;databinding&#8221;) to an instance of a <code>DataSet</code>. In this case,
we just call the <code>.DataBind()</code> method on the repeater object, and the
view component is filled with the data inside.</p><p>The advantage of this approach is that it is simpler from the point of
view of the developer; a couple of lines of code are usually enough.
However, this design tends to break the MVC model, because it creates a
direct dependency between the model and the view component. This
coupling makes it hard to modify the model of the application without
breaking the view layer.</p><p>In Objective-C this pattern is seldom used. Instead, an object will opt
to let someone else do the job for them. That other object is known as
the <strong>delegate object</strong>, and the methods to be implemented (sometimes
optionally) are referred to as a protocol. In this model, there is a
controller object that acts as intermediate between the view and the
model, effectively creating a decoupled MVC architecture.</p><p>In Objective-C, an object tells the compiler that it implements a
protocol using this syntax:</p><pre><code>@interface MyAppDelegate : NSObject &lt;UIApplicationDelegate&gt;
@end
</code></pre><p>The inclusion of <code>&lt;UIApplicationDelegate&gt;</code> signals that this class
conforms to the UIApplicationDelegate protocol. Meanwhile, in
UIApplication.h, you will see this:</p><pre><code>@protocol UIApplicationDelegate &lt;NSObject&gt;
@optional
- (void)applicationDidFinishLaunching:(UIApplication *)application;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
...
@end
</code></pre><p>Thus, MyAppDelegate.m may optionally respond to <code>-applicationDidFinishLaunching:</code> and <code>-application:didFinishLaunchingWithOptions:</code>. (In this particular case,
be aware that the former method is used by apps prior to iOS 3.0, and
that the latter method should now be used instead.)</p><h2>More about Delegates</h2><p>It is up to the class in question to determine when to call a delegate
method, and in what order. This order is of particular interest when it
comes to iOS Table Views. In fact, go ahead and press Cmd-Shift-O in
Xcode right now. Search for and open UITableView.h.</p><p>Look inside. There&#8217;s a lot to take in here! In fact, that&#8217;s a good idea
- take a moment to browse this header. (Go ahead. We&#8217;ll wait.) A Cocoa
developer can write apps and never look once inside these header files.
To borrow (abuse?) a classic Apple mantra, we code different. We want to
get our hands dirty and look inside at the engine &#8230; or at least as
much of it as possible. The instance variables are out of our reach, but
there are plenty of other things to take in.</p><p>UITableView is unusual in that it declares two protocols, whereas most
classes you come across will only declare one.</p><p>The UITableViewDelegate is responsible for mediating all table cell
display and behavior. A quick look at the protocol makes this abundantly
clear. There are methods covering custom display, variable height,
headers and footers, accessories, selection, editing, reordering, and
indentation.</p><pre><code>@protocol UITableViewDelegate &lt;NSObject, UIScrollViewDelegate&gt;
</code></pre><p>UITableViewDataSource represents the data model object. While it
supplies no information about appearance &#8212; of the cells or otherwise &#8211;
this doesn&#8217;t mean it avoids cells altogether. There are methods covering
cell view creation (and, more importantly, reuse), the number of
sections and rows, titles for headers and footers, index titles along
the right-hand side, plus cell editing, insertion, deletion, and moving.</p><p>In this protocol, two methods are required:</p><pre><code>- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
</code></pre><p>The rest are optional. That&#8217;s right, even -numberOfSectionsInTableView:, which you almost always see implemented like so:</p><pre><code>- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}
</code></pre><p>However, the header tells us that the default value is 1 if this is not
implemented! If all you have is one section, save yourself some extra
coding and leave it out. Aren&#8217;t well-documented header files great?</p><p>Now there has to be some degree of bootstrapping involved with setting
up these delegates. This is accomplished via properties:</p><pre><code>@property (nonatomic,assign) id &lt;UITableViewDataSource&gt; dataSource;
@property (nonatomic,assign) id &lt;UITableViewDelegate&gt;   delegate;
</code></pre><p>&#8230; and usually set to self:</p><pre><code>// Set the table view and data source delegates:
myTableView.delegate = self;
myTableView.dataSource = self;
</code></pre><p>If you use a UITableViewController, this is done for you automagically,
in addition to several other niceties. (We heart UITableViewController.
Use it early. Use it often!)</p><h2>Delegate Method Call Order</h2><p>Great. So we have two delegate objects that can receive almost 30 method
calls combined. Not five. Not ten. Thirty. Helpful as the delegate
design pattern is, it&#8217;s easy to get confused knowing which method will
be called at which time. Thus, it can also be instructive to know what
order these methods are called.</p><p>You can probably guess a few of them right off the bat. For instance,
-tableView:numberOfSections: is likely called before
-tableView:numberOfRows:inSection:. It&#8217;s not always so clear cut,
though.</p><p>So <em>how do we trace Objective-C messages anyway?</em> One possibility is to
set up an Xcode breakpoint and declare this as an action (borrowed from <a
href="http://stackoverflow.com/questions/1029962/nsobjcmessageloggingenabled-with-iphone-3-0">StackOverflow</a>):</p><pre><code>while 1
printf "[%s %s]", (char *)object_getClassName($r0), (char *) $r1
c
end
</code></pre><p>Hmm &#8230; maybe not.</p><p>Is it possible to trace Objective-C messages en masse? As a matter of
fact, <a
href="http://www.dribin.org/dave/blog/archives/2006/04/22/tracing_objc/">it is</a>:</p><p>On the iPhone Simulator, you can compile with the <code>NSObjCMessageLoggingEnabled</code> Foundation environment variable set to
YES, then look in <code>/tmp/msgSends-&lt;pid&gt;</code> (where <pid> is your running
app&#8217;s process id).</pid></p><p>You&#8217;ll also get a deluge of messages, accent on deluge.</p><p>What else? You could use (<a
href="http://developer.apple.com/technotes/tn2004/tn2124.html">the undocumented</a>) <code>-instrumentObjcMessageSends:</code> to toggle logging on and off.</p><p>Hmm. This isn&#8217;t looking so good. &#8220;There&#8217;s got to be a better way!&#8221;</p><p>We can certainly drop breakpoints in each of our delegate methods and
trace through them, but wouldn&#8217;t it be nice to just log the call order
of our class delegates in one swell foop, without resorting to
undocumented or cumbersome means?</p><h2>Using an NSProxy</h2><p>Of course there is. That&#8217;s why we wrote this blog post, after all, so
we&#8217;re going to show you how it&#8217;s done. Best of all, you can use this
technique for any class. Roll up your sleeves and let&#8217;s get started.</p><p>[This code is adapted from
http://blog.jayway.com/2009/03/06/proxy-based-aop-for-cocoa-touch/]</p><p>Remember, we&#8217;re operating under the notion that you know your way around
Xcode and have already built a project or two! In Xcode, create a new
&#8220;Master-Detail&#8221; iOS Application called DelegateOrder. We&#8217;re going to use
a PTV prefix for all of our classes (why? Long story <img
src='http://akosma.com/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Thanks to the wonders of modern template technology, our root view
controller happens to be a table view. How convenient!</p><p>Time to create a new class. Right-click on the Classes group in Xcode,
and choose New File&#8230; from the popup menu. Add an Objective-C Cocoa
Touch subclass of NSObject, and name it PTVControllerProxy. Open
PTVControllerProxy.h and change it to look like this:</p><pre><code>@interface PTVControllerProxy : NSProxy
+ (id&lt;UITableViewDataSource, UITableViewDelegate&gt;)proxyWithTableViewController:(UITableViewController *)controller;
- (id)initWithTableViewController:(UITableViewController *)controller;
@end
</code></pre><p>Notice anything different?</p><p>We have not so secretly replaced the NSObject Xcode usually serves with
a dark, sparkling NSProxy object. (Footnote: This is a cultural
reference to a famous Folgers coffee commercial that ran in the US in
the &#8217;80s. Not sure if it aired worldwide though!) Like NSObject, NSProxy
is a root class, except it also <em>conforms</em> to NSObject, plus it adds a
few methods of its own. Here&#8217;s the header:</p><pre><code>#import &lt;Foundation/NSObject.h&gt;
@class NSMethodSignature, NSInvocation;
@interface NSProxy &lt;NSObject&gt; {
    Class   isa;
}
+ (id)alloc;
+ (id)allocWithZone:(NSZone *)zone;
+ (Class)class;
- (void)forwardInvocation:(NSInvocation *)invocation;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel;
- (void)dealloc;
- (void)finalize;
- (NSString *)description;
+ (BOOL)respondsToSelector:(SEL)aSelector;
@end
</code></pre><p>NSProxy objects act as stand-ins for other objects. In our case, we&#8217;ll
use PTVControllerProxy as our table view&#8217;s dataSource and delegate. It
will also know about our actual Table View Controller (and table view)
so that it can pass messages down the line.</p><p>The next item of interest is our private instance variable, _controller,
a pointer to a UITableViewController object.</p><p>Following the Coding Guidelines for Cocoa, we always make our instance
variables private. We also add a leading underscore &#8212; just like Apple
does with their own headers &#8212; so as to distinguish them from
properties. This further enforces class interaction through properties
and methods. Meanwhile, on the implementation side, sometimes you want
to access the instance variable. Other times, you need to use the
property. Underscores make it clear which is which.</p><p>In this case, we&#8217;re not creating a property &#8230; at least not one that&#8217;s
publicly available. More on that later.</p><p>We&#8217;ve also defined one class method and one instance method:</p><pre><code>+ (id&lt;UITableViewDataSource, UITableViewDelegate&gt;)proxyWithTableViewController:(UITableViewController *)controller;
</code></pre><p>Our class method takes a UITableViewController and returns an object
that conforms to both the Table View Data Source and Delegate protocols.</p><pre><code>- (id)initWithTableViewController:(UITableViewController *)controller;
</code></pre><p>Our designated initializer method (called by the class method) does the
deed of setting our controller property.</p><p>Did we mean _controller instance variable? No, we meant property. Now
press Cmd-Option-Up-Arrow to switch to the implementation file and make
it look like this:</p><pre><code>#import "PTVControllerProxy.h"
@interface PTVControllerProxy ()
@property (nonatomic, assign) UITableViewController *controller;
- (void)logInvocation:(NSInvocation *)invocation;
@end
@implementation PTVControllerProxy
@synthesize controller = _controller;
@end
</code></pre><p>Ah-ha! So that&#8217;s where the property went.</p><p>We have included yet another interface declaration for
PTVControllerProxy, and this time we&#8217;re extending it beyond what we
originally declared in the header. The parentheses after @interface
PTVControllerProxy signify that this is a class extension. In this case,
we&#8217;ve declared a property and a method that isn&#8217;t exposed to the outside
world. It&#8217;s not private per se, but it&#8217;s not visible in the header
either. Next, in the implementation, we&#8217;ve synthesized a property named
controller, which is represented by the instance variable named
_controller.</p><p>Due to the architecture of Objective-C, you could make a few end-runs
around this and still get at the property and methods. You just have to
know how they&#8217;re defined. Be careful of doing this with Apple&#8217;s classes
though. Them&#8217;s grounds for App Store rejection!</p><p>You can even override extensions previously defined in the header,
making this technique quite handy for exposing readwrite properties as
readonly. Read more about Categories and Extensions in The Objective-C
Programming Language.</p><p>We&#8217;ll discuss <code>-logInvocation:</code> in a moment, but you probably have a
good idea of what it will do just by looking at the name.</p><p>Time to add our methods. Heads up: Some of these may &#8212; or will &#8212; be a
bit unfamiliar. All we are doing here is implementing the minimum number
of methods to handle proxying for our table view controller, and then
some.</p><p>The following should be added between @synthesize and @end in our class
implementation. First, we add our previously defined initializers, and
our lone NSObject method:</p><pre><code>#pragma mark - Initializers
+ (id&lt;UITableViewDataSource, UITableViewDelegate&gt;)proxyWithTableViewController:(UITableViewController *)controller
{
    return [[[[self class] alloc] initWithTableViewController:controller] autorelease];
}
- (id)initWithTableViewController:(UITableViewController *)controller
{
    self.controller = controller;
    return self;
}
#pragma mark - NSObject
- (void)dealloc
{
    [_controller release];
    [super dealloc];
}
</code></pre><p>Our class method takes a table view controller and sends it along to the
designated initializer, which in turn assigns it to the property
controller, and returns itself. As there is no superclass to worry
about, there is no use of <code>[super init]</code> here.</p><p>There&#8217;s one more benefit to our use of private instance variables
beginning with underscores. Our method parameters do not conflict with
like-named instance variables! Look at this line again:</p><pre><code>self.controller = controller;
</code></pre><p>This dot notation is 100% equivalent to:</p><pre><code>[self setController:controller];
</code></pre><p>Very clean, consistent, and easy to read. Contrast this with the
scenario where our instance and method variable named matched. We would
have to code methods like this:</p><pre><code>- (id)initWithTableViewController:(UITableViewController *)theController
{
    self.controller = theController;
    return self;
}
</code></pre><p>It should also be pointed out that these method names are not haphazard.
Apple does in fact provide a method (pun intended) for naming methods!
The previously mentioned Coding Guidelines for Cocoa tells all. Take the
time to name your instance variables, properties, and methods according
to the guidelines. It&#8217;s worth the effort!</p><p>The dealloc method is also standard-issue. Notice that we work with the
instance variable at this point. After dealloc, the show&#8217;s over for this
class, so we don&#8217;t even bother setting _controller to nil. In other
cases, you would likely want to clear it, using the property to take
advantage of its retain/release smarts in one step:</p><pre><code>// This setter (-setController:) releases _controller for us!
self.controller = nil;
</code></pre><p>Continuing with our NSObject methods, add the following:</p><pre><code>- (BOOL)isKindOfClass:(Class)aClass;
{
    return [self.controller isKindOfClass:aClass];
}
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
{
    return [self.controller conformsToProtocol:aProtocol];
}
- (BOOL)respondsToSelector:(SEL)aSelector;
{
    return [self.controller respondsToSelector:aSelector];
}
</code></pre><p>Be careful here. There are class methods with the same signature like
NSProxy&#8217;s +respondsToSelector:! We&#8217;re responding to NSObject&#8217;s protocol
methods instead, passing (well, proxying) the parameter over to our
table view controller. This takes care of establishing our proxy as
having the same class, protocol conformance, and selector response.
That, in turn, assures us an opportunity to tap in to the deluge of
table view delegate traffic.</p><p>Now, so we just discussed how you can avoid naming collisions between
method parameters and instance variables, and here we have aClass,
aProtocol, and aSelector! This leads us to an important maxim: &#8220;You have
to know the rules before you can break them.&#8221; Use discretion! Here,
we&#8217;re honoring the naming convention established by the authors of
NSObject.h, in particular the NSObject protocol.</p><p>As it turns out, the Protocol and Base Class declarations of <code>-conformsToProtocol:</code> are ever so slightly different:</p><pre><code>// Protocol
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
// Base Class
+ (BOOL)conformsToProtocol:(Protocol *)protocol;
</code></pre><p>Go figure. (It&#8217;s OK. We still love Cocoa. Tasty Cocoa &#8230;)</p><p>Let&#8217;s add two more, slightly longer methods, this time from NSProxy&#8217;s
protocol:</p><pre><code>#pragma mark - NSProxy
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    if ([self.controller respondsToSelector:aSelector])
    {
        return [self.controller methodSignatureForSelector:aSelector];
    }
    else
    {
        return [super methodSignatureForSelector:aSelector];
    }
}
</code></pre><p>Method signatures help us forward along messages we otherwise wouldn&#8217;t
respond to. Here, the message is either bound for our table view
controller or the superclass.</p><pre><code>- (void)forwardInvocation:(NSInvocation *)invocation
{
    SEL selector = [invocation selector];
    if ([self.controller respondsToSelector:selector])
    {
        [self logInvocation:invocation];
        [invocation setTarget:self.controller];
        [invocation invoke];
    }
}
</code></pre><p><code>-forwardInvocation:</code> is used by subclasses to send Objective-C
messages-as-objects (or Invocations) to other objects. For the proxy,
it&#8217;s just a matter of passing the message along to whatever object we
aim to represent. That object, of course, is the table view controller.</p><p>First, we ensure the controller responses to the selector represented by
the invocation. Then, just before we dispatch the invocation using
-invoke, we call &#8211; ta-dah &#8211; our private -loginvocation: method. With
that, we can now log every single solitary table view controller message
that comes our way, all from one place.</p><p>Oh, and look, it&#8217;s invocation and not anInvocation. (You&#8217;re not going to
let us live this one down, are you.)</p><p>At last, we come to the coup de grace of our controller proxy class. Add
this to the implementation:</p><pre><code>#pragma mark - Private
- (void)logInvocation:(NSInvocation *)invocation
{
    SEL selector = [invocation selector];
    NSString *currentMethod = NSStringFromSelector(selector);
    NSString *argument = @"";
    NSMethodSignature *methodSignature = [invocation methodSignature];
    NSInteger argCount = [methodSignature numberOfArguments];
    for (NSInteger index = 3; index &lt; argCount; ++index)
    {
        const char *argType = [methodSignature getArgumentTypeAtIndex:index];
        if (strcmp(argType, "@") == 0)
        {
            id object = nil;
            [invocation getArgument:&amp;object atIndex:index];
            if ([object isKindOfClass:[NSIndexPath class]])
            {
                NSIndexPath *indexPath = (NSIndexPath *)object;
                argument = [NSString stringWithFormat:@"{%d, %d}", indexPath.section, indexPath.row];
            }
        }
        else if (strcmp(argType, "i") == 0)
        {
            NSInteger section;
            [invocation getArgument:&amp;section atIndex:index];
            argument = [NSString stringWithFormat:@"%d", section];
        }
    }
    NSLog(@"%@%@", currentMethod, argument);
}
</code></pre><p>OK! A lot to take in here. Let&#8217;s talk through it.</p><p>Just like in <code>-forwardInvocation:</code>, we grab our selector, or in this case
our delegate message. In preparation for logging, we turn it into a
string called <code>currentMethod</code>. This gives us, for example,
@&#8221;tableView:cellForRowAtIndexPath:&#8221; &#8211; ready for logging.</p><p>Perhaps that would be enough, but we can do better. NSInvocation
contains a NSMethodSignature object with all the arguments, so let&#8217;s
grab a few of those while we&#8217;re at it.</p><p>If you were to look at the method signature&#8217;s arguments, you would soon
discover the first two arguments are always claimed by a few
behind-the-scenes players, (id)self and (SEL)_cmd. Argument indices are
zero-based, so that places us at index 2 for the start of our delegate
methods. Meanwhile, following best practices for delegate method
conventions, the table view is always passed back as the first argument,
in this case index 2. Thus we want to start at index 3, which should
explain this loop construct:</p><pre><code>for (NSInteger index = 3; index &lt; argCount; ++index)
{
    const char *argType = [methodSignature getArgumentTypeAtIndex:index];
...
</code></pre><p>Next, we look at the argument type, returned as constant C string
representing an Objective C argument type. &#8220;@&#8221; represents an object, and
&#8220;i&#8221; represents an integer. Easy enough.</p><p>If we have an object, we check to see if it&#8217;s of class NSIndexPath. If
so, good! We grab the index path&#8217;s row and section, and use that in the
log message. If we have an integer, we simply grab the integer value
instead.</p><p>What if we have no such argument, as in -numberOfSectionsInTableView? No
worries, we&#8217;ll still log the message. We just won&#8217;t have any of these
parameters to go along with it.</p><p>Finally, we log our method and our (possible) lone argument. At last,
the controller proxy is complete.</p><p>We now turn our attention to our table view controller, represented here
by PTVRootViewController. Open the header file first, and change it to
look like this:</p><pre><code>#import &lt;UIKit/UIKit.h&gt;
@interface PTVRootViewController : UITableViewController
{
@private
    id&lt;UITableViewDataSource, UITableViewDelegate&gt; _proxy;
}
@end
</code></pre><p>We&#8217;ve merely added a private instance variable for the proxy object.
Notice that there is no publicly exposed property. We will only be using
the proxy within the confines of the class.</p><p>Now switch to the implementation file and &#8230; remove everything. Nothing
wrong with the pre-fab code here. We&#8217;re just going to start over. Add
this for starters:</p><pre><code>#import "PTVRootViewController.h"
#import "PTVControllerProxy.h"
static NSInteger SECTION_COUNT = 25;
static NSInteger ROW_COUNT = 5;
</code></pre><p>We first import our class header, as well as the proxy header. Next,
because we&#8217;re testing out the proxy, we can keep the data source rather
sparse and simple, but we still want a good number of rows and sections
to work with. We define a few constants to this effect, giving us 25
table view sections, each one with five rows.</p><p>Time for another private extension:</p><pre><code>@interface PTVRootViewController ()
@property (nonatomic, retain) id&lt;UITableViewDataSource, UITableViewDelegate&gt; proxy;
@end
@implementation PTVRootViewController
@synthesize proxy = _proxy;
@end
</code></pre><p>There it is, our internal proxy property, and a bare-bones
implementation, complete with synthesized methods. Next up is our
requisite NSObject method:</p><pre><code>#pragma mark - NSObject
- (void)dealloc
{
    [_proxy release];
    [super dealloc];
}
</code></pre><p>Nothing earth-shattering there. Next up, a bunch of UIViewController
methods:</p><pre><code>#pragma mark - UIViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.proxy = [PTVControllerProxy proxyWithTableViewController:self];
    self.tableView.dataSource = self.proxy;
    self.tableView.delegate = self.proxy;
    self.title = @"Delegate Call Order";
    self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
</code></pre><p>In -viewDidLoad, we create and connect the proxy object. We also take a
moment to set the associated navigation bar&#8217;s title and add a stock edit
button on the right side.</p><pre><code>- (void)viewDidUnload
{
}
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
</code></pre><p>We&#8217;ll disable autorotation for now, so we only respond to portrait
orientation requests.</p><pre><code>- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}
</code></pre><p>At last! Time to add the delegate methods. <em>All of them</em>. That&#8217;s right, <strong>we will respond to every single one</strong>. In doing so, the proxy will get
a chance to work its logging magic. Add the following for starters:</p><pre><code>#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return SECTION_COUNT;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:SECTION_COUNT];
    for (NSInteger index = 0; index &lt; SECTION_COUNT; ++index)
    {
        NSString *sectionTitle = [NSString stringWithFormat:@"%d", index];
        [array addObject:sectionTitle];
    }
    return array;
}
</code></pre><p>Our table view has <code>SECTION_COUNT</code> sections. The section index titles
(along the right side of the table view) will be represented by our
section numbers 0 through 24. This will make it easy to see the effects
of changing our vantage point.</p><p>Let&#8217;s add a few more:</p><pre><code>- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
</code></pre><p>We allow editing and moving of all rows.</p><pre><code>- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"Section %d, row %d", indexPath.section, indexPath.row];
    return cell;
}
</code></pre><p>Here is where the cell generation and reuse takes place. Again, nothing
surprising here. We take advantage of our table view&#8217;s cell queue and
either dequeue or create a cell, setting its text label to the current
cell&#8217;s section and row.</p><pre><code>- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
    else if (editingStyle == UITableViewCellEditingStyleInsert)
    {
    }
}
</code></pre><p>Since we&#8217;re allowing editing (and by editing we mean deletion of cells,
not insertion), we&#8217;ll respond to this method as well, deleting the row
indicated by the indexPath, fading it out as it goes.</p><pre><code>- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return ROW_COUNT;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
    return [title intValue];
}
</code></pre><p>We respond to <code>-tableView:moveRowAtIndexPath:toIndexPath:</code> as well.
Since we aren&#8217;t manipulating any behind-the-scenes data, we don&#8217;t need
to do anything extra. We also offer up <code>ROW_COUNT</code> rows in each section.
Next, we take advantage of our section index titles (which are just
numbers represented as strings), converting them back to integers as
needed.  index is meant to be used with our index title array, which of
course we aren&#8217;t keeping track of. Then again, it&#8217;s simple enough that
we don&#8217;t have to. Each index title maps directly to a like-numbered
section in the table view, so it&#8217;s as simple as returning each title&#8217;s
integer value.</p><p>Two more data source methods and we&#8217;re more than halfway there.</p><pre><code>- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
    return [NSString stringWithFormat:@"Footer for section %d", section];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return [NSString stringWithFormat:@"Header for section %d", section];
}
</code></pre><p>Easy peasy, right? Good! Now for the table view delegate methods. These
are even easier:</p><pre><code>#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellEditingStyleDelete;
}
</code></pre><p>A few more empty methods, again just to get the benefit of logging. We
will also deselect each row in response to it being selected. Next, we
assure that the editing style of each row supports deletion.</p><p>Now we&#8217;ll handle header, footer, and row sizing, plus indentation:</p><pre><code>- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 20.0f;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 20.0f;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44.0f;
}
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 0;
}
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
</code></pre><p>Returning YES for <code>-tableView:shouldIndentWhileEditingRowAtIndexPath:</code> allows the background of the edited row to be indented. This allows the
cell contents to shift and more gracefully accomodate the Delete button
appearing on the right-hand side.</p><pre><code>- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    return proposedDestinationIndexPath;
}
</code></pre><p>We won&#8217;t do anything unusual with proposed moving of cells, so we return
the proposed destination index path.</p><pre><code>- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return @"Delete";
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
    return nil;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    return nil;
}
</code></pre><p>The delete confirmation button will remain @&#8221;Delete&#8221;, and we won&#8217;t be
using views for the section headers or footers. Still, we need to
implement these methods if we are to see them logged!</p><p>Four more methods to go, and our implementation is finished:</p><pre><code>- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    return indexPath;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    return indexPath;
}
</code></pre><h2>Executing the Code</h2><p><img
src="http://akosma.com/wp/wp-content/uploads/2012/01/delegateorder1.png" alt="Delegateorder1" border="0" width="170" height="319" class="alignleft size-full" /></p><p>Congratulations! Let&#8217;s take it for a spin in the Simulator. Before
building your project, bring up the debugger console window by typing
Shift-Cmd-R or selecting Run > Console from the menu. Move the console
off to the side so that you can see what happens next. You might even
want to venture a guess as to which messages and parameters you&#8217;ll see
first. Place your bets!</p><p>Now Build and Run your project using the Debug configuration. The
Simulator will launch and the console will soon be filled with a bunch
of log messages. Do not use the Simulator just yet. Let&#8217;s focus on the
console.</p><p>Thankfully, they will only be concerning our table view controller
delegates. (Otherwise, we would be positively buried with messages. You
think <em>this</em> is a lot of messages, you should see what Objective-C deals
with in a typical app&#8217;s lifetime!)</p><p>Let&#8217;s start at the top and see what we have here. (We have removed the
timestamp and App specific info. Your log lines will be a bit lengthier
by comparison. You might want to make the console window a bit wider to
help keep the lines from wrapping.)</p><pre><code>numberOfSectionsInTableView:
numberOfSectionsInTableView:
</code></pre><p>The first thing we&#8217;re asked for is the number of sections in our table
view &#8230; and we&#8217;re asked for this information <em>twice</em>. (Your guess is as
good as ours.)</p><p>Remember, we have 24 sections in our table view.</p><pre><code>tableView:viewForHeaderInSection:24
tableView:titleForHeaderInSection:24
tableView:heightForHeaderInSection:24
tableView:heightForHeaderInSection:24
tableView:viewForFooterInSection:24
tableView:titleForFooterInSection:24
tableView:heightForFooterInSection:24
tableView:heightForFooterInSection:24
</code></pre><p>Next, we see a bunch of messages pertaining to one section, in this case
section 24. First the headers, then the footers. Here we have two more
examples of a twice-called method in <code>-tableView:heightForHeaderInSection:</code> and <code>-tableView:heightForFooterInSection:</code>.</p><p>So the order so far is as follows (eliminating duplicate invocations):</p><pre><code>numberOfSectionsInTableView:
</code></pre><p>Then, for each section, the header and footer information:</p><pre><code>tableView:viewForHeaderInSection:
tableView:titleForHeaderInSection:
tableView:heightForHeaderInSection:
tableView:viewForFooterInSection:
tableView:titleForFooterInSection:
tableView:heightForFooterInSection:
</code></pre><p>You can imagine that the title is not needed (and the relevant method
not called) if a view is returned, so it makes sense that the view is
asked for first.</p><p>Armed with our section count, the table view turns its attention to the
rows, starting with &#8230; the last one?</p><pre><code>tableView:numberOfRowsInSection:24
tableView:heightForRowAtIndexPath:{24, 0}
tableView:heightForRowAtIndexPath:{24, 1}
tableView:heightForRowAtIndexPath:{24, 2}
tableView:heightForRowAtIndexPath:{24, 3}
tableView:heightForRowAtIndexPath:{24, 4}
</code></pre><p>We have 5 rows in each section, which explains the index paths from {24,
0} through {24, 4}. The height is returned for each. So far, so good.</p><p>Now it would appear as if we&#8217;re starting at the end of the list and
working our way backward, but the next thing you see is this:</p><pre><code>tableView:viewForHeaderInSection:0
tableView:titleForHeaderInSection:0
tableView:heightForHeaderInSection:0
tableView:heightForHeaderInSection:0
tableView:viewForFooterInSection:0
tableView:titleForFooterInSection:0
tableView:heightForFooterInSection:0
tableView:heightForFooterInSection:0
tableView:numberOfRowsInSection:0
tableView:heightForRowAtIndexPath:{0, 0}
tableView:heightForRowAtIndexPath:{0, 1}
tableView:heightForRowAtIndexPath:{0, 2}
tableView:heightForRowAtIndexPath:{0, 3}
tableView:heightForRowAtIndexPath:{0, 4}
</code></pre><p>Is UITableView darting back and forth between the beginning and the end?
(Answer: No. The next section it inquires about is section 1, all the
way up to 23.) In fact, if you recompile this with only three sections,
numbered 0 through 2, you&#8217;ll get a similar outcome with the section
order: 2, 0, and 1.</p><p>So what&#8217;s happening here? Why does UITableView need to know about the
last section first? [Note: Unknown! Any insights?]</p><pre><code>sectionIndexTitlesForTableView:
</code></pre><p>Now that UITableView knows all the row heights, you shouldn&#8217;t see those
called again unless the table is reloaded. That&#8217;s a good thing too
because calculating those row heights can take some time, depending on
the situation.</p><pre><code>tableView:cellForRowAtIndexPath:{0, 0}
tableView:indentationLevelForRowAtIndexPath:{0, 0}
tableView:canEditRowAtIndexPath:{0, 0}
tableView:willDisplayCell:forRowAtIndexPath:{0, 0}
</code></pre><p>Next up are a series of four messages for each visible row, as well as
those just out of view above and below. Since we&#8217;re at the start of the
content area, we begin with index path {0, 0} and the messages are sent
all the way through index path <code>{1, 3}</code>. The familiar <code>-tableView:cellForRowAtIndexPath:</code> is called first, followed by a
request for the indentation level, and a check to see if the row is
editable.  Last comes <code>-tableView:willDisplayCell:forRowAtIndexPath:</code>.
If you&#8217;ve read the documentation, you know this is your last chance to
make final adjustments before a cell is displayed &#8230; and now we have
proof!</p><pre><code>tableView:viewForHeaderInSection:0
tableView:titleForHeaderInSection:0
tableView:viewForFooterInSection:0
tableView:titleForFooterInSection:0
</code></pre><p>Finally, we have a set of four different messages for the view (or,
failing that, the title) for the header in each visible section. You
probably know that headers are always visible, even when all of a given
section&#8217;s rows are not. This holds true for section footers as well,
only these are kept visible on the bottom of the view instead of the
top.</p><p>In the Debugger console, press return a few times to add some blank
space (or just press Clear Log in the toolbar). Now let&#8217;s try and scroll
another screenful of rows into view and see what happens. Click and drag
the bottom-most row up to the top until Section 2, row 4 is visible.
Here&#8217;s what we get. Note that we have added blank lines in between each
logical group of method invocations.</p><pre><code>tableView:viewForHeaderInSection:0
tableView:titleForHeaderInSection:0
tableView:cellForRowAtIndexPath:{1, 4}
tableView:indentationLevelForRowAtIndexPath:{1, 4}
tableView:canEditRowAtIndexPath:{1, 4}
tableView:willDisplayCell:forRowAtIndexPath:{1, 4}
tableView:viewForFooterInSection:1
tableView:titleForFooterInSection:1
tableView:viewForHeaderInSection:2
tableView:titleForHeaderInSection:2
tableView:cellForRowAtIndexPath:{2, 0}
tableView:indentationLevelForRowAtIndexPath:{2, 0}
tableView:canEditRowAtIndexPath:{2, 0}
tableView:willDisplayCell:forRowAtIndexPath:{2, 0}
tableView:viewForFooterInSection:2
tableView:titleForFooterInSection:2
tableView:cellForRowAtIndexPath:{2, 1}
tableView:indentationLevelForRowAtIndexPath:{2, 1}
tableView:canEditRowAtIndexPath:{2, 1}
tableView:willDisplayCell:forRowAtIndexPath:{2, 1}
tableView:cellForRowAtIndexPath:{2, 2}
tableView:indentationLevelForRowAtIndexPath:{2, 2}
tableView:canEditRowAtIndexPath:{2, 2}
tableView:willDisplayCell:forRowAtIndexPath:{2, 2}
tableView:cellForRowAtIndexPath:{2, 3}
tableView:indentationLevelForRowAtIndexPath:{2, 3}
tableView:canEditRowAtIndexPath:{2, 3}
tableView:willDisplayCell:forRowAtIndexPath:{2, 3}
tableView:viewForHeaderInSection:1
tableView:titleForHeaderInSection:1
tableView:cellForRowAtIndexPath:{2, 4}
tableView:indentationLevelForRowAtIndexPath:{2, 4}
tableView:canEditRowAtIndexPath:{2, 4}
tableView:willDisplayCell:forRowAtIndexPath:{2, 4}
</code></pre><p><img
src="http://akosma.com/wp/wp-content/uploads/2012/01/delegateorder2.png" alt="Delegateorder2" border="0" width="600" height="409" class="alignleft size-full" /></p><p>Of particular interest here are the header and footer related methods.
They appear to be invoked in a rather odd pattern, until you examine the
order that each header and footer appears on screen. Then it makes
perfect sense. Interestingly enough, now that we&#8217;re on the move and have
stopped at a definitive spot, we never see index path {3, 0} on the
radar, which is just out of view, past the bottom.</p><p>What about editing? Add some blank space in your debugger, then tap the
edit button.</p><pre><code>tableView:canEditRowAtIndexPath:{1, 1}
tableView:editingStyleForRowAtIndexPath:{1, 1}
tableView:shouldIndentWhileEditingRowAtIndexPath:{1, 1}
tableView:canMoveRowAtIndexPath:{1, 1}
</code></pre><p>We&#8217;ve already seen -tableView:canEditRowAtIndexPath: invoked, just
before our last chance to adjust the cell prior to display. Now it&#8217;s the
first message in the group, followed by a few additional requests. The
editing style is sought, followed by a request to indent the row while
editing, and rounded out by an inquiry to see if the row can be moved.</p><p>Here&#8217;s another observation. Notice how index path {1, 1} seems to be out
of view in our example, yet we see it being called here. This is
repeated through index path {2, 4} which is just in view, but <em>not</em> index path {3, 0} which is just out of view once again. Why?</p><p>There is a good reason for this behavior. When a header and footer are
covering up rows within their related section (that is, when the header
or footer is pegged to the top or bottom of the visible part of the
view), look for a little bit of transparency, letting the underlying
cells show through. When a header is directly above the first cell in
its section (or when a footer is directly below the last cell in its
section), there are no underlying cells to show through. In our case, we
know each section has a header and footer. Thus, there is no need for
fetching adjacent section/row data until at least the next section&#8217;s
header comes into view.</p><p>Let&#8217;s switch Section 1, rows 3 and 4. With the debugger console in view,
tap and hold index path {1, 4}, just over the three bars (signifying a
movable row). Drag it upward until it switches places with index path
{1, 3} but don&#8217;t let go just. Observe the log:</p><pre><code>tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:{1, 3}
</code></pre><p>Had we been logging this one more completely, it would have looked like this:</p><pre><code>tableView:targetIndexPathForMoveFromRowAtIndexPath:{1, 4}toProposedIndexPath:{1, 3}
</code></pre><p>That&#8217;s all the table view needs to do. Now let go, and the move is complete:</p><pre><code>tableView:moveRowAtIndexPath:toIndexPath:{1, 3}
</code></pre><p>Again, a more complete log would have shown:</p><pre><code>tableView:moveRowAtIndexPath:{1, 4}toIndexPath:{1, 3}
</code></pre><p>Tap Done in the navigation bar, and we see this:</p><pre><code>tableView:canEditRowAtIndexPath:{1, 1}
tableView:canEditRowAtIndexPath:{1, 2}
tableView:canEditRowAtIndexPath:{1, 3}
tableView:canEditRowAtIndexPath:{1, 4}
tableView:canEditRowAtIndexPath:{2, 0}
tableView:canEditRowAtIndexPath:{2, 1}
tableView:canEditRowAtIndexPath:{2, 2}
tableView:canEditRowAtIndexPath:{2, 3}
tableView:canEditRowAtIndexPath:{2, 4}
</code></pre><p>Terrific! Now what other mischief can we cause? Let&#8217;s delete section 2,
row 1 (index path {2, 1}). Add some whitespace to the console, then tap
edit once again, then the red circle at the left of the cell in section
2, row 1.</p><pre><code>tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:{2, 1}
</code></pre><p>Makes sense. The delete button appears (properly labeled). Now tap it to
delete the row.</p><pre><code>tableView:commitEditingStyle:forRowAtIndexPath:{2, 1}
</code></pre><p>First, we commit the editing style for index path {2, 1}. Then we
effectively have a <code>reloadData</code> operation, which causes everything to be
rechecked once again &#8211; headers, footers, row heights, the works. Only
now we start at index path {0, 0} and run all the way clear through {24,
4}. So section 24 gets to go last this time!</p><p>Aaaand &#8230; the app crashes big-time.</p><pre><code> *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1261.5/UITableView.m:920
 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 2.  The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (5), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'
</code></pre><p>Wha happen? Well, our faux data model still thinks there are 24 sections
of five rows each. Obviously that doesn&#8217;t match up with the table view&#8217;s
reality. In short, &#8220;table view fall down go boom.&#8221;</p><p>Well, it was fun while it lasted <img
src='http://akosma.com/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> Get the <a
href="https://github.com/akosma/DelegateOrder">whole source code on
Github</a> and we hope it&#8217;ll be useful to you!</p><p><strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2012/04/20/getting-the-next-and-the-previous-nsindexpath-instances/" rel="bookmark" title="April 20, 2012">Getting the Next and the Previous NSIndexPath Instances</a></li><li><a
href="http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/" rel="bookmark" title="June 3, 2010">Objective-C Categories as Stylesheets</a></li><li><a
href="http://akosma.com/2011/03/28/smart-pointers-in-objective-c/" rel="bookmark" title="March 28, 2011">Smart Pointers in Objective-C++</a></li><li><a
href="http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/" rel="bookmark" title="September 20, 2011">A Proposed Architecture for Network-Bound iOS Apps</a></li><li><a
href="http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/" rel="bookmark" title="October 11, 2010">How knowing C and C++ can help you write better iPhone apps, part 1</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2012/01/31/determining-delegate-object-method-call-in-objective-c-with-nsproxy/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>A Proposed Architecture for Network-Bound iOS Apps</title><link>http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-proposed-architecture-for-network-bound-ios-apps</link> <comments>http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/#comments</comments> <pubDate>Tue, 20 Sep 2011 15:48:17 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[iPad]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[application]]></category> <category><![CDATA[Architecture]]></category> <category><![CDATA[blocks]]></category> <category><![CDATA[delegates]]></category> <category><![CDATA[iOS]]></category> <category><![CDATA[Network]]></category> <category><![CDATA[notifications]]></category> <category><![CDATA[polymorphism]]></category> <guid
isPermaLink="false">http://akosma.com/?p=3094</guid> <description><![CDATA[One of my most popular answers in StackOverflow is the one I gave to the following question: &#8220;What is the best architecture for an iOS application that makes many network requests?&#8221; The problem is the following: let&#8217;s consider a relatively complex application, which has to connect to, and retrieve and send data from different remote [...]]]></description> <content:encoded><![CDATA[<p>One of my <a
href="http://stackoverflow.com/questions/4810289/best-architecture-for-an-ios-application-that-makes-many-network-requests/4823001#4823001">most popular
answers</a> in StackOverflow is the one I gave to the following question: &#8220;What is
the best architecture for an iOS application that makes many network
requests?&#8221;</p><p>The problem is the following: let&#8217;s consider a relatively complex
application, which has to connect to, and retrieve and send data from
different remote resources (from the same origin or from different
ones), all while handling as gracefully as possible different problems
such as &#8220;network not available&#8221;, &#8220;500&#8243; errors, etc, while at the same
time notifying the app about showing popups, enabling and disabling
fields, with many different screens (usually each with its own
controller), and so on.</p><p><img
src="http://akosma.com/wp/wp-content/uploads/2010/02/senbei_icon.png"
alt="senbei_icon.png" border="0" width="170" height="170"
class="alignleft size-full" /></p><p>This article will describe in detail a solution for this problem using <a
href="http://allseeing-i.com/ASIHTTPRequest/">ASIHTTPRequest</a>, my favorite
HTTP library for iOS. The solution involves a bit of object oriented
code, and there is a sample implementation in our <a
href="https://github.com/akosmasoftware/Senbei/">Senbei project in
Github</a> that I am going to
refer to in this article.</p><p>I want to point out that I do not consider this the &#8220;best&#8221; architecture
by any means; it is simply a pattern or structure that has given me
excellent results in many different applications, and which has evolved
over time from many other approaches. If someone else has a better idea,
I&#8217;d be glad to try it! This architecture also has the advantage of being
easy to document, understand, maintain and extend.<span
id="more-3094"></span>In the answer on StackOverflow I just enumerated the different elements
of the architecture; here I will explain the rationale behind every
decision.</p><h2>Singleton, &#8220;Class Cluster&#8221;</h2><p>As I said in the answer, this architecture involves a single object
taking care of network connectivity, which I will call a &#8220;network
manager&#8221;. Typically this object is a singleton (created using <a
href="http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html">Matt
Gallagher&#8217;s Cocoa singleton macro</a>). Basically this is because it&#8217;s a
good way to centralize all the network logic in a single component, and
it is also a very common Cocoa design pattern.</p><p>This object can also be seen as a class cluster, because it uses an army
of individual classes that perform the real work behind the scenes.</p><p>In Senbei, this singleton object is the <a
href="https://github.com/akosmasoftware/Senbei/tree/master/Classes/Helpers/SBNetworkManager">SBNetworkManager</a> class. All the
controllers of the application use the methods of this class to trigger
asynchronous requests to the remote FFCRM server used by the
application. All of these controllers, as well as the application
delegate, are notified of events by means of ad hoc notifications
(defined in the <a
href="https://github.com/akosmasoftware/Senbei/blob/master/Classes/Helpers/SBNotifications.h">SBNotifications.h</a> file).</p><h2>Network Queues</h2><p>The network manager wraps an instance of ASINetworkQueue, and also acts
as its delegate. Network queues are interesting in mobile apps, given
that the available bandwidth varies drastically when the device is
connected through a wifi connection or a low-speed GPRS mobile network.
The network queue will automatically change the number of requests sent
by unit of time depending on the current connectivity, without clogging
the device.</p><p>In our example, SBNetworkManager has a private ivar (well, as private as
Objective-C allows ivars to be) pointing to an instance of
ASINetworkQueue, itself a subclass of NSOperationQueue.</p><h2>One Subclass per Request</h2><p>I create subclasses of ASIHTTPRequest for each kind of network request
that my app requires (typically, for each backend REST interaction or
SOAP endpoint).</p><p>I also create a base class for all the requests of the application; this
allows to centralize some shared behavior in the base class, which
proves handy while extending and refactoring your network code.</p><p>In our example, Senbei has a base class for all the GET requests in the
application, called <a
href="https://github.com/akosmasoftware/Senbei/blob/master/Classes/Helpers/SBNetworkManager/Requests/SBBaseRequest.h">SBBaseRequest</a>. There is another base request, called <a
href="https://github.com/akosmasoftware/Senbei/blob/master/Classes/Helpers/SBNetworkManager/Requests/SBBaseFormDataRequest.h">SBBaseFormDataRequest</a>, which is used for requests that use the POST and
PUT verbs (used to create and modify resources on the server).</p><p>There is also a category on ASIHTTPRequest, to add some methods to any
request create on the system; this is required because SBBaseRequest
inherits from ASIHTTPRequest, while SBFormDataRequest inherits from
ASIHTTPFormDataRequest, which also inherits from ASIHTTPRequest. The
category on the latter allows to inject some common behavior in a way
that classic inheritance does not allow per se.</p><p>For every network interaction in the server, there is a dedicated class
available for the SBNetworkManager; the code is easy to understand, and
the responsibilities are separated and well defined. Should the system
be extended in the future, the extension mechanism will naturally fit
any new request, in a horizontal fashion.</p><p>The following class diagram (generated from the Xcode project using the
excellent [OmniGraffle][9] application) shows how the system is structured
(you can click the diagram to see a larger version).</p><p><a
href="http://akosma.com/wp/wp-content/uploads/2011/09/diagram-large.png"><img
src="http://akosma.com/wp/wp-content/uploads/2011/09/diagram.png" alt="Network manager class diagram" border="0" width="620" height="241" class="alignleft size-full" /></a></p><h2>Polymorphism to the Rescue</h2><p>The network manager doesn&#8217;t know what to do with the result of each
request; hence, it just calls a method <strong>on the request</strong>. Remember,
requests are subclasses of ASIHTTPRequest, so you can just put the code
that manages the result of the request (typically, deserialization of
JSON or XML into real objects, triggering other network connections,
updating Core Data stores, etc). Putting the code into each separate
request subclass, using a polymorphic method with a common name accross
request classes, makes it very easy to debug and manage them.</p><p>In our example, the SBNetworkManager calls the &#8220;processResponse&#8221; method
in each subclass. This method has an empty implementation in our
category for ASIHTTPRequest, and each individual subclass performs a
different set of operations; some will parse XML, some will just post a
notification; the separation of the logic in each subclass makes it easy
to debug, document, maintain and extend the system.</p><h2>Usage</h2><p>Every time one of my controllers requires some data (refresh,
viewDidAppear, etc), the network manager creates an instance of the
required ASIHTTPRequest subclass, and then adds it to the queue.</p><p>Whenever a request finishes or fails, the network manager is called
(remember, the network manager is the queue&#8217;s delegate). In turn, the
network manager calls a method on the request itself, delegating the
task of the processing of the response to each subclass.</p><p>In Senbei, every method of the SBNetworkManager class just creates an
instance of a dedicated SBBaseRequest subclass, and pushes it into the
wrapped network queue.</p><h2>Notifications</h2><p>The network manager notifies the controllers above about interesting
events using notifications; using a delegate protocol is not a good
idea, because in your app you typically have many controllers talking to
your network manager, and notifications are more flexible.</p><p>However, as with always with notifications, using them requires
planning, naming conventions and documentation. Code using notifications
might be complex to maintain, because the dependencies are not obvious
at first hand; that&#8217;s the price of their flexibility. In Senbei,
notifications are all defined in the same file, so that different
components can use the same constants throughout the application. The
names of the notifications are clear and express the purpose and
circumstance of each one.</p><p>Since iOS 4 there is also the possibility of using blocks as callback
notifications, but then again, I think they just offer an alternative to
delegate protocols; notifications are much more flexible, as many
different objects can be notified of the same event (and receive the
same information through userInfo dictionaries) at once.</p><h2>Conclusion</h2><p>This is how I&#8217;ve been writing many network-bound apps for the past few
years, and frankly it has worked pretty well so far. I can extend the
system horizontally, adding more ASIHTTPRequest subclasses as I need
them, and the core of the network manager stays intact. The
responsibilities is clearly separated, and the class and notification
names give a pretty good idea of the purpose of each request.</p><p>One problem that I haven&#8217;t yet solved with this architecture (and one
that a commenter of my StackOverflow answer points out) is finding a way
to test the system; probably using mock objects, we could simulate
different network conditions, and integrate this knowledge with
automated tests.</p><p>I hope that this architecture is useful to you too! I look forward to
read your comments below.</p><p>[9]:http://www.omnigroup.com/products/omnigraffle/<strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2011/09/27/senbei-1-3-hits-the-app-store/" rel="bookmark" title="September 27, 2011">Senbei 1.3 hits the App Store!</a></li><li><a
href="http://akosma.com/2012/04/24/our-open-source-projects/" rel="bookmark" title="April 24, 2012">Our Open Source Projects</a></li><li><a
href="http://akosma.com/2010/05/28/initwithcontentsofurl-methods-considered-harmful/" rel="bookmark" title="May 28, 2010">initWithContentsOfURL: Methods Considered Harmful</a></li><li><a
href="http://akosma.com/2012/04/23/introducing-the-teaching-editor/" rel="bookmark" title="April 23, 2012">Introducing the Teaching Editor</a></li><li><a
href="http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/" rel="bookmark" title="June 3, 2010">Objective-C Categories as Stylesheets</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Useful 3rd Party Extensions to CoreTextWrapper</title><link>http://akosma.com/2011/07/07/useful-3rd-party-extensions-to-coretextwrapper/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=useful-3rd-party-extensions-to-coretextwrapper</link> <comments>http://akosma.com/2011/07/07/useful-3rd-party-extensions-to-coretextwrapper/#comments</comments> <pubDate>Thu, 07 Jul 2011 09:10:12 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[Open Source]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[collaboration]]></category> <category><![CDATA[contribution]]></category> <category><![CDATA[Core Text]]></category> <category><![CDATA[open source]]></category> <guid
isPermaLink="false">http://akosma.com/?p=3015</guid> <description><![CDATA[Our CoreTextWrapper project in Github is certainly popular! Many developers have told us that they find it easier to approach Core Text using it, providing an easy learning path, showing the key concepts with an easy-to-use example. Some developers have gone the extra mile, though: we have kindly received two enhancements for the project! Jared [...]]]></description> <content:encoded><![CDATA[<p><a
target="_blank" href="https://github.com/akosma/CoreTextWrapper">Our CoreTextWrapper project in Github</a> is certainly popular! Many developers have told us that they find it easier to approach Core Text using it, providing an easy learning path, showing the key concepts with an easy-to-use example.</p><p>Some developers have gone the extra mile, though: we have kindly received two enhancements for the project!</p><ul><li><a
target="_blank" href="https://github.com/JaredCrawford">Jared Crawford</a> contributed support for shadows in AKOCustomFontLabel <a
target="_blank" href="https://github.com/akosma/CoreTextWrapper/commit/66af5409db46410e3cc8f5490ea9f4418e2843be">back in March.</a></li><li>Today, <a
target="_blank" href="http://www.tapwork.de/">Christian Menschel from tapwork.de</a> contributed the AKOMultiColumnTextViewDataSource protocol to add custom views in the text columns.</li></ul><p>These contributions make the CoreTextWrapper a very interesting option to display rich, multi-column text on your iPad application! Thanks to Jared and Christian for the contributions, and don&#8217;t hesitate to send us your pull requests or your changes for us to integrate with the project. We would love to make your code part of this project.</p><p><img
src="http://akosma.com/wp/wp-content/uploads/2011/07/coredatawrapper_view.png" alt="Coredatawrapper view" border="0" width="440" height="315" class="alignnone size-medium" /><strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2010/07/08/core-text-objective-c-wrapper/" rel="bookmark" title="July 8, 2010">Core Text Objective-C Wrapper</a></li><li><a
href="http://akosma.com/2011/01/20/new-project-request-form/" rel="bookmark" title="January 20, 2011">New Project Request Form</a></li><li><a
href="http://akosma.com/2010/07/09/digital2-0/" rel="bookmark" title="July 9, 2010">digital2.0 iPad Application</a></li><li><a
href="http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/" rel="bookmark" title="September 20, 2011">A Proposed Architecture for Network-Bound iOS Apps</a></li><li><a
href="http://akosma.com/2010/10/04/integrating-ios-applications-with-backend-rest-services/" rel="bookmark" title="October 4, 2010">Integrating iOS Applications with Backend REST Services</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2011/07/07/useful-3rd-party-extensions-to-coretextwrapper/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Smart Pointers in Objective-C++</title><link>http://akosma.com/2011/03/28/smart-pointers-in-objective-c/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=smart-pointers-in-objective-c</link> <comments>http://akosma.com/2011/03/28/smart-pointers-in-objective-c/#comments</comments> <pubDate>Mon, 28 Mar 2011 14:31:15 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[Open Source]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[C++]]></category> <category><![CDATA[Github]]></category> <category><![CDATA[Objective-C]]></category> <category><![CDATA[open source]]></category> <category><![CDATA[templates]]></category> <guid
isPermaLink="false">http://akosma.com/?p=2920</guid> <description><![CDATA[One of the coolest features of C++ are templates, of which I&#8217;ve been drooling in the past. One of the most useful things that templates have brought to C++ are smart pointers, which simplify memory management tremendously; they combine the capacity of C++ to instantiate objects in the stack, the flexibility of heap allocation, and [...]]]></description> <content:encoded><![CDATA[<p>One of the coolest features of C++ are templates, of which <a
target="_blank" href="http://kosmaczewski.net/2008/03/13/templates/">I&#8217;ve been drooling in the past</a>. One of the most useful things that templates have brought to C++ are smart pointers, which simplify memory management tremendously; they combine the capacity of C++ to instantiate objects in the stack, the flexibility of heap allocation, and template classes, all in one thing.</p><p>I&#8217;ve talked about them in a <a
target="_blank" href="http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/">previous article in this blog</a>. In C++, a smart pointer will automatically call &#8220;delete&#8221; on the managed pointer when it goes out of scope, simplifying resource management and providing many more advantages over common pointers, as Andrei Alexandrescu explained in chapter 7 of his book <a
target="_blank" href="http://www.amazon.com/Modern-Design-Generic-Programming-Patterns/dp/0201704315">&#8220;Modern C++ Design&#8221;</a>.</p><p>In Objective-C, the &#8220;new&#8221; and &#8220;delete&#8221; keywords are replaced by some combination of &#8220;alloc / init&#8221;, &#8220;copy&#8221;, &#8220;release&#8221;, and &#8220;autorelease&#8221;. But given that Objective-C does not allow for stack allocation of objects (apart from blocks, but <a
target="_blank" href="http://www.mikeash.com/pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html">that&#8217;s another story</a>), I&#8217;ve tried to create such a beast in Objective-C++. <span
id="more-2920"></span> These are the features of my smart pointer:</p><ul><li>It takes ownership of any non-autoreleased object with a retain count of at least 1.</li><li>It has value semantics, that is, it is copied by value from stack frame to stack frame, while the &#8220;owned&#8221; object, as any Objective-C entity, lives happily in the heap.</li><li>When it goes out of scope, its destructor is called, which sends a &#8220;release&#8221; message to the owned object.</li></ul><p>Here&#8217;s how you could use it:</p><div><pre class="brush:c">
for (NSInteger index = 0; index < 10; ++index)
{
    // A SmartPointer around an NSObject
    SmartPointer<NSObject> obj = SmartPointer<nsobject>::create();
    // SomeType is a typedef (see above)
    SomeType someObj = SomeType::create();
    // You can get access to the underlying Objective-C object
    // using "*", ".get()" or "()"; they all return the same pointer.
    // And once you have it, it's a normal Objective-C pointer
    // you can send messages to:
    SmartPointer<nsmutablearray> array = [*someObj createArrayWithCapacity:5];
    // Here a SmartPointer around an NSNumber
    NSNumber *value = [[NSNumber alloc] initWithInt:1424];
    SmartPointer<nsnumber> number = SmartPointer</nsnumber><nsnumber>(value);
    // Playing with the array we got above, just to show it's a normal object
    [array.get() addObject:@"test1"];
    [*array      addObject:@"test2"];
    [*array      addObject:number()];
    [array()     addObject:*obj];
    // After this NSLog call, in the console you should see
    // "[SomeClass dealloc]" which is printed when the SmartPointer goes
    // out of scope, sending the release message on the underlying pointer.
    NSLog(@"array %@", *array);
}
</nsnumber></nsmutablearray></nsobject></pre></div><p>In general, NSAutoreleasePools fit the bill quite comfortably in Objective-C for this kind of tasks, apart from some performance issues in iOS devices (particularly older iPhones and iPod touch devices), but I think there might be cases where just using a &#8220;non-autoreleased&#8221; approach to resource management might be useful, and typing an extra &#8220;[obj release]&#8221; line would be too much to ask <img
src='http://akosma.com/wp/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Of course, this is just an experiment, that I just publish as part of my own curiosity. I would be more than glad to hear some feedback about it from people more knowledgeable in Objective-C and C++ than I am. The code, as usual, is <a
target="_blank" href="https://github.com/akosma/SmartPointerTest">available in Github</a> under a liberal BSD license. Enjoy!</p><p><strong>Update, 2011-03-28:</strong> just found by pure chance <a
href="http://www.levelofindirection.com/journal/2010/8/13/ocptr-a-smart-pointer-for-objective-c.html">another, much more complete</a>, implementation of this idea (note to self: always Google first!) with its <a
href="https://github.com/philsquared/OCPtr">code in Github</a>. <strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/" rel="bookmark" title="October 11, 2010">How knowing C and C++ can help you write better iPhone apps, part 1</a></li><li><a
href="http://akosma.com/2010/07/08/core-text-objective-c-wrapper/" rel="bookmark" title="July 8, 2010">Core Text Objective-C Wrapper</a></li><li><a
href="http://akosma.com/2012/01/31/determining-delegate-object-method-call-in-objective-c-with-nsproxy/" rel="bookmark" title="January 31, 2012">Determining Delegate Object Method Call Order in Objective-C with NSProxy</a></li><li><a
href="http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/" rel="bookmark" title="June 3, 2010">Objective-C Categories as Stylesheets</a></li><li><a
href="http://akosma.com/2010/07/17/nib2objc-updated/" rel="bookmark" title="July 17, 2010">nib2objc updated</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2011/03/28/smart-pointers-in-objective-c/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>How knowing C and C++ can help you write better iPhone apps, part 1</title><link>http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1</link> <comments>http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/#comments</comments> <pubDate>Mon, 11 Oct 2010 06:15:35 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[iPad]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[C++]]></category> <category><![CDATA[code]]></category> <category><![CDATA[CPU]]></category> <category><![CDATA[heap]]></category> <category><![CDATA[iOS]]></category> <category><![CDATA[memory]]></category> <category><![CDATA[Objective-C]]></category> <category><![CDATA[stack]]></category> <category><![CDATA[technology]]></category> <guid
isPermaLink="false">http://akosma.com/?p=2722</guid> <description><![CDATA[While learning how to write iOS applications, you will often encounter the phrase &#8220;learn C first&#8221;. Writers of Cocoa applications apparently benefit from knowing about C (sometimes even C++), but it is not very clear to many new developers how this actually works. The obvious question being &#8220;why should I learn C if actually I [...]]]></description> <content:encoded><![CDATA[<p>While learning how to write iOS applications, you will often encounter the phrase <a
target="_blank" href="http://stackoverflow.com/questions/180549/learn-c-first-before-learning-objective-c/180832#180832">&#8220;learn C first&#8221;</a>. Writers of Cocoa applications apparently benefit from knowing about C (sometimes even C++), but it is not very clear to many new developers how this actually works.</p><p>The obvious question being &#8220;why should I learn C if actually I have to use Objective-C to create my apps?&#8221;, and the answer &#8220;because Objective-C is a superset of C&#8221; is not really useful, albeit technically correct.</p><p>This series of two articles will provide some pointers (no pun intended) to answer that question, in the hopes that new iOS developers will get a copy of the <a
target="_blank" href="http://www.amazon.com/Programming-Language-2nd-Brian-Kernighan/dp/0131103628%3FSubscriptionId%3D0F0YTN83N46JSX6KDT02%26tag%3Dakosmasoftwar-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0131103628">K&amp;R</a> and the <a
target="_blank" href="http://www.amazon.com/C-Programming-Language-Special/dp/0201700735%3FSubscriptionId%3D0F0YTN83N46JSX6KDT02%26tag%3Dakosmasoftwar-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201700735">Stroustrup</a> books soon.</p><h2>Objective-C</h2><p>Before starting with this article, I would like to remind my readers about some key facts of Objective-C, often overlooked by tutorials and teachers, and which explains much of the characteristics of Cocoa as well:</p><ol><li>All methods (at instance and / or class level) are public, virtual and overridable. You can have @public, @private and @protected instance variables (also known as &#8220;ivars&#8221;), but methods are public. And yes, you can override class methods in subclasses, too, which is not a very common pattern (you can do that in C++ through templates, though). <a
target="_blank" href="http://en.wikipedia.org/wiki/Type_polymorphism">Polymorphism is the key to understanding Objective-C.</a></li><li>There is no formal concept of abstract classes. You can override the alloc and init methods of some class to avoid creating instances from it, but a priori, you can create an instance from almost any class.</li><li>You can have as many &#8220;root classes&#8221; as you want. You are not forced to inherit from NSObject, although in most cases that is what you do. In Cocoa there are two root classes already defined for developers to use: NSObject and NSProxy.</li><li>There is no concept of namespaces. That explains the prefix crazyness all over the place, because all classes live in the same planet, so you should better use a nice prefix for your stuff. In my case I usually publish my classes with the &#8220;AKO&#8221; prefix.</li></ol><p><span
id="more-2722"></span></p><h2>Stack and Heap</h2><p>This is the probably the most important thing to know about iOS programming. Many developers, particularly those coming from Java, .NET, PHP or other garbage-collected environments, just don&#8217;t know that the computer memory used by applications is not a uniform space, and that running code uses space in three different, yet complementary, regions of memory, or as computer scientists refer to them, &#8220;segments&#8221;: <a
target="_blank" href="http://www.ualberta.ca/CNS/RESEARCH/LinuxClusters/mem.html">the text, the stack and the heap.</a> <a
target="_blank" href="http://www.boundscheck.com/knowledge-base/c-cpp/memory-layout-in-c/342/"><img
src="http://akosma.com/wp/wp-content/uploads/2010/10/MemoryLayout.gif" alt="MemoryLayout.gif" border="0" width="440" height="344" class="alignnone size-medium" /></a></p><p>The &#8220;text segment&#8221; is where the application code lives in memory while your application runs. Every instruction is there, every single function and procedure and method and executable code lives in that part of memory until your application exits. Usually you don&#8217;t really have to know anything about the text segment, other that it is there.</p><p>When the application starts, the main() function is called and some space is allocated in the &#8220;stack&#8221;. This is another segment of memory allocated for your application, and that&#8217;s where the memory required for the variables of your functions are allocated. Each time you call a function in your program, a section of the stack called a &#8220;frame&#8221; is allocated in the stack. The local variables of this new function are allocated there.</p><p><a
target="_blank" href="http://www.futuregov.asia/photologue/photo/2008/aug/30/stack-papers/"><img
src="http://akosma.com/wp/wp-content/uploads/2010/10/paper_stack_gallery_display.jpg" alt="paper_stack_gallery_display.jpg" border="0" width="170" height="170" class="alignleft size-full" /></a></p><p>As the name implies, the stack is a &#8220;last in &amp; first out&#8221; (or LIFO) structure, and when functions call other functions, stack frames are created; when those functions exit, their frames are destroyed automatically (that&#8217;s why stack objects are usually referred to as &#8220;automatic&#8221; objects). In your code, an &#8220;end&#8221; statement or a closing curly brackets &#8220;}&#8221; visually indicate a delimiter of stack context; when the current execution goes beyond that element, you can be sure that the stack frame is gone.</p><p>The stack region is at the origin of the &#8220;stack overflow&#8221; concept, which frequently happens when using recursive functions; you allocate too many frames, and you run out of space in the stack. Boom. Another interesting problem associated with stacks is that of &#8220;buffer overflows&#8221;, which constitutes one of the most common security problems caused by badly written C code. When you write memory contents in the stack, and you don&#8217;t check the size of your structures, you might end up writing something on the text segment&#8230; which basically means that you might as well be rewriting the code of the application, as it runs. Bad, very bad things can happen then.</p><p><a
target="_blank" href="http://linguiniontheceiling.blogspot.com/2008/10/thats-madame-trash-heap-to-you.html"><img
src="http://akosma.com/wp/wp-content/uploads/2010/10/trash-heap2.jpg" alt="trash heap.jpg" border="0" width="170" height="172" class="alignleft size-full" /></a></p><p>Finally, the &#8220;heap&#8221; (also called the &#8220;data&#8221; segment) provides a storage medium that can last throughout the execution of functions; global and static variables live on the heap, until the application exits. To access whatever data you have created in the heap, you require at least one &#8220;pointer&#8221; on the stack, because that&#8217;s how your CPU can access data in the heap; through the stack. You can think of a pointer as just an integer variable that holds the number of a particular memory address in the heap (it is actually a bit more complicated, but that&#8217;s the basic picture).</p><p>To summarize: the CPU uses the value of the pointer in the stack to access or, as they say, &#8220;dereference&#8221;, the structure in the heap. Without pointer on the stack, no access to the object on the heap. And here lies the reason of all memory leaks: if you lose your pointer for whatever reason, then you have lost track of an object in the heap. And given that the heap is cleared only when your application exits, you have &#8220;leaked&#8221; memory, and you will never be able to recover it again (unless you restart your program, that is, but we don&#8217;t want to ask your user to quit and restart to solve that problem, do we?).</p><p>In C++ you can create objects in both the stack and the heap, and to know how to differentiate between both regions, you have to pay attention to the syntax used to create them:</p><div><pre class="brush:c">
// The variable does not use a "star"!
// Created on the stack, don't use "new"
SomeClass stackObject;
// do not call delete stackObject!!!
// Pay attention to the "star"...
// it's a pointer on the stack!
// We are initializing it to NULL,
// as a rule of thumb.
SomeClass *heapObject = NULL;
// And to create the object, use "new"
// to have it created on the heap
heapObject = new SomeClass;
// you must call this to avoid a leak!
delete heapObject;
</pre></div><p>In the case of the stack object, its destructor is called automatically when the stack frame is removed. In the case of the heap object, what goes away is the pointer variable in the stack&#8230; but not the object on the heap! To avoid that problem, in C you have to balance every malloc() (or calloc() or similar function) with a free(). In C++ you have to balance every call to &#8220;new&#8221; with a call to &#8220;delete&#8221;.</p><p>Now, imagine for a second that you have an object in the stack (an automatic object) that points to some other object in the heap, and that our first object is prepared to call the destructor of the second one. This is how the <a
target="_blank" href="http://en.wikipedia.org/wiki/Auto_ptr">auto_ptr</a> (or &#8220;smart pointer&#8221;) class of the standard C++ template library (STL) works; it takes advantage of the fact that variables on the stack are automatic. Instead of having to manage manually the lifecycle of your objects, an auto_ptr object on the stack will call delete automatically when it goes out of scope:</p><div><pre class="brush:c">
#include <iostream>
#include <memory>
using namespace std;
int main(int argc, char **argv)
{
    // created on the heap
    SomeClass *heapObject = new SomeClass;
    // now the stackPointer owns the heapObject
    auto_ptr<someclass> auto(heapObject);
    // Print non-NULL address of heapObject
    cout < < auto.get() << endl;
    // no need to call delete here!
    // "auto" is an stack object that
    // "owns" heapObject
    // (see below for a discussion
    // about ownership!)
    // and will call the destructor of heapObject
    // automatically when required. Magic!
}
</pre></someclass></memory></iostream></pre></div><p>How does all of this apply to Objective-C? Well, it turns out that the current versions of Objective-C only allow us to create objects on the heap. Apparently creating objects on the stack was possible in early versions of Objective-C, but that isn't the case anymore. All objects that you manipulate in Objective-C live in the heap (*), and as such, if you lose the pointer to them, you have a memory leak. Here goes some code in Objective-C with an obvious memory leak:</p><div><pre class="brush:objc">
- (void)doSomething
{
    NSObject *obj = [[NSObject alloc] init];
    // do something else with obj...
    // and now we forget to release, and boom:
    // Memory leak! This is because the
    // "obj" pointer in the stack is lost
    // when this stack frame is removed...
    // ... but the heap object stays!
}
</pre></div><p>What can you do to avoid that? Two things:</p><ol><li>Remember how in C you balance malloc() with free, and how you balance "new" with "delete" in C++? Well, in Objective-C you have to balance every call to "alloc", "copy" or "retain" with a "release".</li><li>You can also use the "autorelease" method, to add your object to the current autorelease pool, so that it will be automatically disposed of in the next iteration of the run loop cycle. OK, this is slightly more complex, but basically this also solves the memory leak problem.</li></ol><p>Here goes some code illustrating the two solutions in detail:</p><div><pre class="brush:objc">
// First solution
- (void)doSomething
{
    NSObject *obj = [[NSObject alloc] init];
    // do something else with obj...
    [obj release];
}
// Second solution
- (void)doSomething
{
    NSObject *obj = nil;
    obj = [[[NSObject alloc] init] autorelease];
    // do something else with obj...
    // Don't release obj! The object referenced
    // by that pointer will be disposed
    // in the next run loop iteration.
}
</pre></div><p>However, please, please, avoid the following code, which stretches the use of the autorelease pool to the level of abuse(**):</p><div><pre class="brush:objc">
for (NSData *data in veryLargeArrayWithImages)
{
    UIImage *image = [UIImage imagedWithData:data];
    // do something with image
}
</pre></div><p>because this will create an unnecessary large number of instances that will remain in memory until the next run loop cycle (which will probably happen after the end of the current loop, that is, in a long CPU time in the future). Instead, either use a temporary autorelease pool, or use the non-autoreleased version of the code above (which I prefer, particularly in the iPhone):</p><div><pre class="brush:objc">
for (NSData *data in veryLargeArrayWithImages)
{
    UIImage *image = [[UIImage alloc] initWithData:data];
    // do something with image
    [image release];
}
</pre></div><p>All of these memory management techniques are explained in detail in my article <a
target="_blank" href="http://akosma.com/2009/01/28/10-iphone-memory-management-tips/">10 iPhone Memory Management Tips</a>.</p><p>Mike Ash has written an extensive <a
target="_blank" href="http://www.mikeash.com/pyblog/friday-qa-2010-01-15-stack-and-heap-objects-in-objective-c.html">article about stack and heap objects</a> that will help you understand all of these issues even better. Finally, to see visually how the stack and the heap collaborate with each other, and how to keep an object-oriented mindset when writing code in C, I recommend watching on iTunesU the excellent <a
target="_blank" href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=384233005">Programming Paradigm</a> course by professor Jerry Cain from Stanford University.</p><h2>Object ownership</h2><p>Ownership is a key concept in C++ memory management: whenever an object creates or copies another, the first one becomes the "owner" of the second. And as such, it is the task of the first one to destroy the second. Here goes some code that shows that pattern; here some class requires another one, and the ownership relationship is enforced throughout the lifetime of both objects.</p><div><pre class="brush:c">
// Forward declaration of some owned class
class Owned;
// Declaration of the owner
class OwnerClass : BaseClass
{
public:
    OwnerClass();
    virtual ~OwnerClass();
    const Owned&amp; getOwnedObject();
private:
    Owned* _owned;
};
// Constructor implementation
OwnerClass::OwnerClass()
: BaseClass()
, _owned(new Owned)
{
}
// Destructor implementation
OwnerClass::~OwnerClass()
{
    delete _owned;
}
// Provide to clients a reference
// to the underlying owned object
const Owned&amp; OwnerClass::getOwnedObject()
{
    return _owned;
}
</pre></div><p>In Objective-C, the chain of ownership is important to solve the problem of circular references; this is a common problem when creating delegation relationships between objects. When an object is delegate of another, the reference between the object and its delegate must be weak:</p><div><pre class="brush:objc">
// A delegate protocol declaration
@protocol OwnedDelegate <nsobject>
@optional
- (void)ownedObjectSaysSomething:(Owned *)owned;
@end
// Interface of the owner
@interface OwnerClass : NSObject <owneddelegate>
{
@private
    Owned *_owned;
}
@property (nonatomic, retain) Owned *owned;
@end
// Interface of the owned
@interface Owned : NSObject
{
@private
    id</owneddelegate><owneddelegate> _delegate;
}
@property (nonatomic, assign) id</owneddelegate><owneddelegate> delegate;
@end
</owneddelegate></nsobject></pre></div><p>Pay attention at the @property declarations in the code above. The OwnerClass "retains" the Owned object, but the Owned class just "assigns" the delegate. This way, we know clearly who's responsible of releasing who: it is the OwnerClass dealloc method that will do that, and not the other way around!</p><div><pre class="brush:objc">
@implementation OwnerClass
@synthesize owned = _owned;
- (id)init
{
    if (self = [super init])
    {
        _owned = [[Owned alloc] init];
        _owned.delegate = self;
    }
    return self;
}
- (void)dealloc
{
    _owned.delegate = nil;
    [_owned release];
    _owned = nil;
    [super dealloc];
}
#pragma mark -
#pragma mark OwnedDelegate protocol
- (void)ownedObjectSaysSomething:(Owned *)owned
{
    // do something now
}
@end
</pre></div><p>If you don't follow this pattern, you might end up with a circular reference, and the reference counting scheme of Objective-C won't be able to solve this problem, which means that you might end up leaking two instances at once!</p><h2>free() vs. delete vs. dealloc</h2><p>In C, free() is a function taking any pointer as parameter, and whose purpose is to mark the region of memory pointed by the parameter as available for the application. It is up to the application developer to pay attention to properly clean any owned objects in the structures stored in that region, as the standard C runtime makes no assumptions whatsoever about those secondary relations.</p><p>In C++, delete is an operator, and its task is to ultimately call the destructor of the target object, starting by the class of the current object, until it reaches the last class in the inheritance chain, and it does this immediately when called, in a synchronous fashion. Your constructors do not have to call the constructor of the base class in their implementation; it is, however, strongly recommended to <a
target="_blank" href="http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7">mark your destructors as virtual</a>, to ensure that the delete operator does this in all cases.</p><p>On the other hand, dealloc in Objective-C is a polymorphic, virtual, overridable method, not an operator neither a function, and it is never called directly by your code. It is called in a kind of asynchronous fashion, when the current run loop ends, and when the retain count of the current object reaches zero. This means that you might not know exactly when that happens, and actually, you shouldn't care. The important thing is to release all the things you were holding on to (see the "object ownership" section above).</p><p>Another important fact of dealloc is that, being polymorphic, only the implementation of the current class will be called, so you must always remember to add a call to [super dealloc] at the end of your own dealloc. And always, always add it at the end, <a
target="_blank" href="http://stackoverflow.com/questions/909856/why-do-i-have-to-call-super-dealloc-last-and-not-first/909925#909925">not at the beginning</a>, of your own dealloc.</p><h2>Conclusion</h2><p>I hope this information will be useful to developers new to the iOS platform. Objective-C and Cocoa share many characteristics with other similar platforms and frameworks written in C and C++, and developers working with garbage-collected runtimes are not used to know the layout of structures in memory. I think, however, that knowing this is useful also in such environments.</p><p>In the second part of this series I will dive into variable initialization, bitwise masks, functions and other related aspects of C and C++ programming, and how they relate to Objective-C.</p><p>Acknowledgement: Many thanks to <a
target="_blank" href="http://volonbolon.net/">Ariel Rodríguez</a> for reviewing early drafts of this post.</p><p>(*) Well, that is not entirely true; there is one kind of Objective-C object that lives in the stack, and that is <a
target="_blank" href="http://www.mikeash.com/pyblog/friday-qa-2008-12-26.html">blocks</a>. But this is an exception, one that I will tackle in a separate blog post.</p><p>(**) Autorelease pools are definitely material for another blog post.</p><p><strong>Update, 2010-10-13:</strong> Ariel has written an excellent follow up to this article, <a
target="_blank" href="http://volonbolon.net/post/1305559150/stack-overflow">explaining the problem of stack overflows</a>. <strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2011/03/28/smart-pointers-in-objective-c/" rel="bookmark" title="March 28, 2011">Smart Pointers in Objective-C++</a></li><li><a
href="http://akosma.com/2010/06/03/objective-c-categories-as-stylesheets/" rel="bookmark" title="June 3, 2010">Objective-C Categories as Stylesheets</a></li><li><a
href="http://akosma.com/2010/07/08/core-text-objective-c-wrapper/" rel="bookmark" title="July 8, 2010">Core Text Objective-C Wrapper</a></li><li><a
href="http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/" rel="bookmark" title="September 20, 2011">A Proposed Architecture for Network-Bound iOS Apps</a></li><li><a
href="http://akosma.com/2012/01/31/determining-delegate-object-method-call-in-objective-c-with-nsproxy/" rel="bookmark" title="January 31, 2012">Determining Delegate Object Method Call Order in Objective-C with NSProxy</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2010/10/11/how-knowing-c-and-c-can-help-you-write-better-iphone-apps-part-1/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Integrating iOS Applications with Backend REST Services</title><link>http://akosma.com/2010/10/04/integrating-ios-applications-with-backend-rest-services/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=integrating-ios-applications-with-backend-rest-services</link> <comments>http://akosma.com/2010/10/04/integrating-ios-applications-with-backend-rest-services/#comments</comments> <pubDate>Mon, 04 Oct 2010 15:22:14 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[iPhone]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[iOS]]></category> <category><![CDATA[iPad]]></category> <category><![CDATA[REST]]></category> <category><![CDATA[Web services]]></category> <guid
isPermaLink="false">http://akosma.com/?p=2707</guid> <description><![CDATA[A couple of hours ago I finished my presentation at JAOO, a discussion of what I&#8217;ve learnt about integrating REST services in iOS apps while creating the iPhoneWebServicesClient project at Github. This project showcases different transport formats and libraries to consume web services from an iPhone application. It features a server application written in PHP, [...]]]></description> <content:encoded><![CDATA[<p>A couple of hours ago I finished <a
target="_blank" href="http://jaoo.dk/aarhus-2010/presentation/Accessing%20Web%20Services%20From%20iPhone%20and%20iPad%20Applications">my presentation at JAOO</a>, a discussion of what I&#8217;ve learnt about integrating REST services in iOS apps while creating the <a
target="_blank" href="http://github.com/akosma/iPhoneWebServicesClient">iPhoneWebServicesClient project at Github</a>.</p><p>This project showcases different transport formats and libraries to consume web services from an iPhone application. It features a server application written in PHP, a command-line script that saves the output of the server application in different formats, and an iPhone client application (compatible with iPhone OS 3.0 and higher). The server application reads a MySQL database and outputs data in the following formats: HTML, JSON, YAML, XML (arbitrary format), SOAP, Property list (Binary and XML), CSV, and Protocol Buffers.</p><p>As promised, here go the slides and of course, check the <a
target="_blank" href="http://github.com/akosma/iPhoneWebServicesClient">project in Github</a> which actually contains the real thing!</p><div
style="width:425px" id="__ss_5353512"><strong
style="display:block;margin:12px 0 4px"><a
href="http://www.slideshare.net/akosma/integrating-ios-applications-with-backend-rest-services" title="Integrating iOS Applications with Backend REST Services">Integrating iOS Applications with Backend REST Services</a></strong><object
id="__sse5353512" width="425" height="355"><param
name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=restiphoneclient-101004100516-phpapp02&#038;stripped_title=integrating-ios-applications-with-backend-rest-services&#038;userName=akosma" /><param
name="allowFullScreen" value="true"/><param
name="allowScriptAccess" value="always"/><embed
name="__sse5353512" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=restiphoneclient-101004100516-phpapp02&#038;stripped_title=integrating-ios-applications-with-backend-rest-services&#038;userName=akosma" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div
style="padding:5px 0 12px">View more <a
href="http://www.slideshare.net/">presentations</a> from <a
href="http://www.slideshare.net/akosma">Adrian Kosmaczewski</a>.</div></div><p>Although <a
target="_blank" href="http://www.version2.dk/artikel/16464-jaoo-den-foerste-roede-seddel">not everyone liked it</a> (you definitely can&#8217;t please everyone) I&#8217;ve got good feedback from many other attendees and all in all I&#8217;m happy to have shared what I&#8217;ve learnt in this project. Feel free to fork the code and add support for other libraries and configurations! I&#8217;d love to receive feedback about this project. <strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2011/04/30/presentations-at-sdc-2011/" rel="bookmark" title="April 30, 2011">Presentations at SDC 2011</a></li><li><a
href="http://akosma.com/2011/03/31/talking-at-the-scandinavian-developer-conference-2011/" rel="bookmark" title="March 31, 2011">Talking at the Scandinavian Developer Conference 2011</a></li><li><a
href="http://akosma.com/2012/04/23/introducing-the-teaching-editor/" rel="bookmark" title="April 23, 2012">Introducing the Teaching Editor</a></li><li><a
href="http://akosma.com/2011/12/29/trainings-2012-advanced-ios-mobile-web-apps-and-node-js/" rel="bookmark" title="December 29, 2011">Trainings 2012: Advanced iOS, Mobile Web Apps and Node.js</a></li><li><a
href="http://akosma.com/2011/09/20/a-proposed-architecture-for-network-bound-ios-apps/" rel="bookmark" title="September 20, 2011">A Proposed Architecture for Network-Bound iOS Apps</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2010/10/04/integrating-ios-applications-with-backend-rest-services/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Migrating iPhone 3.x apps to iPad and iOS 4.0</title><link>http://akosma.com/2010/07/26/migrating-iphone-3-x-apps-to-ipad-and-ios-4-0/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=migrating-iphone-3-x-apps-to-ipad-and-ios-4-0</link> <comments>http://akosma.com/2010/07/26/migrating-iphone-3-x-apps-to-ipad-and-ios-4-0/#comments</comments> <pubDate>Mon, 26 Jul 2010 08:43:30 +0000</pubDate> <dc:creator>Adrian Kosmaczewski</dc:creator> <category><![CDATA[iPad]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[Tech]]></category> <category><![CDATA[iOS]]></category> <category><![CDATA[migration]]></category> <category><![CDATA[technology]]></category> <category><![CDATA[Xcode]]></category> <guid
isPermaLink="false">http://akosma.com/?p=2597</guid> <description><![CDATA[Right now, creating Universal Applications for the iPod touch, the iPhone and the iPad is not really a straightforward task. The current panorama of iOS-compatible software and hardware platforms is getting more and more complex, and this blog post is a small guide (by no means exhaustive) of tips and tricks that have helped me [...]]]></description> <content:encoded><![CDATA[<p>Right now, creating <a
target="_blank" href="http://devimages.apple.com/iphone/resources/introductiontouniversalapps.pdf">Universal Applications</a> for the iPod touch, the iPhone and the iPad is not really a straightforward task. The current panorama of iOS-compatible software and hardware platforms is getting more and more complex, and this blog post is a small guide (by no means exhaustive) of tips and tricks that have helped me get my apps running in as many platforms as possible, with as few headaches as possible.</p><p>First of all, a few warnings:</p><ul><li>I assume your current applications run in iPhone OS 3.1 as a minimum requirement. Apple does not accept any more applications targeting the 2.x frameworks these days, and the developer tools do not include those anymore.</li><li>I assume your projects <a
target="_blank" href="http://akosma.com/2009/07/16/objective-c-compiler-warnings/">compile and link without warnings</a>; many API calls have been deprecated between 2.x and 4.0, so you&#8217;d better have code using the latest methods and no deprecated ones.</li></ul><h2>Panorama</h2><p>Waiting for an unification of the iPad and the iOS 4 frameworks (probably <a
target="_blank" href="http://adage.com/digital/article?article_id=144670">later this year</a>), the current panorama of software and hardware iOS platforms looks as follows:</p><table
border="1" width="100%"><tr><th
style="text-align: center" rowspan="2" width="25%"></th><th
style="text-align: center" colspan="3" width="25%">iPhone</th><th
style="text-align: center" colspan="2" width="25%">iPod touch</th><th
style="text-align: center" rowspan="2" width="25%">iPad</th></tr><tr><th
style="text-align: center" width="8.3%">3G</th><th
style="text-align: center" width="8.3%">3GS</th><th
style="text-align: center" width="8.3%">4</th><th
style="text-align: center" width="12.5%">2nd gen</th><th
style="text-align: center" width="12.5%">3rd gen</th></tr><tr><td
style="text-align: center"><strong>iPhone OS 3.1</strong></td><td
style="text-align: center"> <strong>x</strong></td><td
style="text-align: center"> <strong>x</strong></td><td></td><td
style="text-align: center"> <strong>x</strong></td><td
style="text-align: center"> <strong>x</strong></td><td></td></tr><tr><td
style="text-align: center"><strong>iPhone OS 3.2</strong></td><td></td><td></td><td></td><td></td><td></td><td
style="text-align: center"> <strong>x</strong></td></tr><tr><td
style="text-align: center"><strong>iOS 4.0</strong></td><td></td><td
style="text-align: center"> (ls)</td><td
style="text-align: center"> <strong>x</strong></td><td
style="text-align: center"> (ls)</td><td
style="text-align: center"> <strong>x</strong></td><td></td></tr><tr><td
style="text-align: center"><strong>Year Released</strong></td><td
style="text-align: center"> 2008</td><td
style="text-align: center"> 2009</td><td
style="text-align: center"> 2010</td><td
style="text-align: center"> 2008</td><td
style="text-align: center"> 2009</td><td
style="text-align: center"> 2010</td></tr><tr><td
style="text-align: center"><strong>RAM (MB)</strong></td><td
style="text-align: center"> 128</td><td
style="text-align: center"> 256</td><td
style="text-align: center"> 512</td><td
style="text-align: center"> 128</td><td
style="text-align: center"> 256</td><td
style="text-align: center"> 256</td></tr><tr><td
style="text-align: center"><strong>CPU (MHz)</strong></td><td
style="text-align: center"> 620</td><td
style="text-align: center"> 833</td><td
style="text-align: center"> 1 GHz</td><td
style="text-align: center"> 620</td><td
style="text-align: center"> 833</td><td
style="text-align: center"> 1 GHz</td></tr></table><p>(ls): limited support, particularly for multitasking.</p><p>For practical purposes, I&#8217;ve omitted in the table above the fact that the iPhone 3G is (theoretically) able to run iOS 4. Something that has been empirically proved to be a <a
target="_blank" href="http://www.tuaw.com/2010/07/22/ios-4-and-iphone-3g-is-a-match-made-in-whats-the-opposite-of/">bad idea</a>. <span
id="more-2597"></span> <img
src="http://akosma.com/wp/wp-content/uploads/2010/07/ios4_icon_20100624.png" alt="ios4_icon_20100624.png" border="0" width="170" height="73" class="alignleft size-full" /></p><h2>Upgrading Xcode Projects to iOS 4</h2><p>Your Xcode 3.1 iPhone project can be migrated to iOS 4 as follows:</p><ul><li>If you are using an SCM with branching support, create a new branch for all of the operations below; you don&#8217;t want to impact your &#8220;trunk&#8221;, or main branch with all these changes, as more urgent bugs might appear while you are doing this.</li><li>Download the <a
target="_blank" href="http://developer.apple.com/iphone/">latest SDK from Apple</a>. This is required by Apple, actually. And the latest version of Xcode (3.2.3 at the time of this writing) allows you to write applications compatible with all the platforms in the table above.</li><li>Open your project with Xcode 3.2.3; select the &#8220;Project / Edit Project Settings&#8230;&#8221; menu and change the &#8220;Base SDK value to iPhone Device 4.0 (yes, even if your project is meant to target iPhone OS 3.1&#8230; stay with me!)</li></ul><p><img
src="http://akosma.com/wp/wp-content/uploads/2010/07/default_sdk_xcode1.png" alt="default_sdk_xcode.png" border="0" width="440" height="608" class="alignnone size-medium" /></p><ul><li>In the &#8220;Targets&#8221; group of your Xcode project, open the &#8220;Info&#8221; panel, select the &#8220;Build&#8221; tab and change the &#8220;iPhone OS Deployment Target&#8221; entry for all the configurations of your target to &#8220;iPhone OS 3.1&#8243;. This will allow your code to be loaded in earlier versions of iOS, even if your application uses iOS 4 as a base SDK for all configurations:</li></ul><p><img
src="http://akosma.com/wp/wp-content/uploads/2010/07/deployment_target_xcode.png" alt="deployment_target_xcode.png" border="0" width="440" height="608" class="alignnone size-medium" /></p><ul><li>Set the UIKit framework, as well as any new framework provided by iOS 4, to link as &#8220;Weak&#8221;; for example, in the screenshot below, taken from the settings of <a
target="_blank" href="http://github.com/akosma/Senbei">my open source Senbei application</a>, you can see that UIKit is weakly linked, as well as the MobileCoreServices framework (which does not exist in iPhone OS 3). This prevents the application from crashing at startup in versions of iOS earlier than 4, because newer versions of UIKit bring new classes and APIs that were not available before:</li></ul><p><img
src="http://akosma.com/wp/wp-content/uploads/2010/07/weak_type_framework.png" alt="weak_type_framework.png" border="0" width="440" height="630" class="alignnone size-medium" /></p><ul><li>Change your Entitlements.plist file, because iOS 4 applications submitted to the App Store require a new format in the Entitlements.plist file. In most cases, you can just delete the previous file, and create a new one from Xcode (&#8220;File / New File&#8230;&#8221;, then select &#8220;Code Signing / Entitlements&#8221; in the dialog that appears).</li></ul><p>Old Entitlements.plist:</p><div><pre class="brush:xml">
< !DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>get-task-allow</key>
    <false />
</dict>
</plist>
</pre></div><p>New Entitlements.plist:</p><div><pre class="brush:xml">
< !DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    
    <key>application-identifier</key>
    <string>$(AppIdentifierPrefix)$(CFBundleIdentifier)</string>
    <key>keychain-access-groups</key>
    <array>
        <string>$(AppIdentifierPrefix)$(CFBundleIdentifier)</string>
    </array>
    
</dict>
</plist>
</pre></div><ul><li>Update your icons and graphics for the new &#8220;Retina&#8221; display of the iPhone 4; <a
target="_blank" href="http://developer.apple.com/iphone/library/qa/qa2010/qa1686.html">Apple has published a special guide</a> that provides all the information required in terms of sizes, formats and naming conventions.</li></ul><p>After doing the steps above, you should have an application running on iPhone OS 3.1, 3.2 (as an iPhone application) and 4.0, offering exactly the same functionality and ready to be sent to the App Store.</p><p><img
src="http://akosma.com/wp/wp-content/uploads/2010/03/ipadbooks.png" alt="ipadbooks.png" border="0" width="170" height="206" class="alignleft size-full" /></p><h2>Create a Universal iPhone and iPad application</h2><p>Creating an iPad-compatible application from your iPhone app requires much more than just adapting your source code; the user experience of iPad apps is a completely different beast than that of iPhone apps, so I strongly recommend you <a
target="_blank" href="http://www.smashingmagazine.com/2010/04/16/design-tips-for-your-ipad-app/">ask a graphic and/or UX designer for help</a>. I can&#8217;t stress this too much; iPad apps aren&#8217;t just &#8220;big&#8221; iPhone apps. They are much, much more.</p><p>Technically speaking, in the simplest of terms, you should be able to migrate most UIKit-based application following the standard path provided by Apple:</p><ul><li>Select your target in Xcode and choose the &#8220;Project / Upgrade Current Target for iPad&#8230;&#8221; menu.</li><li>Use some compile-time and runtime tricks to get different parts of your code to execute in different environments, as explained by <a
target="_blank" href="http://iphonedevelopment.blogspot.com/2010/04/few-more-notes-on-creating-universal.html">Jeff LaMarche</a>:</li></ul><div><pre class="brush:objc">
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        NSLog(@"iPad Idiom");
    else
#else
        NSLog(@"iPhone Idiom");
#endif
</pre></div><h2>Testing your code in different devices</h2><p>My advice is the following: don&#8217;t upgrade your old iPhone to iOS 4, particularly if you own a 3G. Keep it running under 3.1 and get the new iPhone 4 as soon as you can. This has two major advantages:</p><ul><li>You will be sure that there aren&#8217;t crashes or unexpected situations in iPhone OS 3.1, particularly when you are using new APIs in your code.</li><li>The iPhone 3G and 3GS are slower than the new iPhone 4, but they are still (probably not for long) the most widely deployed, particularly in those countries where the iPhone 4 has not yet been released. This will help you create code that uses low memory, and that runs faster in newer models.</li></ul><p>In my personal situation, I have my old iPhone 3G running iPhone OS 3.1.3, and a second generation iPod touch running iOS 4. And of course, my iPad runs iPhone OS 3.2.1.</p><h2>Adapting your code for different platforms</h2><p>Although <a
target="_blank" href="http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadProgrammingGuide/StartingYourProject/StartingYourProject.html">Apple recommends using the UI_USER_INTERFACE_IDIOM macro</a>, sometimes you need a tighter control in your code. For this, I have used three different techniques:</p><ul><li>Use a different class as the app delegate in your iPad application; instead of making your code a mess of &#8220;if&#8221; and &#8220;else&#8221; statements or preprocessor routines, make your iPad application create an instance of a different class, one that might or might not be a child class of the existing application delegate. This way, you can completely separate the code of both platforms, and each can load a different UI control hierarchy, without impacting the existing iPhone OS 3.1 or iOS 4.0 infrastructure.<br
/> You can specify a different class for your iPad app delegate directly in your MainWindow-iPad.xib file, created for you when you selected the &#8220;Project / Upgrade Current Target for iPad&#8230;&#8221; menu (one more advantage of using Interface Builder files in your projects!):</li></ul><p><img
src="http://akosma.com/wp/wp-content/uploads/2010/07/mainwindow_xib_ipad.png" alt="mainwindow_xib_ipad.png" border="0" width="440" height="255" class="alignnone size-medium" /></p><ul><li>Check for symbols at runtime, taking advantage of the dynamic nature of Objective-C; for example, the code below only executes in iOS 4 or later, because the ADBannerView is not available in previous versions of the iPhone OS. This code will run without problems in iPhone OS 3.1! You can also use NSObject&#8217;s &#8220;respondToSelector:&#8221; method to perform runtime checks of the capabilities of your current platform, which might help you branch your code in different directions depending on the context:</li></ul><div><pre class="brush:objc">
- (void)showAdvertising
{
    Class klass = NSClassFromString(@"ADBannerView");
    if (klass)
    {
        ADBannerView *adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0.0, 416.0, 320.0, 50.0)];
        adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifier320x50;
        adView.delegate = self;
        [self.view addSubview:adView];
    }
}
</pre></div><ul><li>Include and use in your project the <a
target="_blank" href="http://github.com/erica/uidevice-extension">UIDevice extensions by Erica Sadun</a>. This very handy set of categories provides a wealth of options, making your code much more readable and easier to understand. Most importantly, it is actively maintained by Erica, and this means that future versions of the categories will be able to detect more features of iOS.</li></ul><p>Finally, MPMoviePlayerController requires special attention, because it&#8217;s widely used in many applications and also because it has been greatly improved (and changed) between iPhone OS 3.1, iPhone OS 3.2 and iOS 4. Those changes include, in some cases, deprecated APIs, so here I&#8217;ll just link to <a
target="_blank" href="http://iphonedevelopertips.com/video/getting-mpmovieplayercontroller-to-cooperate-with-ios4-3-2-ipad-and-earlier-versions-of-iphone-sdk.html">this excellent article by John Muchow</a> in the iPhone Developer Tips blog, which explains all the problems and the possible solutions.</p><h2>Conclusion</h2><p>As you could see, creating universal apps is not easy, but it isn&#8217;t impossible either; it requires a bit of attention and lots of testing. Do you have any tips or links that you would like to share? Feel free to add more information in the comments below. <strong>Similar Posts:</strong></p><ul
class="similar-posts"><li><a
href="http://akosma.com/2010/07/18/more-nib2objc-fun/" rel="bookmark" title="July 18, 2010">More nib2objc fun</a></li><li><a
href="http://akosma.com/2010/07/08/core-text-objective-c-wrapper/" rel="bookmark" title="July 8, 2010">Core Text Objective-C Wrapper</a></li><li><a
href="http://akosma.com/2011/08/23/dropping-support-for-iphone-os-3-x/" rel="bookmark" title="August 23, 2011">Dropping support for iPhone OS 3.x</a></li><li><a
href="http://akosma.com/2010/07/09/digital2-0/" rel="bookmark" title="July 9, 2010">digital2.0 iPad Application</a></li><li><a
href="http://akosma.com/2012/04/23/introducing-the-teaching-editor/" rel="bookmark" title="April 23, 2012">Introducing the Teaching Editor</a></li></ul>]]></content:encoded> <wfw:commentRss>http://akosma.com/2010/07/26/migrating-iphone-3-x-apps-to-ipad-and-ios-4-0/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> </channel> </rss>
