<?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>Carpé Cocoa &#187; Programming</title>
	<atom:link href="http://carpe-cocoa.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://carpe-cocoa.com</link>
	<description>My journey into iPhone development</description>
	<lastBuildDate>Tue, 24 Nov 2009 21:03:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Detecting when Bluetooth is disabled with GKSession</title>
		<link>http://carpe-cocoa.com/2009-07-29/detecting-when-bluetooth-is-disabled-with-gksession/</link>
		<comments>http://carpe-cocoa.com/2009-07-29/detecting-when-bluetooth-is-disabled-with-gksession/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 21:47:45 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[iPhone Development]]></category>
		<category><![CDATA[GameKit]]></category>

		<guid isPermaLink="false">http://carpe-cocoa.com/?p=304</guid>
		<description><![CDATA[Edit: As noted in the comments, this technique no longer works in iPhone OS 3.1.
If you are writing an iPhone GameKit app without using GKPeerPickerController (as I did in PhotoBeamer), you need to detect when Bluetooth is disabled and ask the user to turn it on in the settings app. Apple doesn&#8217;t provide a way [...]]]></description>
			<content:encoded><![CDATA[<p><em>Edit: As noted in the comments, this technique no longer works in iPhone OS 3.1.</em></p>
<p>If you are writing an iPhone GameKit app without using <code>GKPeerPickerController</code> (as I did in <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=321814330&amp;mt=8">PhotoBeamer</a>), you need to detect when Bluetooth is disabled and ask the user to turn it on in the settings app. Apple doesn&#8217;t provide a way for a developer to enable Bluetooth other than through <code>GKPeerPickerController</code>.</p>
<p>This is pretty easy to do. First, create your <code>GKSession</code> and set it to be available:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">    session <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>GKSession alloc<span style="color: #002200;">&#93;</span> initWithSessionID<span style="color: #002200;">:</span>kMyAppSessionID
                                       displayName<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span>
                                       sessionMode<span style="color: #002200;">:</span>GKSessionModeClient<span style="color: #002200;">&#93;</span>;
    session.delegate <span style="color: #002200;">=</span> self;
    <span style="color: #002200;">&#91;</span>session setDataReceiveHandler<span style="color: #002200;">:</span>self withContext<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
    session.available <span style="color: #002200;">=</span> <span style="color: #a61390;">YES</span>;</pre></div></div>

<p>Next, set up your <code lang="objc">- (void)session:(GKSession *)session didFailWithError:(NSError *)error</code> delegate method to detect when Bluetooth is not available and alert the user:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// GKSessionErrorDomain causes link error (rdar://problem/7014349)</span>
<span style="color: #6e371a;">#if 0</span>
<span style="color: #6e371a;">#define kGKSessionErrorDomain GKSessionErrorDomain</span>
<span style="color: #6e371a;">#else</span>
<span style="color: #6e371a;">#define kGKSessionErrorDomain @&quot;com.apple.gamekit.GKSessionErrorDomain&quot;</span>
<span style="color: #6e371a;">#endif</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>session<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>GKSession <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>session didFailWithError<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>error <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>error domain<span style="color: #002200;">&#93;</span> isEqual<span style="color: #002200;">:</span>kGKSessionErrorDomain<span style="color: #002200;">&#93;</span> <span style="color: #002200;">&amp;</span>amp;<span style="color: #002200;">&amp;</span>amp;
        <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>error code<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> GKSessionCannotEnableError<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">// Bluetooth disabled, prompt the user to turn it on</span>
    <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">// Some other error, get the description from the NSError object</span>
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// destroy the GKSession and clean up</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>The <code lang="objc">GKSessionErrorDomain</code> symbol causes a link error for me, so I&#8217;m temporarily using the constant string instead. When Apple fixes the SDK, I&#8217;ll change that <code lang="objc">#if 0</code> to use the official symbolic name.</p>
<p>Note that this error will sometimes occur on a reconnection attempt even when Bluetooth is enabled, presumably because the old session is still partially active.</p>
<p>It would be nice to have a more user-friendly way to turn on Bluetooth without leaving the app and without using the full <code lang="objc">GKPeerPickerController</code> UI. I&#8217;ve filed a bug report (rdar://problem/7061502) asking for this functionality. You should <a title="Apple Bug Reporter" href="https://bugreport.apple.com/" target="_blank">file one too</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://carpe-cocoa.com/2009-07-29/detecting-when-bluetooth-is-disabled-with-gksession/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>iPhone Application Packaging</title>
		<link>http://carpe-cocoa.com/2009-05-24/iphone-application-packaging/</link>
		<comments>http://carpe-cocoa.com/2009-05-24/iphone-application-packaging/#comments</comments>
		<pubDate>Mon, 25 May 2009 03:33:02 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[iPhone Development]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[XCode]]></category>

		<guid isPermaLink="false">http://carpe-cocoa.com/?p=176</guid>
		<description><![CDATA[When developing for the iPhone it&#8217;s often necessary to build the application in a form that can be easily installed by collaborators and testers. For ease of installation, the app should be distributed as a .ipa (iPhone Application) file. Unfortunately, XCode does not include a way to do this, so I wrote a bash script [...]]]></description>
			<content:encoded><![CDATA[<p>When developing for the iPhone it&#8217;s often necessary to build the application in a form that can be easily installed by collaborators and testers. For ease of installation, the app should be distributed as a .ipa (iPhone Application) file. Unfortunately, XCode does not include a way to do this, so I wrote a bash script to automate the process.</p>
<p>Additionally, in any build that leaves the developer&#8217;s desk it is especially important to include version information so that bug reports can be traced back to the correct version of the source, and to ensure that any distributed version can be located in the version control system. I use <a title="Git - Fast Version Control" href="http://git-scm.com/" target="_blank">git</a> for source control (installed with <a title="The MacPorts Project -- Available Ports" href="http://www.macports.org/ports.php?by=name&amp;substr=git" target="_blank">MacPorts</a>), though the script should be easily adaptible to CVS or SVN.</p>
<p>The goals for this script were:</p>
<ul>
<li>Automatically tag the project with a unique build number before each build.</li>
<li>Build all supported configurations with a single command. Sometimes compiler errors or warnings are only revealed with certain preprocessor flags or optimization settings.</li>
<li>Ensure any build created for distribution is cleanly committed to version control and tagged.</li>
<li>Name tags so that they can be easily correlated to user-visible version information.</li>
</ul>
<p><span id="more-176"></span></p>
<h4>Preliminaries</h4>
<p>Before we get into <a href="#the_script">the script</a>, a bit of groundwork is needed in the XCode project.</p>
<h5>Build Configurations</h5>
<p>By default, XCode includes two configurations in a new project: Debug and Release. I add a third configuration, Distribution, created by copying the Release configuration, but signed with my distributions certificate instead of the development certificate. This allows me to test using the same build settings that will be used for the submitted app.</p>
<p>I also set a couple of preprocessor flags based on the build configuration. The Debug configuration sets <code>DEVELOPMENT_BUILD=1</code> and <code>DEBUG_BUILD=1</code>, while the Release build just sets <code>DEVELOPMENT_BUILD=1</code>. These flags are used for several purposes, including conditional logging, but in the context of this article they are used just for version string generation.</p>
<p>The versioning tool discussed in the next session also requires a build variable. Search for the <code>CURRENT_PROJECT_VERSION</code> key and set its value to <code>1</code>.</p>
<h5>Apple&#8217;s Versioning Tool</h5>
<p>First, we need to take a little side trip into Apple&#8217;s built-in versioning support. XCode includes <code>agvtool</code>, which with a bit of setup can be used to satisfy our versioning requirements. The first step is to separate the &#8220;marketing version&#8221; from the build version. Both components are stored in the Info.plist file, though a new XCode project only includes the build version key.</p>
<table border="0">
<tbody>
<tr>
<th>Field</th>
<th>Key</th>
<th>agvtool use</th>
<th>Description</th>
</tr>
<tr>
<td>Bundle Version</td>
<td><code>CFBundleVersion</code></td>
<td>(Build) Version</td>
<td>Monotonically increasing integer</td>
</tr>
<tr>
<td>Bundle versions string, short</td>
<td><code>CFBundleShortVersionString</code></td>
<td>Marketing Version</td>
<td>Published version number (e.g. 1.1)</td>
</tr>
</tbody>
</table>
<p>I set the marketing version to the version I plan to specify in iTunesConnect when the app is submitted. The build version is simply set to 1 initially and incremented with each build thereafter (this should match the <code>CURRENT_PROJECT_VERSION</code> build variable).</p>
<h5>Displaying the Version</h5>
<p>In the About view controller&#8217;s <code>viewDidLoad</code> method I include the following:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>viewDidLoad <span style="color: #002200;">&#123;</span>
   <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>versionString <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span>
                        NSLocalizedString<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Version: %@%@ (%@)&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Version string format&quot;</span><span style="color: #002200;">&#41;</span>,
                        <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSBundle</span> mainBundle<span style="color: #002200;">&#93;</span> objectForInfoDictionaryKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;CFBundleShortVersionString&quot;</span><span style="color: #002200;">&#93;</span>,
<span style="color: #6e371a;">#if DEBUG_BUILD</span>
                        <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot; Debug&quot;</span>,
<span style="color: #6e371a;">#elif DEVELOPMENT_BUILD</span>
                        <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot; Beta&quot;</span>,
<span style="color: #6e371a;">#else</span>
                        <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;&quot;</span>,
<span style="color: #6e371a;">#endif</span>
                        <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSBundle</span> mainBundle<span style="color: #002200;">&#93;</span> objectForInfoDictionaryKey<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>kCFBundleVersionKey<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
   <span style="color: #002200;">&#91;</span>versionLabel setText<span style="color: #002200;">:</span>versionString<span style="color: #002200;">&#93;</span>;
   <span style="color: #11740a; font-style: italic;">// Additional initialization</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>This provides enough information to determine the build and configuration from any copy of the app. Actually, the marketing version isn&#8217;t even needed, but it allows the user to compare with the information in iTunes.<br />
<a name="the_script"></a></p>
<h3><a name="the_script"></a></h3>
<p>The remainder of this article breaks down the script, section by section. You can <a href="/utils/iPhone/build/build-1.1.sh">download the script</a> (<em>updated July 14, 2009</em>) and use or adapt it to your own projects. The script is under a BSD license.</p>
<p>The description below details the <a href="/utils/iPhone/build/build-1.0.sh">1.0 version</a> of the script.</p>
<h4>Helper Functions</h4>
<p>The first section of the script defines a few helper functions.</p>
<p>The <code>die</code> function simply prints its arguments to <code>stderr</code> and exits.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">die<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;$*&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span>
	<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>The <code>usage</code> function prints its args (if any) followed by a usage message and exits.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">usage<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;$@&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span>
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;usage: build [-n] [config...]&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;    -n : do not update build number or commit to git&quot;</span><span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$xcodeconfigs</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>    Known configs:&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span>
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot; %s&quot;</span> <span style="color: #007800;">$xcodeconfigs</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span>
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>Default action is to build all configs<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span>
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;This does not appear to be a valid project directory!&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
	<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">3</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>The usage message is:</p>
<pre>usage: build [-n] [config...]
    -n : do not update build number or commit to git

    Known configs: Debug Release Distribute

Default action is to build all configs</pre>
<h4>Defaults and Known Configurations</h4>
<p>By default, the script will run agvtool and the git operations, and build all configs in the project.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">nocommit</span>=<span style="color: #000000;">0</span>
<span style="color: #007800;">configs</span>=</pre></div></div>

<p>The list of known configurations is determined by filtering the output of <code>xcodebuild -list</code> with <code>sed</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># all known configurations</span>
<span style="color: #007800;">xcodeconfigs</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>xcodebuild <span style="color: #660033;">-list</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">'
		/Build Configurations:/,/^[[:space:]]*$/	!d
		/Build Configurations/				d
		/^[[:space:]]*$/				d
		s/[[:space:]]*\([^[:space:]]*\).*/\1/
	'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>The output of <code>xcodebuild -list</code> looks like:</p>
<pre>$ xcodebuild -list
Information about project "SpinSlide":
    Targets:
        SpinSlide (Active)

    Build Configurations:
        Debug (Active)
        Release
        Distribute

    If no build configuration is specified "Release" is used.</pre>
<p>The four-line <code>sed</code> script first deletes all lines except those between <code>Build Configurations:</code> and the first blank line. The second and third lines delete the <code>Bould Configurations</code> line and the blank line, respectively. Finally, each line is replaced by just the first word on that line.</p>
<p>Next the script checks for an empty list of configurations, which can occur if there is no project bundle in the current directory.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$xcodeconfigs</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #666666; font-style: italic;"># no project bundle?</span>
	usage;
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<h4>Argument Processing</h4>
<p>Command line arguments are processed in a loop. The only supported flag is &#8216;<code>-n</code>&#8216;, which suppresses <code>avgtool</code> and <code>git</code> operations. All non-flag arguments are assumed to be build configuration names, and are checked against the list of known configurations generated in the last section before being added to the list of configurations to build.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;$*&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
		-n<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #007800;">nocommit</span>=<span style="color: #000000;">1</span> ; <span style="color: #7a0874; font-weight: bold;">shift</span> <span style="color: #000000; font-weight: bold;">;;</span>
		-<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> usage <span style="color: #000000; font-weight: bold;">;;</span>
		<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$xcodeconfigs</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-wq</span> <span style="color: #ff0000;">&quot;$1&quot;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
				<span style="color: #007800;">configs</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$configs</span> $1&quot;</span>; <span style="color: #7a0874; font-weight: bold;">shift</span>
			<span style="color: #000000; font-weight: bold;">else</span>
				usage <span style="color: #ff0000;">&quot;Invalid config '$1'&quot;</span>
			<span style="color: #000000; font-weight: bold;">fi</span>
			<span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #000000; font-weight: bold;">esac</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p>If no configurations were specified on the command line, all known configurations are built.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># default to building all configs</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$configs</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #007800;">configs</span>=<span style="color: #007800;">$xcodeconfigs</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<h4>Check for Modified Files</h4>
<p>The next step is to check for modified files. If modified files exist and <code>-n</code> was not specified, the script will exit with an error. If <code>-n</code> was specified the script continues after setting the <code>isdirty</code> flag.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #000000; font-weight: bold;">!</span> git status <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-q</span> <span style="color: #ff0000;">'nothing to commit (working directory clean)'</span> ; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$nocommit</span>&quot;</span> <span style="color: #660033;">-eq</span> <span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #666666; font-style: italic;"># if committing the directory must be clean at first</span>
		git status
		die <span style="color: #ff0000;">&quot;directory is dirty&quot;</span>
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #666666; font-style: italic;"># development build, just remember that it was dirty</span>
		<span style="color: #007800;">isdirty</span>=<span style="color: #000000;">1</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">else</span>
	<span style="color: #007800;">isdirty</span>=<span style="color: #000000;">0</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>This step is <code>git</code>-specific, and must be adapted if you are using a different VCS.</p>
<h4>Versioning</h4>
<p>The next step handles all of the versioning and source control operations.</p>
<p>The steps required depend on the command line options used.</p>
<h5>Tagged Builds</h5>
<p>First, we handle the case where the <code>-n</code> flag was not specified. The first step is to use <code>agvtool</code> to determine the marketing version. This will not be changed when the build number is incremented. Checking the marketing version first lets us verify that the project is set up properly before making changes.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$nocommit</span>&quot;</span> <span style="color: #660033;">-eq</span> <span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #666666; font-style: italic;"># read out the marketing version</span>
	<span style="color: #666666; font-style: italic;"># do this separate from the cut so we can check the exit code</span>
	<span style="color: #007800;">mvers</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>agvtool mvers -terse<span style="color: #7a0874; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$?</span> <span style="color: #660033;">-ne</span> <span style="color: #000000;">0</span> <span style="color: #660033;">-o</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$mvers</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
		die <span style="color: #ff0000;">&quot;No marketing version found&quot;</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$mvers</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-q</span> = ; <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #007800;">mvers</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$mvers</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">cut</span> <span style="color: #660033;">-f</span> <span style="color: #000000;">2</span> <span style="color: #660033;">-d</span> =<span style="color: #7a0874; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>The output of <code>agvtool</code> looks like:</p>
<pre>"SpinSlide.xcodeproj/../Info.plist"=1.0</pre>
<p>The <code>cut</code> command is used to extract the field after the <code>=</code> sign.</p>
<p>After this point, the environment has been fully verified, so we can go ahead and increment the build version.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">	<span style="color: #666666; font-style: italic;"># going to commit, bump the version number</span>
	agvtool bump <span style="color: #660033;">-all</span></pre></div></div>

<p>Now we extract the (newly incremented) build version&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">	<span style="color: #007800;">bvers</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>agvtool vers -terse<span style="color: #7a0874; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$?</span> <span style="color: #660033;">-ne</span> <span style="color: #000000;">0</span> <span style="color: #660033;">-o</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$bvers</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
		die <span style="color: #ff0000;">&quot;No build version found&quot;</span>
	<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>&#8230; and combine the marketing version and build numbers into a human-readable string and a tag identifier, which has the spaces replace by underscores.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">	<span style="color: #666666; font-style: italic;"># read out the build version, must exist if the marketing version does</span>
	<span style="color: #007800;">fullvers</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$mvers</span> build <span style="color: #007800;">$bvers</span>&quot;</span>
	<span style="color: #007800;">tag</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$fullvers</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tr</span> <span style="color: #ff0000;">' '</span> _<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Finally, we commit the changed .plist and tag the new version.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">	<span style="color: #666666; font-style: italic;"># commit the changed version and tag it</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Committing &quot;</span><span style="color: #007800;">$fullvers</span><span style="color: #ff0000;">&quot; with tag <span style="color: #007800;">$tag</span>&quot;</span>
	git ci <span style="color: #660033;">-a</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Set build version '<span style="color: #007800;">$fullvers</span>'&quot;</span> <span style="color: #660033;">-n</span> <span style="color: #000000; font-weight: bold;">||</span> die <span style="color: #ff0000;">'commit failed'</span>
	git tag <span style="color: #ff0000;">&quot;<span style="color: #007800;">$tag</span>&quot;</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$fullvers</span>&quot;</span></pre></div></div>

<h5>Untagged Builds</h5>
<p>Untagged builds are much simpler. The SHA1 of the current version is used as the tag. If the source directory is dirty, the current date and time is added to make a unique identifier.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">else</span>
	<span style="color: #666666; font-style: italic;"># not committing, use the SHA1 as the version</span>
	<span style="color: #007800;">fullvers</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>git rev-parse HEAD <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;"># if it's dirty, append the date, time, and timezone</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$isdirty</span>&quot;</span> <span style="color: #660033;">-ne</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #007800;">fullvers</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$fullvers</span>+ <span style="color: #007800;">$(date +%F\ %T\ %Z)</span>&quot;</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<h4>Build Prep</h4>
<p>To ensure the build matches the source, we delete the <code>build</code> directory and the <code>Payload</code> directory (the former is used by XCode, the latter by this script).</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># clean up old builds so that everything is built from scratch</span>
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> build
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> Payload
<span style="color: #007800;">all</span>=</pre></div></div>

<h4>Build and Package</h4>
<p>Next we loop over the requested configurations, building and packaging each one.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># build and package each requested config</span>
<span style="color: #000000; font-weight: bold;">for</span> config <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #007800;">$configs</span> ; <span style="color: #000000; font-weight: bold;">do</span></pre></div></div>

<p>The build is performed with the <code>xcodebuild</code> utility, supplied with XCode. A failed build stops the script.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">	xcodebuild <span style="color: #660033;">-alltargets</span> <span style="color: #660033;">-parallelizeTargets</span> <span style="color: #660033;">-configuration</span> <span style="color: #007800;">$config</span> build <span style="color: #000000; font-weight: bold;">||</span> die <span style="color: #ff0000;">&quot;Build failed&quot;</span></pre></div></div>

<p>Build output is stored in a tree named for the build type (tagged or untagged), version, and XCode build configuration:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">	<span style="color: #666666; font-style: italic;"># packaged output goes in Releases if tagged, Development otherwise</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$nocommit</span>&quot;</span> <span style="color: #660033;">-eq</span> <span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #007800;">basedir</span>=Releases
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #007800;">basedir</span>=Development
	<span style="color: #000000; font-weight: bold;">fi</span>
	<span style="color: #007800;">releasedir</span>=<span style="color: #007800;">$basedir</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$config</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #ff0000;">&quot;<span style="color: #007800;">$fullvers</span>&quot;</span>
	<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$releasedir</span>&quot;</span></pre></div></div>

<p>Each build target is then packaged, one at a time.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">	<span style="color: #666666; font-style: italic;"># Package each app</span>
	<span style="color: #000000; font-weight: bold;">for</span> app <span style="color: #000000; font-weight: bold;">in</span> build<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$config</span>-iphoneos<span style="color: #000000; font-weight: bold;">/*</span>.app ; <span style="color: #000000; font-weight: bold;">do</span>
		<span style="color: #007800;"><span style="color: #c20cb9; font-weight: bold;">basename</span></span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$(basename &quot;$app&quot; .app)</span>&quot;</span></pre></div></div>

<p>The application bundle is copied into a directory called <code>Payload/Payload</code>. The first directory name isn&#8217;t significant, but the second is important to make a working <code>.ipa</code> file.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">		<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> Payload<span style="color: #000000; font-weight: bold;">/</span>Payload
		<span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-Rp</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$app</span>&quot;</span> Payload<span style="color: #000000; font-weight: bold;">/</span>Payload</pre></div></div>

<p>To have an icon in iTunes, the package must include a 512&#215;512 PNG or JPEG named <code>iTunesArtwork</code> at the root. The following code supports per-project default artwork as well as app-specific artwork (if there are multiple apps in a single project).</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">		<span style="color: #666666; font-style: italic;"># Get app-specific iTunes artwork or project-specific artwork</span>
		<span style="color: #666666; font-style: italic;"># if available</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-f</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$basename</span>&quot;</span>.iTunesArtwork <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
			<span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-f</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$basename</span>&quot;</span>.iTunesArtwork Payload<span style="color: #000000; font-weight: bold;">/</span>iTunesArtwork
		<span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-f</span> iTunesArtwork <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
			<span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-f</span> iTunesArtwork Payload<span style="color: #000000; font-weight: bold;">/</span>iTunesArtwork
		<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>A <code>.ipa</code> file is just a <code>.zip</code> file with a particular content format. When building for distribution through the AppStore, the <code>.zip</code> extension is required. Otherwise the <code>.ipa</code> extension is used.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">		<span style="color: #666666; font-style: italic;"># Distribution builds have a .zip extension, development</span>
		<span style="color: #666666; font-style: italic;"># builds have a .ipa extension</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$config</span>&quot;</span> <span style="color: #660033;">-eq</span> <span style="color: #ff0000;">&quot;Distribute&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
			<span style="color: #007800;">ext</span>=<span style="color: #c20cb9; font-weight: bold;">zip</span>
		<span style="color: #000000; font-weight: bold;">else</span>
			<span style="color: #007800;">ext</span>=ipa
		<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>Next we use <code>ditto</code> to zip the contents, then delete the temp directory.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">		<span style="color: #666666; font-style: italic;"># zip the Payload directory then delete it</span>
		<span style="color: #007800;">output</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$releasedir</span>/<span style="color: #007800;">$basename</span>.<span style="color: #007800;">$ext</span>&quot;</span>
		ditto <span style="color: #660033;">-c</span> <span style="color: #660033;">-k</span> Payload <span style="color: #ff0000;">&quot;<span style="color: #007800;">$output</span>&quot;</span> <span style="color: #000000; font-weight: bold;">||</span> die <span style="color: #ff0000;">&quot;Failed to compress&quot;</span>
		<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> Payload</pre></div></div>

<p>We remember the name of the generated file to display at the end of the script.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">		<span style="color: #666666; font-style: italic;"># add to the list of output files</span>
		<span style="color: #007800;">all</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">${all:+$(printf &quot;%s\n&quot; &quot;$all&quot;)}</span><span style="color: #007800;">$(printf &quot;\t%s&quot; &quot;$output&quot;)</span>&quot;</span></pre></div></div>

<p>XCode supports splitting the debug symbols from the app. If this option is enabled (as it should be for Release and Distribution builds) we save the debug symbols with the app:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">		<span style="color: #666666; font-style: italic;"># save debug symbols (if available) with the app</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$app</span>.dSYM&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
			<span style="color: #007800;">output</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$releasedir</span>/<span style="color: #007800;">$basename</span>.dSYM.zip&quot;</span>
			ditto <span style="color: #660033;">-c</span> <span style="color: #660033;">-k</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$app</span>.dSYM&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$output</span>&quot;</span> <span style="color: #000000; font-weight: bold;">||</span> die <span style="color: #ff0000;">&quot;Failed to compress debug info&quot;</span>
			<span style="color: #007800;">all</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$(printf &quot;%s\n&quot; &quot;$all&quot;)</span><span style="color: #007800;">$(printf &quot;\t%s&quot; &quot;$output&quot;)</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>Finally, we update a symlink to point to the latest version.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">		<span style="color: #666666; font-style: italic;"># update a symlink to the latest version</span>
		<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$basedir</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$config</span> ; <span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-sf</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$fullvers</span>/<span style="color: #007800;">$basename</span>.<span style="color: #007800;">$ext</span>&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">done</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<h4>Report Results</h4>
<p>Once all the builds have completed and been packaged, a build summary is displayed to the user.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># report the generated files</span>
<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;Created: <span style="color: #007800;">$all</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://carpe-cocoa.com/2009-05-24/iphone-application-packaging/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Balsamiq Mockups</title>
		<link>http://carpe-cocoa.com/2009-05-21/balsamiq-mockups/</link>
		<comments>http://carpe-cocoa.com/2009-05-21/balsamiq-mockups/#comments</comments>
		<pubDate>Fri, 22 May 2009 00:57:17 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[iPhone Development]]></category>

		<guid isPermaLink="false">http://www.szczerba.net/?p=135</guid>
		<description><![CDATA[I&#8217;ve heard good things about Balsamiq Mockups so I thought I&#8217;d give it a try. The desktop version is currently just $79, and installs in moments from the Mockups site. The app is based on Adobe Air, so if you don&#8217;t have Air installed already, you&#8217;ll need to do that first. Mockups runs on OS [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve heard good things about <a href="http://www.balsamiq.com/products/mockups/">Balsamiq Mockups</a> so I thought I&#8217;d give it a try. The <a href="http://www.balsamiq.com/products/mockups/desktop">desktop version</a> is currently just $79, and <a href="http://www.balsamiq.com/products/mockups/desktop#download">installs in moments</a> from the Mockups site. The app is based on <a href="http://get.adobe.com/air/">Adobe Air</a>, so if you don&#8217;t have Air installed already, you&#8217;ll need to do that first. Mockups runs on OS X, Windows, and Linux. There is also a <a href="http://www.balsamiq.com/demos/mockups/Mockups.html">web version</a>. This review uses the OS X desktop version. You can try out the desktop version for free, but to save or export designs you&#8217;ll need a license key.</p>
<p><span id="more-135"></span></p>
<h4>Registration</h4>
<p>Registration is simple, although the menu item is hidden in the Help menu instead of being in the Application menu (which doesn&#8217;t actually exist). Once you&#8217;ve entered the registered name and serial number, the app is fully activated. Registration is per-user, not per-machine, so you can install it on your desktop, laptop, home desktop, etc. Registration includes free perpetual updates.</p>
<h4>Reinventing the&#8230; uh&#8230; clock</h4>
<p><a title="New Mockup Window" rel="lightbox[mockups]" href="http://www.szczerba.net/wp-content/uploads/2009/05/picture-1.png" title="New Mockup Window" rel="lightbox[135]"><img class="alignleft size-thumbnail wp-image-136" title="New Mockup Window" src="http://www.szczerba.net/wp-content/uploads/2009/05/picture-1-150x100.png" alt="New Mockup Window" width="150" height="100" /></a> When you launch Mockups, you are presented with a new mockup window, ready for your design. Across the top are a number of controls you can add to the Mockup. These controls are broken down into a number of categories. Since I write iPhone apps for a living, we&#8217;ll select the iPhone category to get started, then set about creating a workflow for the built-in clock app.</p>
<p><a title="iPhone Container Options" rel="lightbox[mockups]" href="http://www.szczerba.net/wp-content/uploads/2009/05/picture-2.png" title="iPhone Container Options" rel="lightbox[135]"><img class="alignleft size-thumbnail wp-image-140" title="iPhone Container Options" src="http://www.szczerba.net/wp-content/uploads/2009/05/picture-2-150x106.png" alt="iPhone Container Options" width="150" height="106" /></a> First, drag a iPhone object into the mockup to act as a container for our views. Bring up the properties window (it&#8217;s greyed out until you point at it) and select the middle background pattern, which shows a Nav Bar at the top and a Tab Bar at the bottom. Then click in the &#8220;Quick Add&#8221; box and start typing &#8220;Icon&#8221;. Select the &#8220;Icon and Text Label&#8221; and type in &#8220;World Clock&#8221;. Click on &#8220;Icon search&#8221; and type in &#8220;Circle&#8221;, then select the &#8220;Dot, Little Black Circle&#8221; icon. Change the font size to 9 and icon size to Small to make it fit better, and drag it over the tab bar area on the phone. In a similar way, we can quickly make the Alarm, Stopwatch, and Timer buttons and place them in their approximate locations. Select all 4 icons and Align Bottom, then Distribute Centers Horizontally and Group them. We&#8217;ll save this as &#8220;iPhone Clock App World Clock&#8221;.</p>
<p><a title="Completed World Clock Controls" rel="lightbox[mockups]" href="http://www.szczerba.net/wp-content/uploads/2009/05/picture-3.png" title="Completed World Clock Controls" rel="lightbox[135]"><img class="alignleft size-thumbnail wp-image-141" title="Completed World Clock Controls" src="http://www.szczerba.net/wp-content/uploads/2009/05/picture-3-150x106.png" alt="Completed World Clock Controls" width="150" height="106" /></a>Next we clone the mockup (??N) three times and save the clones as &#8220;iPhone Clock App Alarm&#8221;, &#8220;iPhone Clock App Stopwatch&#8221;, and &#8220;iPhone Clock App Timer&#8221;. Later we can link the icon buttons to the different views, but for now we&#8217;ll continue creating the World Clock view. In a few moments we can add an Edit button and a + button and use a Label to finish the Nav Bar.</p>
<p><a title="Completed World Clock View" rel="lightbox[mockups]" href="http://www.szczerba.net/wp-content/uploads/2009/05/picture-4.png" title="Completed World Clock View" rel="lightbox[135]"><img class="alignleft size-thumbnail wp-image-142" title="Completed World Clock View" src="http://www.szczerba.net/wp-content/uploads/2009/05/picture-4-150x106.png" alt="Completed World Clock View" width="150" height="106" /></a>Next we complete the content view. Simple add a Rectangle/Canvas to the content area, an icon for the clock, and a few Labels for the City, Time, AM/PM and Day, adjusting the fonts appropriately (remember, the goal is an approximate representation of the final app). Duplicate the row we just created a few times to fill out the content area.</p>
<h4>In-App Navigation</h4>
<p><a title="Adding Links" rel="lightbox[mockups]" href="http://www.szczerba.net/wp-content/uploads/2009/05/picture-5.png" title="Adding Links" rel="lightbox[135]"><img class="alignleft size-thumbnail wp-image-153" title="Adding Links" src="http://www.szczerba.net/wp-content/uploads/2009/05/picture-5-150x106.png" alt="Adding Links" width="150" height="106" /></a>The last step on this view is to fill out the links. Just select each control and choose the desired mockup from the Link dropdown. A small blue arrow will appear on the control. If you switch to View-&gt;Full Screen Presentation (?F) you can click on these linked buttons to navigate around the mockup.</p>
<p><a title="Timer Mockup" rel="lightbox[mockups]" href="http://www.szczerba.net/wp-content/uploads/2009/05/picture-6.png" title="Timer Mockup" rel="lightbox[135]"><img class="alignleft size-thumbnail wp-image-154" title="Timer Mockup" src="http://www.szczerba.net/wp-content/uploads/2009/05/picture-6-150x106.png" alt="Timer Mockup" width="150" height="106" /></a> We can use the included iPhone Picker control to quickly mockup the Timer screen as well. The buttons in the middle are made from Canvases and Labels to allow customizing the text layout and colors, much as we&#8217;d have to do in Interface Builder or programmatically if we were to build this app for real. It would be nice if Mockups let you change button colors. Maybe that feature will be added soon.</p>
<h4>Full Screen Presentation</h4>
<div class="alignright"><a title="Full Screen Mode, Big Pointer for Discussions" rel="lightbox[full screen]" href="http://www.szczerba.net/wp-content/uploads/2009/05/picture-71.png" title="Full Screen Mode, Big Pointer for Discussions" rel="lightbox[135]"><img class="alignleft size-thumbnail wp-image-156" title="Full Screen Mode, Big Pointer for Discussions" src="http://www.szczerba.net/wp-content/uploads/2009/05/picture-71-109x150.png" alt="Full Screen Mode, Big Pointer for Discussions" width="109" height="150" /></a><a title="Links are highlighted...." rel="lightbox[full screen]" href="http://www.szczerba.net/wp-content/uploads/2009/05/picture-81.png" title="Links are highlighted...." rel="lightbox[135]"><img class="alignleft size-thumbnail wp-image-157" title="Links are highlighted...." src="http://www.szczerba.net/wp-content/uploads/2009/05/picture-81-110x150.png" alt="Links are highlighted...." width="110" height="150" /></a> <a title="... and can be followed" rel="lightbox[full screen]" href="http://www.szczerba.net/wp-content/uploads/2009/05/picture-9.png" title="... and can be followed" rel="lightbox[135]"><img class="alignleft size-thumbnail wp-image-158" title="... and can be followed" src="http://www.szczerba.net/wp-content/uploads/2009/05/picture-9-109x150.png" alt="... and can be followed" width="109" height="150" /></a></div>
<p>We can go on like this adding additional mockups until we&#8217;ve covered all the screens in the app. Along the way we can share the files with the rest of the team to get feedback much more quickly than if we were writing code for all of this. If you are in the same office as the rest of your team or use some sort of web collaboration software, you can use the Full Screen Presentation mode to click through the various screens in the app, using the ridiculously large pointer (and I mean that in a nice way) to point out parts of the interface as you discuss it.</p>
<h4>Conclusions</h4>
<p>Mockups is extremely easy to use. I wrote this review as I was learning the app for the first time. The hand-drawn images really do have the intended &#8220;lo-fi&#8221; effect, encouraging you to stay focused on the big picture instead of spending hours tweaking individual pixels. Mockups will definitely become part of the <a href="http://appmobi.com/">AppMobi</a> design process. It will be a big help as we move ahead with development of our more sophisticated productivity apps.</p>
]]></content:encoded>
			<wfw:commentRss>http://carpe-cocoa.com/2009-05-21/balsamiq-mockups/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Not Entirely Accurate History of Programming Languages</title>
		<link>http://carpe-cocoa.com/2009-05-12/a-not-entirely-accurate-history-of-programming-languages/</link>
		<comments>http://carpe-cocoa.com/2009-05-12/a-not-entirely-accurate-history-of-programming-languages/#comments</comments>
		<pubDate>Tue, 12 May 2009 15:20:25 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[Humor]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.szczerba.net/?p=59</guid>
		<description><![CDATA[James Iry has posted A Brief, Incomplete, and Mostly Wrong History of Programming Languages, a hilarious look at the development of programming languages over the years.
Some of my favorites:
On C:

On Objective-C:

On LiveScript/JavaScript/ECMAScript:

Visit his blog to read more.
]]></description>
			<content:encoded><![CDATA[<p><a href="http:/james-iry.blogspot.com/">James Iry</a> has posted <a href="http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html">A Brief, Incomplete, and Mostly Wrong History of Programming Languages</a>, a hilarious look at the development of programming languages over the years.</p>
<p>Some of my favorites:</p>
<p>On C:</p>
<blockquote>&#8220;1972 - Dennis Ritchie invents a powerful gun that shoots both forward and backward simultaneously. Not satisfied with the number of deaths and permanent maimings from that invention he invents C and Unix.&#8221;<br/>~&nbsp;James Iry<em>&nbsp;<a href="http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html">A Brief, Incomplete, and Mostly Wrong History of Programming Languages</a></em></blockquote>
<p>On Objective-C:</p>
<blockquote>&#8220;1986 - Brad Cox and Tom Love create Objective-C, announcing "this language has all the memory safety of C combined with all the blazing speed of Smalltalk." Modern historians suspect the two were dyslexic.&#8221;<br/>~&nbsp;James Iry<em>&nbsp;<a href="http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html">A Brief, Incomplete, and Mostly Wrong History of Programming Languages</a></em></blockquote>
<p>On LiveScript/JavaScript/ECMAScript:</p>
<blockquote>&#8220;1995 - Brendan Eich reads up on every mistake ever made in designing a programming language, invents a few more, and creates... JavaScript&#8221;<br/>~&nbsp;James Iry<em>&nbsp;<a href="http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html">A Brief, Incomplete, and Mostly Wrong History of Programming Languages</a></em></blockquote>
<p><a href="http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html">Visit his blog to read more.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://carpe-cocoa.com/2009-05-12/a-not-entirely-accurate-history-of-programming-languages/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Detecting Memory Leaks in the iPhone Simulator</title>
		<link>http://carpe-cocoa.com/2009-05-08/detecting-memory-leaks-in-the-iphone-simulator/</link>
		<comments>http://carpe-cocoa.com/2009-05-08/detecting-memory-leaks-in-the-iphone-simulator/#comments</comments>
		<pubDate>Sat, 09 May 2009 03:10:43 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[iPhone Development]]></category>

		<guid isPermaLink="false">http://www.szczerba.net/2009-05-08/detecting-memory-leaks-in-the-iphone-simulator/</guid>
		<description><![CDATA[
There are a number of useful debug flags for the iPhone that can be set in the environment. To access these settings, select your executable from the Groups &#038; Files pane in XCode, then press ?I or select Get Info from the context menu.
Go to the Arguments tab and add the following entries into the [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.szczerba.net/wp-content/uploads/2009/05/picture-7.png" alt="Selecting executable in XCode" title="Selecting executable in XCode" width="244" height="113" class="alignright size-full wp-image-50" /><br />
There are a number of useful debug flags for the iPhone that can be set in the environment. To access these settings, select your executable from the Groups &#038; Files pane in XCode, then press ?I or select Get Info from the context menu.</p>
<p>Go to the Arguments tab and add the following entries into the &#8220;Variables to be set in the environment&#8221; box:</p>
<ul>
<li><code>NSAutoreleaseFreedObjectCheckEnabled</code>
</li>
<li><code>NSDebugEnabled</code>
</li>
<li><code>NSZombieEnabled</code>
</li>
</ul>
<p>Set the value for all each to <code>YES</code>.</p>
<p>Your settings should now look like:</p>
<p><a href="http://www.szczerba.net/wp-content/uploads/2009/05/picture-8.png" rel="lightbox"><img src="http://www.szczerba.net/wp-content/uploads/2009/05/picture-8.png" alt="Executable arguments settings" title="Executable arguments settings" width="770" height="673" class="alignnone size-full wp-image-51" /></a></p>
<p>You may also want to set <code>NSHangOnUncaughtException=YES</code>. Additional useful debugging tips can be found in <a href="http://www.cocoabuilder.com/archive/message/cocoa/2003/9/14/87250">this thread</a>.</p>
<p>Edit: <a href="http://www.cocoadev.com/index.pl?NSZombieEnabled">CocoaDev has additional <code>NSZombieEnabled</code> tips</a>, and notes that you may not want to leave this enabled all the time, especially if your application churns through a lot of objects, as the memory never gets freed. The fact that your code is running on a desktop or laptop system instead of the phone helps a lot here, so this is probably a lot less of a concern than for a desktop application. They also provide instructions for setting these flags in your .gdbinit using:</p>
<pre>set env NSAutoreleaseFreedObjectCheckEnabled=YES
set env NSDebugEnabled=YES
set env NSZombieEnabled=YES</pre>
]]></content:encoded>
			<wfw:commentRss>http://carpe-cocoa.com/2009-05-08/detecting-memory-leaks-in-the-iphone-simulator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finding Average File Size with Perl</title>
		<link>http://carpe-cocoa.com/2008-10-09/finding-average-file-size-with-perl/</link>
		<comments>http://carpe-cocoa.com/2008-10-09/finding-average-file-size-with-perl/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 20:22:47 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.szczerba.net/2008-10-09/finding-average-file-size-with-perl/</guid>
		<description><![CDATA[I was creating a new filesystem on a NetBSD box today, and wondered about the appropriate value for the &#8220;average file size&#8221; parameter. The first question I had was &#8220;what is the average filesize in my data set&#8221;, which I figured I could answer, since I had some representative data handy. I put together a [...]]]></description>
			<content:encoded><![CDATA[<p>I was creating a new filesystem on a NetBSD box today, and wondered about the appropriate value for the &#8220;average file size&#8221; parameter. The first question I had was &#8220;what is the average filesize in my data set&#8221;, which I figured I could answer, since I had some representative data handy. I put together a quick one-liner to answer this question:</p>
<p><code>find /export -type f -print | perl -ne 'chomp; $count++; $total += (stat())[7]; END { print "$count files $total bytes total ", $total/$count, " byte average\n"; }</code></p>
<p>After running this, I was surprised at just how large the &#8220;average&#8221; size was, which led me to wonder just <em>which</em> average they were looking for here: <a href="http://en.wikipedia.org/wiki/Arithmetic_mean">mean</a> or <a href="http://en.wikipedia.org/wiki/Median">median</a>? While I was at it, I decided to calculate the <a href="http://en.wikipedia.org/wiki/Mode_(statistics)">mode</a> as well.</p>
<p><span id="more-46"></span></p>
<p>The one-liner evolved to:</p>
<p><code>find /export -type f -print | perl -ne 'chomp; $count++; $size = (stat())[7]; push @sizes, $size; $total += $size; $sizes{int(($size+511)/512)}++; print "$count\r" if ($count % 2048 == 0); END { $median = (sort @sizes)[$#sizes / 2]; $mode = 512 * (sort { $sizes{$b} &lt;=&gt; $sizes{$a} } keys %sizes)[0]; print "$count files $total bytes total ", $total/$count, " byte mean $median byte median $mode byte mode\n"; } BEGIN { $| = 1; }'<br />
</code></p>
<p>We can make this a bit more legible:</p>
<pre><code>find /export -type f -print | perl -ne '\
      chomp; \
      $count++; \
      $size = (stat())[7]; \
      push @sizes, $size; \
      $total += $size; \
      $sizes{int(($size+511)/512)}++; \
      print &#34;$count\r&#34; if ($count % 2048 == 0); \
BEGIN { $| = 1; } \
END { $median = (sort @sizes)[$#sizes / 2]; \
      $mode = 512 * (sort { $sizes{$b} &lt;=&gt; $sizes{$a} } keys %sizes)[0]; \
      print &#34;$count files $total bytes total &#34;, $total/$count, \
            &#34; byte mean $median byte median $mode byte mode\n&#34;; }'</code></pre>
<p>Let&#8217;s take it line by line. First, the shell pipeline <code>find /export -type f -print | perl -ne &#39;<i>stuff</i>&#39;</code>  recursively descends into the /export directory and prints the names of all regular files found, one per line. This output is piped into Perl, which processes the commands in the <code>-e &#39;<i>stuff</i>&#39;</code> block once per line due to the <code>-n</code> flag.</p>
<p>The heavy lifting is done in the Perl program:</p>
<p><strong>Gathering the Information</strong></p>
<p><code>chomp;</code> strips the trailing newline from the input line.</p>
<p><code>$count++;</code> counts the number of lines.</p>
<p><code>$size = (stat())[7];</code> gets the size in bytes of the input file.</p>
<p><code>push @sizes, $size;</code> saves the size in a list of all file sizes seen.</p>
<p><code>$total += $size;</code> adds up the total number of bytes seen.</p>
<p><code>$sizes{int(($size+511)/512)}++;</code> converts the size in bytes into a size in 512-byte blocks, and counts the number of files with a given block count. This creates a histogram of file sizes using 512-byte bins.</p>
<p><strong>Showing Progress</strong></p>
<p><code>print &#34;$count\r&#34; if ($count % 2048 == 0);</code> prints a progress indication for every 512 files processed.</p>
<p><code>BEGIN { $| = 1; }</code> is a BEGIN block, which means it is executed once at the beginning of the program. It sets the perl built-in variable $| to a true value, so that output is displayed immediately. With out this, the progress indication would not print until it had been output hundreds of times.</p>
<p><strong>Calculating Results</strong></p>
<p>Results a reported in the <code>END {}</code> block, which, as you may guess, is executed once at the end of the program. It starts with a few calculations:</p>
<p><code>$median = (sort @sizes)[$#sizes / 2];</code> sorts the list of sizes seen (<code>sort @sizes</code>), the selects the middle item from the sorted list (<code>$#sizes</code> is the index of the last element in the list, we use half of that as the index to get the middle element).</p>
<p><code>$mode = 512 * (sort { $sizes{$b} &lt;=&gt; $sizes{$a} } keys %sizes)[0];</code> calculates the mode (the most frequently-occurring item). Working from the inside out, <code>keys %sizes</code> gets a list of the keys from the %sizes hash. Then <code>sort { $sizes{$b} &lt;=&gt; $sizes{$a} } keys %sizes</code> sorts those keys by hash value in descending order, so that the most-frequently occurring element comes first. The first element is accessed at index 0, then multiplied by 512 to convert back to bytes.</p>
<blockquote>
<p><strong>Sorting The Data:</strong> The sort is done by passing a custom comparison routine <code>{&nbsp;$sizes{$b}&nbsp;&lt;=&gt;&nbsp;$sizes{$a}&nbsp;}</code> to the built-in <code>sort</code> function.</p>
<p>Perl&#8217;s <code>sort</code> will call this routine repeatedly with pairs of list elements in <code>$a</code> and <code>$b</code>. The routine should return 0 if the elements are equal, less than 0 if <code>$a</code> should come first, or greater than 0 if <code>$b</code> should come first.</p>
<p>The default comparison is <code>$a&nbsp;&lt;=&gt;&nbsp;$b</code>, which is a lexical sort. Since out data is numeric, we could use the equivalent <code>$a&nbsp;&lt;=&gt;&nbsp;$b</code>, which in this case would sort the list in ascending order by size. Reversing the comparison to <code>$b&nbsp;&lt;=&gt;&nbsp;$a</code> sorts in descending order by size. Finally, using the hash values rather than the keys sorts by frequency of occurrence.</p>
</blockquote>
<p></p>
<p><strong>Output Results</strong></p>
<p>Now it&#8217;s a simple matter of displaying the results:</p>
<p><code>print &#34;$count files $total bytes total &#34;, $total/$count, &#34; byte mean $median byte median $mode byte mode\n&#34;; }'</code></p>
]]></content:encoded>
			<wfw:commentRss>http://carpe-cocoa.com/2008-10-09/finding-average-file-size-with-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stack Overflow!</title>
		<link>http://carpe-cocoa.com/2008-09-23/stack-overflow/</link>
		<comments>http://carpe-cocoa.com/2008-09-23/stack-overflow/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 16:47:29 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.szczerba.net/2008-09-23/stack-overflow/</guid>
		<description><![CDATA[Jeff Atwood of Coding Horror and Joel Spolsky of Joel on Software, two of my favorite programming bloggers, recently created a community-driven programming Q&#038;A site, stackoverflow.com. It&#8217;s been open to the public for a few days now and seems like it will be an extremely useful resource for developers of all types.
]]></description>
			<content:encoded><![CDATA[<p>Jeff Atwood of <a href="http://www.codinghorror.com/">Coding Horror</a> and Joel Spolsky of <a href="http://www.joelonsoftware.com/">Joel on Software</a>, two of my favorite programming bloggers, recently created a community-driven <a href="http://stackoverflow.com">programming Q&#038;A site</a>, stackoverflow.com. It&#8217;s been open to the public for a few days now and seems like it will be an extremely useful resource for developers of all types.</p>
]]></content:encoded>
			<wfw:commentRss>http://carpe-cocoa.com/2008-09-23/stack-overflow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
