<?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>Progressive Degradation &#187; iPhone</title>
	<atom:link href="http://walterg2.com/category/iphone/feed/" rel="self" type="application/rss+xml" />
	<link>http://walterg2.com</link>
	<description>As tools improve, experience declines</description>
	<lastBuildDate>Tue, 12 Jan 2010 19:07:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Getting More Out of Your UITableViews</title>
		<link>http://walterg2.com/2009/12/09/getting-more-out-of-your-uitableviews/</link>
		<comments>http://walterg2.com/2009/12/09/getting-more-out-of-your-uitableviews/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 04:15:05 +0000</pubDate>
		<dc:creator>walterg2</dc:creator>
				<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Building Your App]]></category>
		<category><![CDATA[Interface Builder]]></category>
		<category><![CDATA[NIB]]></category>
		<category><![CDATA[UITableView]]></category>
		<category><![CDATA[XIB]]></category>

		<guid isPermaLink="false">http://walterg2.com/?p=80</guid>
		<description><![CDATA[Everyone that has built an iPhone application has at one time or another worked with UITableViews. They are pretty much at the heart of most data intensive applications from Twitter clients to just your standard news app. One thing that&#8217;s not too clear is how do you get more from your tables without jamming (usually [...]]]></description>
			<content:encoded><![CDATA[<p>Everyone that has built an iPhone application has at one time or another worked with UITableViews. They are pretty much at the heart of most data intensive applications from Twitter clients to just your standard news app. One thing that&#8217;s not too clear is how do you get more from your tables without jamming (usually with a sledgehammer and your trusty shoe horn) them into a header of a table section header. There isn&#8217;t much information on the net (at least that I found in my multiple searches) that really goes into how to accomplish this as well.<span id="more-80"></span></p>
<h2>Starting out</h2>
<div id="attachment_81" class="wp-caption alignleft" style="width: 172px"><img class="size-medium wp-image-81" title="iphone-wireframe" src="http://walterg2.com/wp-content/uploads/2009/12/iphone-wireframe-162x300.png" alt="Wireframe of what your business wants" width="162" height="300" /><p class="wp-caption-text">Wireframe of what your business wants</p></div>
<p>So, you&#8217;ve been looking to build a view that is mainly a table, yet has something, maybe some instructional text or even a little description of what the view is for, more to make that view easily understood by the user, but you don&#8217;t want to sacrifice the use of your table header either. Of course, this probably came as a result of some sort of downfall you had seen in a previous application that does similar things, so you&#8217;re sold on this being the &#8220;right&#8221; way to do it.</p>
<p>But how do you actually do this and ensure that the view scrolls not just the table, but everything in that view? This was something I struggled with for a few hours, Trying time and time again to manpulate a UIScrollView XIB with a UITableView nested inside. All that did was override the scroll features of the UIScrollView to the UITableView, making the only thing you can scroll the table; not the entire view as desired. Before you lose all of your hair as to why, it&#8217;s basically due to the UITableView being a subclass of UIScrollView.</p>
<h2>How it&#8217;s done</h2>
<p>OK, now that we&#8217;re past trying to get our way through force, let&#8217;s get try some finesse. Given that we&#8217;re really trying to add more information to a UITableView, so why don&#8217;t we try something along those lines. First, we need to create the classes and XIB that will be our view when we&#8217;re done. Do this as you normally would by choosing <strong>File</strong> -&gt; <strong>New File</strong> or <strong>Command-N</strong> if you&#8217;re keyboard motivated. When the New File screen comes up, choose <strong>Cocoa Touch Class</strong> under the iPhone OS section, then <strong>UIViewController subclass</strong>. Make sure you check the two options available; <strong>UITableViewController subclass</strong> and <strong>With XIB for user interface</strong>. Choose <strong>Next</strong>, and create the <strong>.m</strong> and <strong>.h</strong> files.</p>
<p><img class="size-medium wp-image-85 alignright" title="interface-builder-table-view-nib" src="http://walterg2.com/wp-content/uploads/2009/12/interface-builder-table-view-nib-300x299.png" alt="interface-builder-table-view-nib" width="300" height="299" />Now you should have three files available to you: your .m, .h and .xib file so it&#8217;s time to make the XIB do what we want. Open the XIB file either by double-clicking it in XCode, or manually by opening Interface Builder, finding the file and opening the XIB file. To add in the necessary label which is the root of all this additional work, we simply need to do only two more things.</p>
<h2>The two steps</h2>
<p><img class="alignleft size-medium wp-image-86" title="interface-builder-table-view-with-label" src="http://walterg2.com/wp-content/uploads/2009/12/interface-builder-table-view-with-label-300x299.png" alt="interface-builder-table-view-with-label" width="300" height="299" />The first thing to do is to add a UIView as a child of your Table View. Easy enough, just find the UIView in the Library within Interface Builder and drag it into your XIB view where you&#8217;re looking to drop it. Simple enough. The next step is just as simple. We need to add the label. Again, find the Label in the Library and drag it under your UIView that you just added.</p>
<p>I&#8217;m sure you&#8217;re thinking, &#8220;It can&#8217;t be that simple, can it?&#8221; Well, believe it or not, it is. When I figured this out, it was just a shot in the dark as I had first tried everything I could think of by using a UIScrollView and embedding a table inside of it.</p>
<p>There is still a little formatting you will need to do to ensure your view and it&#8217;s label have enough space at the top of your view. But, once you&#8217;re done though, you should have the view of your XIB looking like the image below. You can also add another view and using simple positioning, place it at the bottom of your view, creating the same effect after your table.</p>
<p><img class="aligncenter size-medium wp-image-84" title="interface-builder-table-view-layout" src="http://walterg2.com/wp-content/uploads/2009/12/interface-builder-table-view-layout-206x299.png" alt="interface-builder-table-view-layout" width="206" height="299" /></p>
<h2>In close</h2>
<p>There are drawbacks, of course. Yes, everything has to have some drawback, nothing is free. The one that you need to be aware of is that you cannot build your code for an iPhone OS under 3.0. If you&#8217;re still building apps for 2.2.1 or below, this would be a great opportunity to change that.</p>
<p>If you&#8217;re wondering what spurred me into finding a solution for the problem at the beginning of this article, it was for an application where the &#8220;My Profile&#8221; tab is able to be updated by the server, so we needed a short label informing users that they can download their profile, but changes are not reflected at the server and a button to start the (potential) login and download processes.</p>
<p style="text-align: center;">
     ]]></content:encoded>
			<wfw:commentRss>http://walterg2.com/2009/12/09/getting-more-out-of-your-uitableviews/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Adding SVN Revision Numbers to Your Application&#8217;s Version</title>
		<link>http://walterg2.com/2009/12/07/adding-svn-revision-numbers-to-your-applications-version/</link>
		<comments>http://walterg2.com/2009/12/07/adding-svn-revision-numbers-to-your-applications-version/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 04:45:47 +0000</pubDate>
		<dc:creator>walterg2</dc:creator>
				<category><![CDATA[iPhone]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[Versioning]]></category>
		<category><![CDATA[XCode]]></category>

		<guid isPermaLink="false">http://walterg2.com/?p=48</guid>
		<description><![CDATA[Recently, I&#8217;ve been given an oppotunity at my employer to participate in the next great version of our iPhone application. While it isn&#8217;t something fun and exciting, like ConvertBot or a game such as Eliminate Pro, it does allow me to get my hands dirty in Objective-C and iPhone development. With this experience has come [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I&#8217;ve been given an oppotunity at my employer to participate in the next great version of our iPhone application. While it isn&#8217;t something fun and exciting, like <a title="Visit the Tapbot website" href="http://tapbots.com/convertbot/" target="_blank">ConvertBot</a> or a game such as <a title="Visit the ngmoco website" href="http://eliminate.ngmoco.com/" target="_blank">Eliminate Pro</a>, it does allow me to get my hands dirty in Objective-C and iPhone development. With this experience has come a few things that I found difficult, at best, to spot an answer to within a single location. One of these things is something that, within a large corporation such as the one I work in, will help your support staff determine what version of your application a user currently has. Yes, there are items such as CFBundleVersion and CFBundleShortVersionString that accomplish this for you, but sometimes those may not be enough. Wouldn&#8217;t it be great if you could put the most recent commit revision number from your code repository? Good news, you can!<span id="more-48"></span></p>
<h2>Setting up your info.plist file</h2>
<div id="attachment_49" class="wp-caption alignright" style="width: 160px"><img class="size-thumbnail wp-image-49" title="info-plist-example" src="http://walterg2.com/wp-content/uploads/2009/12/info-plist-example-150x150.png" alt="Example info.plist file" width="150" height="150" /><p class="wp-caption-text">Example info.plist file</p></div>
<p>First thing that you&#8217;ll need to do is set up the info.plist file in your project to carry the appropriate keys you&#8217;re going to need for your project. These are your CFBundleVersion and CFBundleShortVersionString, or, if you prefer to use the interface provided within XCode, &#8216;Bundle version&#8217; and &#8216;Bundle version string, short&#8217;. These are used by Apple and iTunes to let the users know which version of the application you are using. From some simple tests I have done, they appear to check for the &#8216;Bundle version string, short&#8217; key if it exists, and, if not, then fall back to the &#8216;Bundle version&#8217;. For our purposes, we know we do not want the build number shown within the App Store and iTunes, so we need to set up both of these variables.</p>
<p>Since the &#8216;Bundle version&#8217; is going to change at build time to the latest commit revision, you can set this variable to anything you&#8217;d like. I prefer setting it to the same number as what will go in the &#8216;Bundle version string, short&#8217; value. This ensures that, no matter what, an appropriate version number is given to the user.</p>
<h2>Creating the Run Script</h2>
<div id="attachment_60" class="wp-caption alignleft" style="width: 160px"><img class="size-thumbnail wp-image-60" title="target-original-example" src="http://walterg2.com/wp-content/uploads/2009/12/target-original-example-150x150.png" alt="Target Build Steps" width="150" height="150" /><p class="wp-caption-text">Target Build Steps</p></div>
<p>Now that the base is established, it&#8217;s time to move to getting the revision number added at build time. Why at build time do you ask? Basically, if this was added at any time other than during the build, it would put you into a loop where your application&#8217;s revision number is always one commit behind. If the update was done at any other time, you would run into the issue of changing info.plist to be the most recent commit statement, then having a sync to get this code into SVN, thus putting you a commit behind. Repeat ad nauseum until your eyes cross and you give up on the effort altogether.</p>
<p>This is where Apple has stepped in and given you an extremely powerful tool within the build process which allows you to create new Build Phases within your project. During the build of your project, you can execute code in multiple languages including, the Bash Shell, Ruby, Perl and Python, just to name a few. Now, your builds can add additional features such as this revision number by simply adding in a script in the right order in your build.</p>
<div id="attachment_59" class="wp-caption alignright" style="width: 160px"><img class="size-thumbnail wp-image-59" title="add-build-phase-run-script" src="http://walterg2.com/wp-content/uploads/2009/12/add-build-phase-run-script-150x150.png" alt="Example shot of the New Run Script Build Phase" width="150" height="150" /><p class="wp-caption-text">Example shot of the New Run Script Build Phase</p></div>
<p>To do this, you have a few ways to do this. Within XCode, you can choose <strong>Project</strong>, <strong>New Build Phase</strong>, <strong>New Run Build Script Phase</strong> or from the Target in <strong>Groups and Files</strong>, <strong>CTRL</strong>+click on your application, choose <strong>Add</strong>, <strong>New Build Phase</strong>, <strong>New Run Build Script Phase</strong>. This will open a window to allow you to write your script in.</p>
<p>Now, for the fun part. In the language of your choosing, write your code. For this post, I&#8217;m going to use a Bash Shell to add the code necessary for the addition of our SVN Revision number. What we&#8217;re going to do is accomplished in only three lines of code, which, as anyone can agree, is awesome! The down side is that the code isn&#8217;t the most readable unless you&#8217;re very familiar with SED scripting.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">REVISION</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">svnversion</span> <span style="color: #660033;">-nc</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'s/^[^:]*://;s/[A-Za-z]//'</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">APPVERSION</span>=<span style="color: #000000; font-weight: bold;">`/</span>usr<span style="color: #000000; font-weight: bold;">/</span>libexec<span style="color: #000000; font-weight: bold;">/</span>PlistBuddy <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;Print CFBundleShortVersionString&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${TARGET_BUILD_DIR}</span>&quot;</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #800000;">${INFOPLIST_PATH}</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>libexec<span style="color: #000000; font-weight: bold;">/</span>PlistBuddy <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;Set :CFBundleVersion <span style="color: #007800;">$APPVERSION</span> (<span style="color: #007800;">$REVISION</span>)&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${TARGET_BUILD_DIR}</span>&quot;</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #800000;">${INFOPLIST_PATH}</span></pre></div></div>

<p>Now, let&#8217;s explain what we&#8217;ve done. In the first line, we&#8217;re getting the SVN Revision number for the project. This is accomplished by using the <strong>svnversion</strong> program with two flags set, <strong>-n</strong> and <strong>-c</strong>. The -n flag removes the new-line character from the response (something we really don&#8217;t want anyway) and the -c flag asks for the most recent commit for the specific project you&#8217;re running under. We pipe that information into SED and run a quick regular expression on it. Why do we need a RegExp? Well, svnversion -c returns more information than we really need. It sends us back the initial version from when project was created followed by the last committed version. For instance, if you created the project and it was assigned version 500, three weeks later you&#8217;ve had quite a bit of code activity and your final check-in gives you revision number 847. When you run svnversion -c within your project folder, you will get back a result of 500:847. That&#8217;s great, but within you&#8217;re application you&#8217;re only looking for the last number. That&#8217;s where the SED command comes in.</p>
<p>The next line is something I&#8217;ve done in my project, but is, obviously not something that has to be done. Within that code is something important, it&#8217;s a call to an application that comes with XCode called <strong>PlistBuddy</strong>. PlistBuddy, in short, is a tool to read and update plist files which is exactly what we&#8217;re looking to do. The call is simply to store the value of <strong>CFBundleShortVersionString</strong> from our info.plist file to a local variable in the shell script. Since some developers (eh-hem, <a title="Visit Chad's Twitter stream" href="http://twitter.com/chadpredovich" target="_blank">@chadpredovich</a>) like to create their projects within a directory structure with spaces in it, the ${TARGET_BUILD_DIR} is wrapped in quotes to ensure the script doesn&#8217;t fail. Of course, TARGE_BUILD_DIR and INFOPLIST_PATH are variables within the build wrapper that is executing this script, so they&#8217;re available to us as well. Nice, huh?</p>
<p>The final line again uses PlistBuddy, but this time to set the <strong>CFBundleVersion </strong>to the values stored in our two variables, APPVERSION and REVISION.</p>
<div class="mceTemp">
<dl id="attachment_77" class="wp-caption alignleft" style="width: 160px;">
<dt class="wp-caption-dt"><img class="size-thumbnail wp-image-77" title="target-example" src="http://walterg2.com/wp-content/uploads/2009/12/target-example-150x108.png" alt="Move your Run Script to ensure updates to info.plist occur before the build of the application" width="150" height="108" /></dt>
</dl>
</div>
<p>Now that you have the script set up, simply place it in the correct order within the Build Phases. In our case, we want to do this immediately after the &#8216;Copy Bundle Resources&#8217; step inside your Target as the image illustrates.</p>
<h2>Time to add the pretty little bow</h2>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>version <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Version &quot;</span> stringByAppendingString<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>mainBundle objectForInfoDictionaryKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;CFBundleVersion&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>Now that you have the revision number added into the info.plist file, it&#8217;s as simple as pulling that information back out where you want to show it in your application. A little Obj-C magic and your support staff can rest easy that they can easily reproduce the issue a user may be having within your application by ensuring they are building the code from the exact code base that went to Apple.</p>
<h2>Update!!! (2010/01/12)</h2>
<p>When we tried to submit our app to the Apple App Store for review, it was rejected due to an improperly formed CFBundleVersion. It turns out, and is consequently poorly documented, that the CFBundleVersion can only be in the following format NN.N.N Where N is a number from 0 to 9. As you can tell, this means that in an application versioning, the app&#8217;s major version is a number between 0 and 99, minor and revision between 0 and 9. I&#8217;m not sure whether the version numbers are strictly upheld, but I can say that the above post will not be accepted.</p>
<p>Well, back to the drawing board on this one!</p>
     ]]></content:encoded>
			<wfw:commentRss>http://walterg2.com/2009/12/07/adding-svn-revision-numbers-to-your-applications-version/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

