<?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>The Carbon Emitter &#187; objective-c</title>
	<atom:link href="http://blog.carbonfive.com/tag/objective-c/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.carbonfive.com</link>
	<description>The blog of Carbon Five</description>
	<lastBuildDate>Mon, 23 Jan 2012 18:38:45 +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>Monkey-Patching iOS with Objective-C Categories Part I: Simple Extensions and Overrides</title>
		<link>http://blog.carbonfive.com/2012/01/23/monkey-patching-ios-with-objective-c-categories-part-1-simple-extensions-and-overrides/</link>
		<comments>http://blog.carbonfive.com/2012/01/23/monkey-patching-ios-with-objective-c-categories-part-1-simple-extensions-and-overrides/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 18:38:45 +0000</pubDate>
		<dc:creator>Rudy Jahchan</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[monkey-patching]]></category>
		<category><![CDATA[objective-c]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=5851</guid>
		<description><![CDATA[Have you ever wanted to introduce new functionality to base classes in the iOS SDK? Or just make them work a little bit differently? In order to do so, you must enter the wild and dangerous world of monkey-patching. Monkey-patching &#8230; <a href="http://blog.carbonfive.com/2012/01/23/monkey-patching-ios-with-objective-c-categories-part-1-simple-extensions-and-overrides/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Have you ever wanted to introduce new functionality to base classes in the iOS SDK? Or just make them work a <strong>little bit</strong> differently? In order to do so, you must enter the wild and dangerous world of monkey-patching.</p>

<p>Monkey-patching is extending or modifying the behavior of code at runtime <strong>without</strong> changing its original source code. You can monkey-patch any code, it doesn&#8217;t matter whether it&#8217;s your own code or not. This is distinctly different than traditional sub-classing because you are not creating a new class, instead, you are reopening an existing class and changing its behavior.</p>

<p>Monkey-patching is possible in Objective-C by using <a href="http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/chapters/occategories.html">categories</a>. In fact, the definition of a category practically matches that of monkey-patching:</p>

<p><code>"A category allows you to add methods to an existing class—even to one for which you do not have the source."</code></p>

<p>In this series of posts, we&#8217;ll use categories to add and change methods, to add new instance variables and properties, and introduce swizzling, a technique that allows us to extend and preserve existing functionality.<span id="more-5851"></span> <a href="#tldr"><strong>TL;DR &raquo;</strong></a></p>

<h2>Category Basics</h2>

<p>To modify an existing class specify the category in both its interface and implementation definitions:</p>

<h4>Interface Definition</h4>

<script src="https://gist.github.com/1660134.js?file=AClassACategoryImplementation.h"></script>

<h4>Implementation</h4>

<script src="https://gist.github.com/1660134.js?file=AClassACategoryImplementation.m"></script>

<h2>Adding Simple Methods</h2>

<p>The most basic usage of categories is to add a new method to an existing class.</p>

<p>Suppose in our application we want to output dates relative to the current time, e.g., &#8220;13 minutes ago&#8221;, &#8220;4 hours ago&#8221;, &#8220;just now&#8221;, etc. Traditional object-oriented solutions would have us introducing a new class that either extends <code>NSDate</code> (e.g., creating a <code>RelativeDescriptionDate</code> subclass with a <code>timeAgoInWords</code> instance method) or is a standalone helper/utility class (e.g., <code>[NSDateHelper timeAgoInWordsFromDate:myDate]</code>).</p>

<p>But with categories, we can reopen the <code>NSDate</code> class and simply add a new instance method:</p>

<h4>NSDate+Formatting.h</h4>

<script src="https://gist.github.com/1660134.js?file=NSDateFormatting.h"></script>

<h4>NSDate+Formatting.m</h4>

<script src="https://gist.github.com/1660134.js?file=NSDateFormatting.m"></script>

<p>Now <strong>every</strong> <code>NSDate</code> object will have the new method available to it. The following code:</p>

<script src="https://gist.github.com/1660134.js?file=UsingNSDateFormatting.m"></script>

<p>Will print out the following on the console:</p>

<script src="https://gist.github.com/1660134.js?file=gistfile1.sh"></script>

<h2>The Dangers of Simply Overriding Methods</h2>

<p>We can take this a step further and instead of adding new behavior we&#8217;ll override existing behavior. Continuing with our example, what if we wanted the default description of a <code>NSDate</code> object to include the time ago in words? We could simply do the following:</p>

<script src="https://gist.github.com/1660134.js?file=NSDateFormatting2.m"></script>

<p>However, this is <strong>strongly discouraged</strong> for two reasons.</p>

<ol>
<li>Other frameworks may rely on the expected behavior of the original method. We now have to go through the trouble of re-implementing that behavior, in addition to the new functionality we wanted to introduce, or risk strange side effects and possibly even crashing out. </li>
<li>If multiple categories implement the same method, the last one loaded wins! The load order is consistent within an application, but it&#8217;s arbitrary, out of our hands, and fragile. For all we know, our implementation could itself be overwritten by an internal framework category!</li>
</ol>

<p>Because of these reasons, this blunt approach to overriding methods should only be used for the simplest of cases. Later in this series, we&#8217;ll explore how swizzling allows us to override a method while preserving all implementations.</p>

<h2>Including Your Monkey-Patches</h2>

<p>Categories are not automatically &#8220;picked up&#8221; in a project. Any code that relies on the behavior will need to <code>#import</code> the necessary header files:</p>

<script src="https://gist.github.com/1660134.js?file=EntryCell.m"></script>

<p>However, including the same set of headers over and over again is redundant. We should first create a single header file that imports all of our most frequently used categories:</p>

<script src="https://gist.github.com/1660134.js?file=Extensions.h"></script>

<p>We can then import this single header file into a prefix header that is added to all source files. XCode projects often have a <code>.pch</code> file in the Supporting Files group for this very purpose.</p>

<script src="https://gist.github.com/1660134.js?file=pc.h"></script>

<h2>Next Up</h2>

<p>While adding and overriding classes is straightforward, there is one very big caveat when using Categories; you <strong>cannot add new instance variables</strong> to a class. We&#8217;ll take a look at working around this limitation in the next post.</p>

<h2><a name="tldr"></a> tl;dr</h2>

<ul>
<li>Use Objective-C categories to add functionality to existing classes without subclassing.</li>
<li>Avoid simple overrides with categories as it can cause problems with other frameworks.</li>
<li>Use prefix headers to easily import your extensions.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2012/01/23/monkey-patching-ios-with-objective-c-categories-part-1-simple-extensions-and-overrides/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Managing iOS Configurations per Environment in Xcode 4</title>
		<link>http://blog.carbonfive.com/2011/06/20/managing-ios-configurations-per-environment-in-xcode-4/</link>
		<comments>http://blog.carbonfive.com/2011/06/20/managing-ios-configurations-per-environment-in-xcode-4/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 10:16:34 +0000</pubDate>
		<dc:creator>Rob Pak</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=3545</guid>
		<description><![CDATA[At Carbon Five we usually have 3 &#8211; 4 environments our iOS applications will run against: development, acceptance, staging and production. Often, the property values that are unique across environments are URLs to APIs that we are integrating with. There &#8230; <a href="http://blog.carbonfive.com/2011/06/20/managing-ios-configurations-per-environment-in-xcode-4/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>At Carbon Five we usually have 3 &#8211; 4 environments our iOS applications will run against: development, acceptance, staging and production. Often, the property values that are unique across environments are URLs to APIs that we are integrating with. There have been several approaches for managing different configurations per environment. Some have included <a href="http://developer.apple.com/library/ios/#documentation/Xcode/Conceptual/iphone_development/115-Configuring_Applications/configuring_applications.html" target="_">conditional compilation</a> or build-time file substitution. While all are valid approaches, I opted to use Xcode&#8217;s build configurations to manage configurations per environment. Here is how I did it:</p>
<h2>Step 1: Modify Your Default PList File</h2>
<p>Your default plist file is usually named ${PRODUCT_NAME}-Info.plist and is located beneath the &#8220;Supporting Files&#8221; group of your Xcode project. Add a new row/item of type <em>String</em> to the plist file and name it <em>Configuration</em>. Set the value to be <em>${CONFIGURATION}</em>, the Xcode provided environment variable for the current build configuration.</p>
<p><a href="http://blog.carbonfive.com/wp-content/uploads/2011/05/infoplist.png"><img class="size-full wp-image-3555" title="InfoPlist" src="http://blog.carbonfive.com/wp-content/uploads/2011/05/infoplist.png" alt="" width="640" height="330" /></a></p>
<p><span id="more-3545"></span></p>
<h2>Step 2: Create a Custom Environments.plist File to Store Configuration Data</h2>
<p>Right-click on the &#8220;Supporting Files&#8221; group and select &#8220;New File&#8221; (New File &gt; Resource &gt; Property List). Save File as &#8220;Environments&#8221;, this will create a file named &#8220;Environments.plist&#8221;. Now that you have your custom plist file ready to be modified, add all of your build configurations (Debug and Release by default) of type Dictionary to the plist. You can also begin to enter custom properties underneath each build configuration (entered as myAPIURL in my example).</p>
<p>Optionally, you can segregate your property files per build configuration. For example, create plist files for each of your build configurations (i.e. Debug.plist, Release.plist).</p>
<p><a href="http://blog.carbonfive.com/wp-content/uploads/2011/05/environments.png"><img class="alignnone size-full wp-image-3559" title="Environments" src="http://blog.carbonfive.com/wp-content/uploads/2011/05/environments.png" alt="Add Custom Properties to Configuration by Environment (Build Configuration)" width="640" height="274" /></a></p>
<h2>Step 3: Make your Custom Configuration Available to your Application</h2>
<p>Create a singleton or implement a strategy to load your configuration data on a per build configuration basis. You can determine your scheme&#8217;s current build configuration by reading the &#8220;Configuration&#8221; property within your default plist file (as applied in step one).</p>
<p>For example, here is a singleton that will load your configuration:<br />
<script src="https://gist.github.com/1032532.js?file=Environment.m"></script></p>
<p>Now you should be able to access properties within your application by sending getter messages to the Environment instance.</p>
<p><pre class="brush: objc; title: ; notranslate">
Environment *myEnvironment = [Environment sharedInstance];
NSString *apiURL = myEnvironment.myApiURL;
</pre>
</p>
<h2>Step 4: Add Additional Build Configurations to your Application</h2>
<p>Within Xcode, select your Project within the left-hand navigation. Your project and target settings should be visible and editable. Next, select your project settings so that your build configurations are exposed (by default, Xcode creates the Debug and Release build configurations for you). At this point you can create a new build configuration for a custom environment (i.e. acceptance, staging or demo).</p>
<p><a href="http://blog.carbonfive.com/wp-content/uploads/2011/05/project.png"><img class="size-full wp-image-3574" title="project" src="http://blog.carbonfive.com/wp-content/uploads/2011/05/project.png" alt="" width="640" height="286" /></a></p>
<p>
 Also, don&#8217;t forget to add your custom configuration data for your new build configuration.
</p>
<p><a href="http://blog.carbonfive.com/wp-content/uploads/2011/05/acceptance.png"><img class="size-full wp-image-3575" title="acceptance" src="http://blog.carbonfive.com/wp-content/uploads/2011/05/acceptance.png" alt="" width="640" height="220" /></a></p>
<h2>Now Your Ready!</h2>
<p>Your application now has access to configurations per environment by use of build configurations. We&#8217;ve made the current build configuration readable by adding it to the default plist file. We used the current build configuration as an identifier for key&#8217;ing entries in a custom properties file (Environments.plist). The custom properties file contains configuration properties per build configuration. In order to read the custom properties programmatically, we created an object (Environment.m) to read the file. Finally, we added custom build configurations to support new, application specific, environments.</p>
<p>Some side notes:</p>
<ul>
<li>One target, configurable schemes: You can change the build configuration you would like to use for a target by editing (or creating) your scheme. This will quickly allow you to run your target against different application environments.</li>
<li>Properties like bundle identifier and bundle name can be set by user defined properties and further specified by your build configurations. This will make deploying you application to devices easier.</li>
<li>The Xcode command line build tool has a parameter named &#8220;configuration&#8221;. This will allow you to build your application per environment (i.e. xcodebuild -configuration Debug).</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2011/06/20/managing-ios-configurations-per-environment-in-xcode-4/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Debug logging with Xcode 4 breakpoints</title>
		<link>http://blog.carbonfive.com/2011/06/16/debug-logging-with-xcode-4-breakpoints/</link>
		<comments>http://blog.carbonfive.com/2011/06/16/debug-logging-with-xcode-4-breakpoints/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 00:12:04 +0000</pubDate>
		<dc:creator>Jonah Williams</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=4111</guid>
		<description><![CDATA[NSLog calls do not belong in release builds. Logging is slow and the performance impact of log statements on a device can be considerable. Logging is also noisy, it can obscure useful debugging information and may leak information you would &#8230; <a href="http://blog.carbonfive.com/2011/06/16/debug-logging-with-xcode-4-breakpoints/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>NSLog calls do not belong in release builds. Logging is slow and the performance impact of log statements on a device can be considerable. Logging is also noisy, it can obscure useful debugging information and may leak information you would rather not expose in a release build. Looking at my device&#8217;s system log I see output full of content urls, api keys, massive log messages, and data only valuable while debugging an app.</p>
<blockquote><p>: Succeeded! Received 18977 bytes of data for url http://www&#8230;<br />
: fetched comments: ( &#8230;&lt;74k of JSON&gt;<br />
: *** &#8230;GetData: http://&#8230;/query?id=1001&amp;sc=17&amp;fields=&#8230;&amp;apiKey=<br />
: applicationDidBecomeActive completed<br />
: JSON parsing finished in 24 ms. String alloc took 2 ms. Comment stripping took 1 ms.<br />
: CallbackHandler registered delegate,, instance=0&#215;263650</p></blockquote>
<p>There are a number of examples of using precompiler macros to eliminate log output on non-debug builds but I recently started using Xcode 4&#8242;s breakpoints and find them to be my favorite mechanism. Breakpoints can be configured to log arbitrary output and automatically continue to avoid stopping program execution. They can be dragged from one line to another, added, disabled, and removed while your app is running. You can even check them in as part of your project to share them with other developers.<br />
<span id="more-4111"></span></p>
<p><strong>Console logging with breakpoints</strong><br />
Create a new breakpoint by clicking in the source editor&#8217;s gutter.<br />
Control-click the breakpoint to edit its behavior.<br />
<a rel="attachment wp-att-4113" href="http://blog.carbonfive.com/2011/06/16/debug-logging-with-xcode-4-breakpoints/edit_breakpoint/"><img class="alignnone size-full wp-image-4113" title="edit_breakpoint" src="http://blog.carbonfive.com/wp-content/uploads/2011/06/edit_breakpoint.png" alt="" width="498" height="273" /></a><br />
When hit the example breakpoint above will log <code>-didReceiveMemoryWarning my title is "Demo!"</code> to the console.</p>
<p><strong>Sharing breakpoints</strong><br />
In the breakpoint navigator control-click a breakpoint to share it as part of a workspace.<br />
Shared breakpoints are stored in .xcworkspace/xcshareddata/xcdebugger/Breakpoints.xcbkptlist<br />
<a rel="attachment wp-att-4114" href="http://blog.carbonfive.com/2011/06/16/debug-logging-with-xcode-4-breakpoints/share_breakpoint/"><img class="alignnone size-full wp-image-4114" title="share_breakpoint" src="http://blog.carbonfive.com/wp-content/uploads/2011/06/share_breakpoint.png" alt="" width="457" height="320" /></a><br />
<a rel="attachment wp-att-4115" href="http://blog.carbonfive.com/2011/06/16/debug-logging-with-xcode-4-breakpoints/shared_breakpoint/"><img class="alignnone size-full wp-image-4115" title="shared_breakpoint" src="http://blog.carbonfive.com/wp-content/uploads/2011/06/shared_breakpoint.png" alt="" width="490" height="290" /></a><br />
I&#8217;ve found breakpoints to be a great way to log debug information about the app in a configuration which I can choose to share with my team and which runs no risk of appearing in a release build. The breakpoints navigator gives me an easy way to jump to any of these log statements and it is trivial to switch a breakpoint from just logging to pausing the app so I can debug in depth. I&#8217;ll still use NSLog for exceptional conditions I want to report in any build but so far you won&#8217;t find a single one in my current project.</p>
<p>Have you found a NSLog alternative you are happy with? Is there anything you couldn&#8217;t replace with logging breakpoints instead?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2011/06/16/debug-logging-with-xcode-4-breakpoints/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Automated ad hoc builds using Xcode 4</title>
		<link>http://blog.carbonfive.com/2011/05/04/automated-ad-hoc-builds-using-xcode-4/</link>
		<comments>http://blog.carbonfive.com/2011/05/04/automated-ad-hoc-builds-using-xcode-4/#comments</comments>
		<pubDate>Wed, 04 May 2011 23:24:19 +0000</pubDate>
		<dc:creator>Jonah Williams</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[teamcity]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=3521</guid>
		<description><![CDATA[I&#8217;ve previously discussed Continuous Integration for iPhone Projects in TeamCity using Xcode 3 and Building Xcode 4 Projects from the Command Line. Now I&#8217;ll tie those together and use TeamCity to automatically create ad hoc builds I can install over &#8230; <a href="http://blog.carbonfive.com/2011/05/04/automated-ad-hoc-builds-using-xcode-4/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve previously discussed <a href="http://blog.carbonfive.com/2010/08/08/continuous-integration-for-iphone-projects-in-teamcity/">Continuous Integration for iPhone Projects in TeamCity</a> using Xcode 3 and <a href="http://blog.carbonfive.com/2011/04/06/building-xcode-4-projects-from-the-command-line/">Building Xcode 4 Projects from the Command Line</a>. Now I&#8217;ll tie those together and use TeamCity to automatically create ad hoc builds I can install over the air (directly onto a device without using iTunes) every time I check in code.</p>
<p><span id="more-3521"></span></p>
<p>I created a basic project configuration in TeamCity 6 to checkout my iOS project from git.</p>
<p>I set the artifact paths for this configuration to</p>
<blockquote><p>
project_name.acceptance.app*<br />
ad_hoc/*.png
</p></blockquote>
<p>This will eventually allow TeamCity to collect the icons, project_name.acceptance.app.ipa, and project_name.acceptance.app.plist files needed to perform an over the air install of the ad hoc build.</p>
<p>Finally I created the following custom script build step (available as <a href="https://gist.github.com/949831">https://gist.github.com/949831</a>).</p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/bash

# https://gist.github.com/949831
# http://blog.carbonfive.com/2011/05/04/automated-ad-hoc-builds-using-xcode-4/

# command line OTA distribution references and examples
# http://nachbaur.com/blog/how-to-automate-your-iphone-app-builds-with-hudson
# http://nachbaur.com/blog/building-ios-apps-for-over-the-air-adhoc-distribution
# http://blog.octo.com/en/automating-over-the-air-deployment-for-iphone/
# http://www.neat.io/posts/2010/10/27/automated-ota-ios-app-distribution.html

project_dir=`pwd`

# Configuration
environment_name=&quot;staging&quot;
keychain=&quot;ci_keys&quot;
keychain_password=&quot;super secret&quot;
workspace=&quot;MyApp.xcworkspace&quot;
scheme=&quot;Ad Hoc&quot;
info_plist=&quot;$project_dir/MyApp-Info.plist&quot;
environment_plist=&quot;$environment_name.plist&quot;
environment_info_plist=&quot;$environment_name-Info.plist&quot;
product_name=&quot;My App $environment_name&quot;
mobileprovision=&quot;$project_dir/ad_hoc/MyAppStaging.mobileprovision&quot;
provisioning_profile=&quot;iPhone Distribution: My Company, LLC&quot;
build_number=&quot;%env.BUILD_NUMBER%&quot;
artifacts_url=&quot;http://my_ci_server.example/artifacts/$build_number&quot;
display_image_name=&quot;Icon-57.png&quot;
full_size_image_name=&quot;Icon-512.png&quot;

function failed()
{
    local error=${1:-Undefined error}
    echo &quot;Failed: $error&quot; &gt;&amp;2
    exit 1
}

function validate_keychain()
{
  # unlock the keychain containing the provisioning profile's private key and set it as the default keychain
  security unlock-keychain -p &quot;$keychain_password&quot; &quot;$HOME/Library/Keychains/$keychain.keychain&quot;
  security default-keychain -s &quot;$HOME/Library/Keychains/$keychain.keychain&quot;

  #describe the available provisioning profiles
  echo &quot;Available provisioning profiles&quot;
  security find-identity -p codesigning -v

  #verify that the requested provisioning profile can be found
  (security find-certificate -a -c &quot;$provisioning_profile&quot; -Z | grep ^SHA-1) || failed provisioning_profile
}

function describe_sdks()
{
  #list the installed sdks
  echo &quot;Available SDKs&quot;
  xcodebuild -showsdks
}

function describe_workspace()
{
  #describe the project workspace
  echo &quot;Available schemes&quot;
  xcodebuild -list -workspace $workspace
}

function increment_version()
{
  cd &quot;MyApp&quot;
  agvtool -noscm new-version -all $build_number
  cd ..
}

function set_environment()
{
  #copy the info plist for the selected environment into place
  cp -v &quot;MyApp/$environment_info_plist&quot; $info_plist || failed environment_plist
  #copy the environment settings plist into place
  cp -v &quot;MyApp/$environment_plist&quot; &quot;MyApp/environment.plist&quot; || failed environment

  #extract settings from the Info.plist file
  info_plist_domain=$(ls $info_plist | sed -e 's/\.plist//')
  short_version_string=$(defaults read &quot;$info_plist_domain&quot; CFBundleShortVersionString)
  bundle_identifier=$(defaults read &quot;$info_plist_domain&quot; CFBundleIdentifier)
  echo &quot;Environment set to $bundle_identifier at version $short_version_string&quot;
}

function build_app()
{
  local devired_data_path=&quot;$HOME/Library/Developer/Xcode/DerivedData&quot;

  #get the name of the workspace to be build, used as the prefix of the DerivedData directory for this build
  local workspace_name=$(echo &quot;$workspace&quot; | sed -n 's/\([^\.]\{1,\}\)\.xcworkspace/\1/p')
  #build the app
  echo &quot;Running xcodebuild &gt; xcodebuild_output ...&quot;

#  disabled overriding PRODUCT_NAME, setting applies to all built targets in Xcode 4 which renames static library target dependencies and breaks linking
#  xcodebuild -verbose -workspace &quot;$workspace&quot; -scheme &quot;$scheme&quot; -sdk iphoneos -configuration Release clean build PRODUCT_NAME=&quot;$product_name&quot; &gt;| xcodebuild_output
  xcodebuild -verbose -workspace &quot;$workspace&quot; -scheme &quot;$scheme&quot; -sdk iphoneos -configuration Release clean build &gt;| xcodebuild_output

  if [ $? -ne 0 ]
  then
    tail -n20 xcodebuild_output
    failed xcodebuild
  fi

  #locate this project's DerivedData directory
  local project_derived_data_directory=$(grep -oE &quot;$workspace_name-([a-zA-Z0-9]+)[/]&quot; xcodebuild_output | sed -n &quot;s/\($workspace_name-[a-z]\{1,\}\)\//\1/p&quot; | head -n1)
  local project_derived_data_path=&quot;$devired_data_path/$project_derived_data_directory&quot;
  #locate the .app file

#  infer app name since it cannot currently be set using the product name, see comment above
#  project_app=&quot;$product_name.app&quot;
  project_app=$(ls -1 &quot;$project_derived_data_path/Build/Products/Release-iphoneos/&quot; | grep &quot;.*\.app$&quot; | head -n1)

  # if [ $(ls -1 &quot;$project_derived_data_path/Build/Products/Release-iphoneos/$project_app&quot; | wc -l) -ne 1 ]
  if [ $(ls -1 &quot;$project_derived_data_path/Build/Products/Release-iphoneos/&quot; | grep &quot;.*\.app$&quot; | wc -l) -ne 1 ]
  then
    echo &quot;Failed to find a single .app build product.&quot;
    # echo &quot;Failed to locate $project_derived_data_path/Build/Products/Release-iphoneos/$project_app&quot;
    failed locate_built_product
  fi
  echo &quot;Built $project_app in $project_derived_data_path&quot;

  #copy app and dSYM files to the working directory
  cp -Rf &quot;$project_derived_data_path/Build/Products/Release-iphoneos/$project_app&quot; $project_dir
  cp -Rf &quot;$project_derived_data_path/Build/Products/Release-iphoneos/$project_app.dSYM&quot; $project_dir

  #rename app and dSYM so that multiple environments with the same product name are identifiable
  echo &quot;Retrieving build products...&quot;
  rm -rf $project_dir/$bundle_identifier.app
  rm -rf $project_dir/$bundle_identifier.app.dSYM
  mv -f &quot;$project_dir/$project_app&quot; &quot;$project_dir/$bundle_identifier.app&quot;
  echo &quot;$project_dir/$bundle_identifier.app&quot;
  mv -f &quot;$project_dir/$project_app.dSYM&quot; &quot;$project_dir/$bundle_identifier.app.dSYM&quot;
  echo &quot;$project_dir/$bundle_identifier.app.dSYM&quot;
  project_app=$bundle_identifier.app

  #relink CodeResources, xcodebuild does not reliably construct the appropriate symlink
  rm &quot;$project_app/CodeResources&quot;
  ln -s &quot;$project_app/_CodeSignature/CodeResources&quot; &quot;$project_app/CodeResources&quot;
}

function sign_app()
{
  echo &quot;Codesign as \&quot;$provisioning_profile\&quot;, embedding provisioning profile $mobileprovision&quot;
  #sign build for distribution and package as a .ipa
  xcrun -sdk iphoneos PackageApplication &quot;$project_dir/$project_app&quot; -o &quot;$project_dir/$project_app.ipa&quot; --sign &quot;$provisioning_profile&quot; --embed &quot;$mobileprovision&quot; || failed codesign
}

function verify_app()
{
  #verify the resulting app
  codesign -d -vvv --file-list - &quot;$project_dir/$project_app&quot; || failed verification
}

function build_ota_plist()
{
  echo &quot;Generating $project_app.plist&quot;
  cat &lt;&lt; EOF &gt; $project_app.plist
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
&lt;plist version=&quot;1.0&quot;&gt;
&lt;dict&gt;
  &lt;key&gt;items&lt;/key&gt;
  &lt;array&gt;
    &lt;dict&gt;
      &lt;key&gt;assets&lt;/key&gt;
      &lt;array&gt;
        &lt;dict&gt;
          &lt;key&gt;kind&lt;/key&gt;
          &lt;string&gt;software-package&lt;/string&gt;
          &lt;key&gt;url&lt;/key&gt;
          &lt;string&gt;$artifacts_url/$project_app.ipa&lt;/string&gt;
        &lt;/dict&gt;
        &lt;dict&gt;
          &lt;key&gt;kind&lt;/key&gt;
          &lt;string&gt;full-size-image&lt;/string&gt;
          &lt;key&gt;needs-shine&lt;/key&gt;
          &lt;true/&gt;
          &lt;key&gt;url&lt;/key&gt;
          &lt;string&gt;$artifacts_url/$full_size_image_name&lt;/string&gt;
        &lt;/dict&gt;
        &lt;dict&gt;
          &lt;key&gt;kind&lt;/key&gt;
          &lt;string&gt;display-image&lt;/string&gt;
          &lt;key&gt;needs-shine&lt;/key&gt;
          &lt;true/&gt;
          &lt;key&gt;url&lt;/key&gt;
          &lt;string&gt;$artifacts_url/$display_image_name&lt;/string&gt;
        &lt;/dict&gt;
      &lt;/array&gt;
      &lt;key&gt;metadata&lt;/key&gt;
      &lt;dict&gt;
        &lt;key&gt;bundle-identifier&lt;/key&gt;
        &lt;string&gt;$bundle_identifier&lt;/string&gt;
        &lt;key&gt;bundle-version&lt;/key&gt;
        &lt;string&gt;$short_version_string $build_number&lt;/string&gt;
        &lt;key&gt;kind&lt;/key&gt;
        &lt;string&gt;software&lt;/string&gt;
        &lt;key&gt;subtitle&lt;/key&gt;
        &lt;string&gt;$environment_name&lt;/string&gt;
        &lt;key&gt;title&lt;/key&gt;
        &lt;string&gt;$project_app&lt;/string&gt;
      &lt;/dict&gt;
    &lt;/dict&gt;
  &lt;/array&gt;
&lt;/dict&gt;
&lt;/plist&gt;
EOF
}

echo &quot;**** Validate Keychain&quot;
validate_keychain
echo
echo &quot;**** Describe SDKs&quot;
describe_sdks
echo
echo &quot;**** Describe Workspace&quot;
describe_workspace
echo
echo &quot;**** Set Environment&quot;
set_environment
echo
echo &quot;**** Increment Bundle Version&quot;
increment_version
echo
echo &quot;**** Build&quot;
build_app
echo
echo &quot;**** Package Application&quot;
sign_app
echo
echo &quot;**** Verify&quot;
verify_app
echo
echo &quot;**** Prepare OTA Distribution&quot;
build_ota_plist
echo
echo &quot;**** Complete!&quot;
</pre>
<p>That is quite a few functions but the bottom of the script steps through them in what is hopefully an understandable sequence.</p>
<ol>
<li>Unlock the keychain containing the private key and provisioning profile used to sign the ad hoc build. Necessary since the TeamCity user&#8217;s login keychain may be locked when this build runs.</li>
<li>List the available sdks on the build machine (unnecessary but I found it helpful when debugging build settings).</li>
<li>List the schemes found in the workspace to be built (again purely for debugging).</li>
<li>Copy a plist containing application settings to &#8220;environment.plist&#8221; which will be copied into the app bundle when built and used to define application behavior, for example it contains the url of the server this build should communicate with.</li>
<li>Build the app using the specified workspace and scheme. Copy the resulting app and dSYM to the project directory so TeamCity can easily find them as build artifacts.</li>
<li>Sign the app using the specified mobile provisioning profile and create a &#8220;.ipa&#8221; package.</li>
<li>Verify that the app was successfully signed.</li>
<li>Create a plist to allow over the air installation of the app.</li>
</ol>
<p>Once run any device which has been added to the mobile provisioning profile used to sign this build can install the app just by visiting (using an appropriate %system.teamcity.buildType.id% for the TeamCity build configuration).</p>
<blockquote><p>
itms-services://?action=download-manifest&amp;url=http://teamcity.example.com:8111/guestAuth/repository/download/%system.teamcity.buildType.id%/.lastSuccessful/project_name.acceptance.app.plist
</p></blockquote>
<p>Possible issues:</p>
<ul>
<li>Access to the keychain will present a security dialog the first time this build runs so it was necessary for me to sign into the TeamCity user&#8217;s account using VNC and allow access to that keychain.</li>
<li>I found that builds occasionally failed to correctly create the CodeResources symlink so I recreate it manually. When this link was broken the ipa would fail verification.</li>
<li>An iOS device won&#8217;t be able to install the app if the artifacts require authenticating to the TeamCity server so I enabled guest access. Alternately I could have exposed those artifacts through some other service and created a nice installation guide page which links to them if I didn&#8217;t want to allow guest access to my TeamCity server.</li>
</ul>
<p>For additional resources for building over the air distribution builds take a look at:</p>
<p>Mike Nachbaur&#8217;s posts on &#8220;<a href="http://nachbaur.com/blog/how-to-automate-your-iphone-app-builds-with-hudson">How to Automate your iPhone App Builds with Hudson</a>&#8221; and &#8220;<a href="http://nachbaur.com/blog/building-ios-apps-for-over-the-air-adhoc-distribution">Building iOS Apps for Over the Air Ad Hoc Distribution</a>&#8220;.<br />
Vincent Daubry&#8217;s &#8220;<a href="http://blog.octo.com/en/automating-over-the-air-deployment-for-iphone/">Automating Over The Air Deployment for iPhone</a>&#8220;.<br />
Basil Shkara&#8217;s &#8220;<a href="http://www.neat.io/posts/2010/10/27/automated-ota-ios-app-distribution.html">Automated OTA iOS App Distribution</a>&#8220;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2011/05/04/automated-ad-hoc-builds-using-xcode-4/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Building Xcode 4 projects from the command line</title>
		<link>http://blog.carbonfive.com/2011/04/06/building-xcode-4-projects-from-the-command-line/</link>
		<comments>http://blog.carbonfive.com/2011/04/06/building-xcode-4-projects-from-the-command-line/#comments</comments>
		<pubDate>Wed, 06 Apr 2011 10:00:59 +0000</pubDate>
		<dc:creator>Jonah Williams</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=3336</guid>
		<description><![CDATA[The Xcode 4 developer tools introduced some changes to the xcodebuild command line tool. Instead of specifying a project and target developers can now provide a workspace and scheme to build. &#62; /Developer_Xcode4/usr/bin/xcodebuild -help Usage: xcodebuild [-project ] [[-target ]&#8230;&#124;-alltargets] &#8230; <a href="http://blog.carbonfive.com/2011/04/06/building-xcode-4-projects-from-the-command-line/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The Xcode 4 developer tools introduced some changes to the xcodebuild command line tool. Instead of specifying a project and target developers can now provide a workspace and scheme to build.<br />
<span id="more-3336"></span></p>
<blockquote><p>&gt; /Developer_Xcode4/usr/bin/xcodebuild -help<br />
Usage: xcodebuild [-project ] [[-target ]&#8230;|-alltargets] [-configuration ] [-arch ]&#8230; [-sdk [|]] [=]&#8230; []&#8230;<br />
       xcodebuild -workspace  -scheme  [-configuration ] [-arch ]&#8230; [-sdk [|]] [=]&#8230; []&#8230;<br />
       xcodebuild -version [-sdk [|] [] ]<br />
       xcodebuild -list [[-project ]|[-workspace ]]<br />
       xcodebuild -showsdks
</p></blockquote>
<p>The workspace and scheme names should be known from the project. The default configuration options are &#8220;Debug&#8221; and &#8220;Release&#8221;. The &#8220;-showsdks&#8221; option lists available SDKs.</p>
<blockquote><p>&gt; /Developer_Xcode4/usr/bin/xcodebuild -showsdks<br />
Mac OS X SDKs:<br />
	Mac OS X 10.6                 	-sdk macosx10.6</p>
<p>iOS SDKs:<br />
	iOS 4.3                       	-sdk iphoneos4.3</p>
<p>iOS Simulator SDKs:<br />
	Simulator &#8211; iOS 3.2           	-sdk iphonesimulator3.2<br />
	Simulator &#8211; iOS 4.0           	-sdk iphonesimulator4.0<br />
	Simulator &#8211; iOS 4.1           	-sdk iphonesimulator4.1<br />
	Simulator &#8211; iOS 4.2           	-sdk iphonesimulator4.2<br />
	Simulator &#8211; iOS 4.3           	-sdk iphonesimulator4.3
</p></blockquote>
<p>Available build actions are listed in the xcodebuild man pages. Unfortunately these do not match the actions available in a scheme and the command line does not provide a mechanism for testing, running, profiling, or analyzing builds.</p>
<blockquote><p>&gt; man xcodebuild<br />
&#8230;</p>
<p>buildaction &#8230;<br />
           Specify a build action (or actions) to perform on the target. Available build actions are:</p>
<p>           build       Build the target in the build root (SYMROOT).  This is the default build action.</p>
<p>           archive     Archive a scheme from the build root (SYMROOT).  This requires specifying a workspace and scheme.</p>
<p>           installsrc  Copy the source of the project to the source root (SRCROOT).</p>
<p>           install     Build the target and install it into the target&#8217;s installation directory in the distribution root (DSTROOT).</p>
<p>           clean       Remove build products and intermediate files from the build root (SYMROOT).
</p></blockquote>
<p>Given all of these configuration options it is then possible to perform builds from the command line.</p>
<blockquote><p>&gt; /Developer_Xcode4/usr/bin/xcodebuild -workspace WrappingScrollView.xcworkspace -scheme WrappingScrollViewDemo -sdk iphonesimulator4.3 -configuration Debug clean build<br />
Build settings from command line:<br />
    SDKROOT = iphonesimulator4.3</p>
<p>=== CLEAN NATIVE TARGET JCFWrappingScrollView OF PROJECT JCFWrappingScrollView WITH CONFIGURATION Debug ===<br />
Check dependencies</p>
<p>&#8230;</p>
<p>** CLEAN SUCCEEDED **</p>
<p>=== BUILD NATIVE TARGET JCFWrappingScrollView OF PROJECT JCFWrappingScrollView WITH CONFIGURATION Debug ===<br />
Check dependencies</p>
<p>ProcessPCH /Users/Jonah/Library/Developer/Xcode/DerivedData/WrappingScrollView-fqscqfdtpoqunuanehtbgpseirdj/Build/PrecompiledHeaders/JCFWrappingScrollView-Prefix-dkkjrdaonxokgpbkgjfmpmcpadoz/JCFWrappingScrollView-Prefix.pch.gch JCFWrappingScrollView/JCFWrappingScrollView-Prefix.pch normal i386 objective-c com.apple.compilers.llvmgcc42<br />
    cd /Users/Jonah/Desktop/WrappingScrollView/JCFWrappingScrollView<br />
    setenv LANG en_US.US-ASCII</p>
<p>&#8230;</p>
<p>** BUILD SUCCEEDED **
</p></blockquote>
<p>Hopefully that is sufficient to automatically produce ad-hoc builds on a continuous integration server.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2011/04/06/building-xcode-4-projects-from-the-command-line/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Using Open Source Static Libraries in Xcode 4</title>
		<link>http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/</link>
		<comments>http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 18:00:21 +0000</pubDate>
		<dc:creator>Jonah Williams</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=3196</guid>
		<description><![CDATA[Xcode 4.0.1 allows us to more easily create and use third party libraries in iOS projects. I think the process is still more complicated than it needs to be. Xcode&#8217;s documentation suggests that it should automatically detect implicit dependencies and &#8230; <a href="http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Xcode 4.0.1 allows us to more easily create and use third party libraries in iOS projects. I think the process is still more complicated than it needs to be. Xcode&#8217;s documentation suggests that it should automatically detect implicit dependencies and index classes across workspaces but I have not found this to be the case. Here I&#8217;ll cover the steps I have found for creating and sharing code between projects and with other developers.<br />
<span id="more-3196"></span></p>
<ol>
<li><a href="#background">Background</a></li>
<li><a href="#using_a_static_library">Using a Static Library</a></li>
<li><a href="#creating_a_static_library">Creating a Static Library</a></li>
<li><a href="#future_improvements">Future Improvements</a></li>
</ol>
<p><a name="background"></a></p>
<h2>Background</h2>
<h3>Workspaces:</h3>
<p>Xcode 4 introduced the concept of <a href="http://developer.apple.com/library/ios/#featuredarticles/XcodeConcepts/Concept-Workspace.html">workspaces</a> as containers for multiple projects. There are a couple of key behaviors of workspaces which we want to build on when choosing how to share code across projects.</p>
<ul>
<li>By default, all the Xcode projects in a workspace are built in the same directory, referred to as the workspace build directory.</li>
<li>Xcode examines the files in the build directory to discover implicit dependencies.</li>
<li>Each project in a workspace continues to have its own independent identity.</li>
</ul>
<h3>Schemes:</h3>
<p>Within a workspace or within a project which is a member of a workspace we have <a href="http://developer.apple.com/library/ios/#featuredarticles/XcodeConcepts/Concept-Schemes.html">schemes</a>. Schemes replace the Active Target, Build Configuration, and Executable settings from Xcode 3 and define which targets to build, the order in which to build them, and what action to take when a build is complete. We&#8217;ll want our shared code to easily fit into the scheme of any projects which use it. The <a href="http://developer.apple.com/library/mac/#documentation/IDEs/Conceptual/Xcode4TransitionGuide/Orientation/Orientation.html#//apple_ref/doc/uid/TP40009984-CH5-SW26">Xcode 4 Transition Guide</a> covers this new structure in more detail.</p>
<h3>Targets:</h3>
<p>Within a scheme we have one or more build <a href="http://developer.apple.com/library/ios/#featuredarticles/XcodeConcepts/Concept-Targets.html">targets</a> which define a set of source files to build, the settings used to build those files, and any dependencies on the build products of other targets which must be completed first. Ultimately we would like a consumer of our code to be able to state that their project&#8217;s build target depends on our shared code and have Xcode build this shared code and make it available to the active build target. We can achieve that by providing a project containing the code to be shared and a static library build target which packages it into a build product other developers can add as a build target dependency.<br />
<a name="using_a_static_library"></a></p>
<h2>Using a static library</h2>
<ol>
<li><a href="#creating_a_workspace">Creating a workspace</a></li>
<li><a href="#adding_projects_to_a_workspace">Adding projects to a workspace</a></li>
<li><a href="#adding_build_target_dependencies">Adding build target dependencies</a></li>
<li><a href="#adding_the_static_librarys_headers">Adding the static library&#8217;s headers</a></li>
<li><a href="#configuring_the_projects_scheme">Configuring the project&#8217;s scheme</a></li>
<li><a href="#fixing_indexing">Fixing indexing</a></li>
</ol>
<p><a name="creating_a_workspace"></a></p>
<h3>Creating a workspace</h3>
<p>We can create a new empty workspace from Xcode&#8217;s file menu or open an existing project and select &#8220;Save As Workspace&#8230;&#8221; to create a new workspace containing our project. This will create a &#8220;.xcworkspace&#8221; package in the file system.</p>
<p><div id="attachment_3314" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.carbonfive.com/wp-content/uploads/2011/04/empty_workspace.png"><img class="size-medium wp-image-3314" title="empty workspace" src="http://blog.carbonfive.com/wp-content/uploads/2011/04/empty_workspace.png?w=300" alt="An empty Xcode 4 workspace" width="300" height="147" /></a><p class="wp-caption-text">An empty Xcode 4 workspace</p></div><br />
<a name="adding_projects_to_a_workspace"></a></p>
<h3>Adding projects to a workspace</h3>
<p>Once we have a workspace we can right-click in the workspace&#8217;s navigator to create a new project or add an existing &#8220;.xcodeproj&#8221; package.</p>
<p><div id="attachment_3317" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.carbonfive.com/wp-content/uploads/2011/04/adding_a_project.png"><img class="size-medium wp-image-3317" title="adding a project" src="http://blog.carbonfive.com/wp-content/uploads/2011/04/adding_a_project.png?w=300" alt="Adding a new project to a workspace" width="300" height="184" /></a><p class="wp-caption-text">Adding a new project to a workspace</p></div></p>
<p><div id="attachment_3318" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.carbonfive.com/wp-content/uploads/2011/04/adding_an_existing_project.png"><img class="size-medium wp-image-3318" title="adding an existing project" src="http://blog.carbonfive.com/wp-content/uploads/2011/04/adding_an_existing_project.png?w=300" alt="Adding an existing project to a workspace" width="300" height="274" /></a><p class="wp-caption-text">Adding an existing project to a workspace</p></div></p>
<p>We want to end up with a single workspace containing our app&#8217;s project and the projects for any static libraries we are going to depend on. It is worth noting that these projects are all siblings in the workspace, our static libraries are not added as references within our app&#8217;s project.</p>
<p>&nbsp;<br />
<a name="adding_build_target_dependencies"></a></p>
<h3>Adding build target dependencies</h3>
<p>With all of the projects we need available in our workspace we can select our app&#8217;s build target and add a static library to the &#8220;Link Binary With Libraries&#8221; build phase.</p>
<p><div id="attachment_3319" class="wp-caption alignnone" style="width: 224px"><a href="http://blog.carbonfive.com/wp-content/uploads/2011/04/linkable_libraries.png"><img class="size-medium wp-image-3319" title="linkable libraries" src="http://blog.carbonfive.com/wp-content/uploads/2011/04/linkable_libraries.png?w=214" alt="Libraries and frameworks available to add to the &quot;Link Binary With Libraries&quot; build phase" width="214" height="300" /></a><p class="wp-caption-text">Libraries and frameworks available to add to the &quot;Link Binary With Libraries&quot; build phase</p></div></p>
<p><div id="attachment_3320" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.carbonfive.com/wp-content/uploads/2011/04/linking_with_static_library.png"><img class="size-medium wp-image-3320" title="linking with a static library" src="http://blog.carbonfive.com/wp-content/uploads/2011/04/linking_with_static_library.png?w=300" alt="A static library added to the &quot;Link Binary With Libraries&quot; build phase" width="300" height="170" /></a><p class="wp-caption-text">A static library added to the &quot;Link Binary With Libraries&quot; build phase</p></div><br />
<a name="adding_the_static_librarys_headers"></a></p>
<h3>Adding the static library&#8217;s headers</h3>
<p>We also need to make sure that our app&#8217;s build target can locate the public headers used in this static library. Open the &#8220;Build Settings&#8221; tab and locate the &#8220;User Header Search Paths&#8221; setting. Set this to &#8220;$(BUILT_PRODUCTS_DIR)&#8221; (or &#8220;$(BUILT_PRODUCTS_DIR)/static_library_name&#8221; if we want to be more specific but then we&#8217;ll have to update this setting every time we add another library) and check the &#8220;Recursive&#8221; check box. Now our built target will search our workspace&#8217;s shared build directory to locate linkable header files.</p>
<p><div id="attachment_3321" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.carbonfive.com/wp-content/uploads/2011/04/header_search_path_value.png"><img class="size-medium wp-image-3321" title="user header search paths value" src="http://blog.carbonfive.com/wp-content/uploads/2011/04/header_search_path_value.png?w=300" alt="Setting the User Header Search Paths" width="300" height="194" /></a><p class="wp-caption-text">Setting the User Header Search Paths</p></div></p>
<p><div id="attachment_3322" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.carbonfive.com/wp-content/uploads/2011/04/set_user_header_search_paths.png"><img class="size-medium wp-image-3322" title="user header search paths set" src="http://blog.carbonfive.com/wp-content/uploads/2011/04/set_user_header_search_paths.png?w=300" alt="User Header Search Paths set" width="300" height="147" /></a><p class="wp-caption-text">User Header Search Paths set</p></div></p>
<p>The &#8220;User Header Search Paths&#8221; setting defines the headers available as quoted imports (eg &#8220;#import &#8220;MyLibraryClass.h&#8221;) while the &#8220;Header Search Paths&#8221; setting defines those headers available as bracketed imports (eg &#8220;#import ). I&#8217;ve found that Xcode will only autocomplete header names in the quoted form so I always add libraries to the user header search path even though, from my project&#8217;s perspective, they might be more appropriate as system level (angle bracketed) libraries.</p>
<p>When using a static library which includes categories we will also have to add the &#8220;-ObjC&#8221; flag to the &#8220;Other Linker Flags&#8221; build setting. This will force the linker to load all objective-c classes and categories from the library. If the library contains only categories &#8220;-all_load&#8221; or &#8220;-force_load&#8221; may be needed as well. See <a href="http://developer.apple.com/library/mac/#qa/qa1490/_index.html">Technical Q&amp;A QA1490</a> for a more detailed explanation of these settings.<br />
<a name="configuring_the_projects_scheme"></a></p>
<h3>Configuring the project&#8217;s scheme</h3>
<p>At this point Xcode should have detected this implicit dependency between our app&#8217;s project and the static library&#8217;s project and have automatically configured our schemes correctly. Unfortunately I haven&#8217;t found this to be the case in practice. Instead we will have to edit our current scheme and add the static library&#8217;s build target before our app&#8217;s build target.</p>
<p><div id="attachment_3323" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.carbonfive.com/wp-content/uploads/2011/04/setting_target_build_order.png"><img class="size-medium wp-image-3323" title="setting target build order" src="http://blog.carbonfive.com/wp-content/uploads/2011/04/setting_target_build_order.png?w=300" alt="Setting the scheme's target build order" width="300" height="205" /></a><p class="wp-caption-text">Setting the scheme&#039;s target build order</p></div><br />
<a name="fixing_indexing"></a></p>
<h3>Fixing indexing</h3>
<p>At this point we should be able to include headers from dependent static libraries, use the included classes, and still successfully build our app. Unfortunately Xcode will not show any classes from these linked static libraries in code completion despite the workspace documentation stating that &#8220;indexing is done across the entire workspace, extending the scope of content-aware features such as code completion and refactoring.&#8221;<br />
As a workaround we can drag the public headers from the static library&#8217;s project into our app&#8217;s project, adding them as references. These headers do not need to be included in any of our build targets, simply having references to the headers in our project will allow their classes to appear in code completion.<br />
<a name="creating_a_static_library"></a></p>
<h2>Creating a Static Library</h2>
<p>If we plan on releasing some of our own code for reuse as a static library there are several things we should do to make sure that the process described above is as easy and simple as possible for our library&#8217;s users.</p>
<ol>
<li><a href="#namespace_classes_appropriately">Namespace classes appropriately</a></li>
<li><a href="#create_a_build_target">Create a build target</a></li>
<li><a href="#expose_public_headers">Expose public headers</a></li>
<li><a href="#set_the_installation_directory">Set the installation directory</a></li>
<li><a href="#set_the_public_header_path">Set the public header path</a></li>
<li><a href="#exclude_user_specific_files_from_vcs">Exclude user specific files from VCS</a></li>
</ol>
<p><a name="namespace_classes_appropriately"></a></p>
<h3>Namespace classes appropriately</h3>
<p>Use an appropriate <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingBasics.html#//apple_ref/doc/uid/20001281-1002226">prefix</a> for classes, protocols, functions, and constants in the library to prevent collisions with names in the library&#8217;s user&#8217;s project.<br />
<a name="create_a_build_target"></a></p>
<h3>Create a build target</h3>
<p>Provide a static library build target in the project for our users to link against. Xcode provides templates for creating projects with static libraries or adding static library build targets to existing projects.<br />
<a name="expose_public_headers"></a></p>
<h3>Expose public headers</h3>
<p>Determine which header files should be visible to users of the library. Provide a clearly named group containing these headers so that our library&#8217;s users can easily locate them as part of the workaround described in &#8220;Fixing Indexing&#8221; above. This also helps us clarify what the public interface our library provides is and what classes are implementation details which are likely to change as the library evolves.</p>
<p>For each public header file make sure it is set as &#8220;public&#8221; in the &#8220;Target Membership&#8221; section of the inspector pane. Only public headers are going to be available for our users to import.</p>
<p><div id="attachment_3326" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.carbonfive.com/wp-content/uploads/2011/04/making_headers_public.png"><img class="size-medium wp-image-3326" title="making headers public" src="http://blog.carbonfive.com/wp-content/uploads/2011/04/making_headers_public.png?w=300" alt="Making a header file public" width="300" height="147" /></a><p class="wp-caption-text">Making a header file public</p></div><br />
<a name="set_the_installation_directory"></a></p>
<h3>Set installation directory</h3>
<p>Our static library build target is going to be a member of a user&#8217;s workspace and subject to that workspace&#8217;s installation rules. Our static library build product could therefore be installed in a location set by Xcode&#8217;s preferences, in the derived data path, or in a path specified by our build target. Since we can&#8217;t control the user&#8217;s settings we should make sure our library is well behaved in all cases. I set the &#8220;Installation Directory&#8221; build setting to &#8220;$(BUILT_PRODUCTS_DIR)&#8221; so that the static library build product can be found in a known location and set the &#8220;Skip Install&#8221; build setting to &#8220;Yes&#8221; to avoid accidentally installing iOS libraries into &#8220;/usr/local/lib&#8221;.</p>
<p><div id="attachment_3327" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.carbonfive.com/wp-content/uploads/2011/04/set_installation_directory.png"><img class="size-medium wp-image-3327" title="set installation directory" src="http://blog.carbonfive.com/wp-content/uploads/2011/04/set_installation_directory.png?w=300" alt="Setting the installation directory" width="300" height="164" /></a><p class="wp-caption-text">Setting the installation directory</p></div><br />
<a name="set_the_public_header_path"></a></p>
<h3>Set the public header path</h3>
<p>We need to specify a location to copy our static library&#8217;s public headers to so that they can be included in our users&#8217; header search paths. Setting the &#8220;Public Headers Folder Path&#8221; to &#8220;$(TARGET_NAME)&#8221; will create a folder named after our static library build target in the workspace&#8217;s shared build directory and be indexed by the &#8220;User Header Search Paths&#8221; setting described above.</p>
<p><div id="attachment_3328" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.carbonfive.com/wp-content/uploads/2011/04/set_public_headers_path.png"><img class="size-medium wp-image-3328" title="set public headers path" src="http://blog.carbonfive.com/wp-content/uploads/2011/04/set_public_headers_path.png?w=300" alt="Setting the public headers path for the static library" width="300" height="147" /></a><p class="wp-caption-text">Setting the public headers path for the static library</p></div><br />
<a name="exclude_user_specific_files_from_vcs"></a></p>
<h3>Exclude user specific files from VCS</h3>
<p>Our workspace and project include a number of files which contain data relevant only to our user account; window positions, open files, and so on. There&#8217;s no need to check these into source control, at least not in our release branch, so let&#8217;s set some reasonable ignore rules in git or whatever VCS we are using. Github provides a convenient set of <a href="https://github.com/github/gitignore">.gitignore files</a><br />
<a name="future_improvements"></a></p>
<h2>Future Improvements</h2>
<p>Hopefully Xcode 4 will eventually live up to the promise of it&#8217;s documentation and consistently auto-detect implicit dependencies and index files across the workspace correctly. There certainly seem to be a number of other developers struggling with this behavior:[<a href="https://devforums.apple.com/message/390470#390470">1</a>], [<a href="https://devforums.apple.com/message/399673#399673">2</a>], [<a href="https://devforums.apple.com/message/397932#397932">3</a>], [<a href="https://devforums.apple.com/message/399316#399316">4</a>], [<a href="https://devforums.apple.com/message/375741#375741">5</a>], [<a href="https://devforums.apple.com/message/377781#377781">6</a>], [<a href="http://stackoverflow.com/questions/5427396/whats-the-correct-way-to-configure-xcode-4-workspaces-to-build-dependencies-when">7</a>], [<a href="http://stackoverflow.com/questions/5483909/how-should-i-manage-dependencies-across-projects-in-an-xcode-workspace">8</a>]. Until that indexing improves I find that this process is at least somewhat simpler and cleaner than trying to maintain simulator and device compatible static library builds in Xcode 3.<br />
I&#8217;ve found this pattern preferable to copying third party classes directly into my projects as it allows me to easily keep version history and make updates to static library projects in my workspace and avoids coupling my project too closely to the private structure and contents of the static library.<br />
Please let me know if you can see any areas where this pattern could be improved or if you&#8217;ve found your own alternative means of sharing code.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/feed/</wfw:commentRss>
		<slash:comments>56</slash:comments>
		</item>
		<item>
		<title>Abusing UIViewControllers</title>
		<link>http://blog.carbonfive.com/2011/03/09/abusing-uiviewcontrollers/</link>
		<comments>http://blog.carbonfive.com/2011/03/09/abusing-uiviewcontrollers/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 12:00:16 +0000</pubDate>
		<dc:creator>Jonah Williams</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[Software Design]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=1699</guid>
		<description><![CDATA[UIViewControllers are a fundamental building block of most iOS applications. Unfortunately many developers seem to use them in unintended and unsupported ways which leaves their apps vulnerable to bugs, rejections, unpredictable behavior under new iOS releases, and with controllers which &#8230; <a href="http://blog.carbonfive.com/2011/03/09/abusing-uiviewcontrollers/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html">UIViewController</a>s are a fundamental building block of most iOS applications. Unfortunately many developers seem to use them in unintended and unsupported ways which leaves their apps vulnerable to bugs, rejections, unpredictable behavior under new iOS releases, and with controllers which are difficult to update or reuse. The core misconceptions behind this abuse of UIViewController are understandable. Apple presents UIViewControllers as a key element of an app&#8217;s navigation and interface stating &#8220;custom view controllers are the primary coordinating objects for your application’s content&#8221;. The basic application templates are defined in terms of their UIViewController behavior; &#8220;navigation-based&#8221;, &#8220;tab bar&#8221;, &#8220;split-view based&#8221;. From our first exposure to the platform developers are presented with UIViewControllers as classes for managing views and the transitions between them. Sadly those examples present a pattern which we, as iOS developers outside Apple, cannot follow or build on.</p>
<p>Any app which contains code like<br />
<code>[viewController.view addSubview:someOtherViewController.view];</code><br />
or<br />
<code>viewController.view.bounds = CGRectMake(50, 50, 100, 200);</code><br />
or which loads a nib doing the equivalent is abusing UIViewControllers. Given time this will emerge as bugs or at least pain for developers continuing to work on the app.</p>
<p><strong>What? How is that wrong?</strong><br />
<span id="more-1699"></span><br />
The core problem, and surprise for too many developers, is stated in the &#8220;View Controller Programing Guide for iOS&#8221; in &#8220;<a href="http://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/AboutViewControllers/AboutViewControllers.html#//apple_ref/doc/uid/TP40007457-CH112-SW12">About Custom View Controllers</a>&#8220;:</p>
<blockquote><p>Each custom view controller object you create is responsible for managing all of the views in a single view hierarchy. In iPhone applications, the views in a view hierarchy traditionally cover the entire screen, but in iPad applications they may cover only a portion of the screen. The one-to-one correspondence between a view controller and the views in its view hierarchy is the key design consideration. You should not use multiple custom view controllers to manage different portions of the same view hierarchy. Similarly, you should not use a single custom view controller object to manage multiple screens worth of content.
</p></blockquote>
<p>Essentially the <em><a href="http://developer.apple.com/library/ios/documentation/uikit/reference/UIWindow_Class/UIWindowClassReference/UIWindowClassReference.html#//apple_ref/doc/uid/TP40006817-CH3-SW33">rootViewController</a></em> of the current UIWindow should be the only UIViewController with a visible view.</p>
<p>With multiple UIViewController&#8217;s views visible at once some of those controllers may not receive important messages like <em>-viewWillAppear:</em> or <em>-didReceiveMemoryWarning</em>. Additionally some of their properties like <em>parentViewController</em> and <em>interfaceOrientation</em> may not be set or updated as expected.</p>
<p>&#8220;<a href="http://developer.apple.com/library/ios/#qa/qa1688/_index.html">Why won&#8217;t my UIViewController rotate with the device?</a>&#8221; states this even more explicitly.</p>
<blockquote><p> If you add an additional view controller&#8217;s UIView property to UIWindow (at the same level as your primary view controller) via the following:</p>
<p>[myWindow addSubview:anotherController.view];</p>
<p>this additional view controller will not receive rotation events and will never rotate. Only the first view controller added to UIWindow will rotate. </p></blockquote>
<p>Now Apple is able to provide &#8220;container view controllers&#8221; like UINavigationController and UITabBarController which manage the presentation of other UIViewController&#8217;s views. Unfortunately to do so requires the use of private API calls which are not available for any app seeking approval for distribution in the App Store (discussed in more detail here: <a href="https://devforums.apple.com/message/310806#310806">https://devforums.apple.com/message/310806#310806</a>). We can come close but without a supported path for implementing custom container view controllers nesting UIViewControllers&#8217; views will not give us all the behavior we expect from a UIViewController.</p>
<p><strong>Isn&#8217;t close good enough?</strong></p>
<p>Not really. We can implement a custom container view controller which sends messages like <em>-viewWillAppear</em> to its child view controllers but that only solves part of the problem. </p>
<ul>
<li>Without being able to rely on <em>interfaceOrientation</em> those child view controllers may never support rotation correctly.<br />
Since view controllers&#8217; views are expected to fill the window views &#8220;behind&#8221; modal view controllers may not be drawn or may be unloaded while visible.</li>
<li>Without properties like <em>parentViewController</em> or <em>navigationController</em> being set all of our child view controllers need to be aware of how they are being presented and the fact that they cannot rely on all the behavior they should be able to expect from inheriting from UIViewController.</li>
<li>Child view controllers may not be properly inserted into the responder chain so they may never see events passed up the chain from their views.</li>
</ul>
<p>With no public setters available for these properties or documentation of these behaviors there&#8217;s currently no way to resolve this situation (see this thread for further discussion: <a href="https://devforums.apple.com/message/365171#365171">https://devforums.apple.com/message/365171#365171</a>). Since there is currently no supported means of creating container view controllers those behaviors which do work now are not guaranteed to continue to function in future iOS updates and may vary between existing iOS versions.<br />
By nesting UIViewControllers we create a UIViewController instance which cannot rely on the entire contract offered by UIViewController. A non-obvious and context specific problem for any developer working on the app in the future.</p>
<p><strong>So what&#8217;s the alternative?</strong></p>
<p>The &#8220;<a href="http://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/AboutViewControllers/AboutViewControllers.html#//apple_ref/doc/uid/TP40007457-CH112-SW12">View Controller Programming Guide for iOS</a>&#8221; at least suggests an alternative:</p>
<blockquote><p>Note: If you want to divide a view hierarchy into multiple subareas and manage each one separately, use generic controller objects (custom objects descending from NSObject) instead of view controller objects to manage each subarea. Then use a single view controller object to manage the generic controller objects.
</p></blockquote>
<p>A controller does not necessarily have to be a subclass of UIViewController. We can create controller objects responsible for managing specific behaviors or portions of our view and have these controllers inherit from NSObject instead of from UIViewController. This allows you to break up your app&#8217;s controller logic into manageable classes with clear responsibilities while still following the limitations of UIViewController. This works well when you want to have different controllers manage different sections of a single view hierarchy. </p>
<p><code><br />
@interface SampleController : NSObject  {<br />
}<br />
@end<br />
</code></p>
<p>This is however an inadequate replacement for custom container view controllers which should be able to manage transitions between arbitrary UIViewControllers. Instead we have to either reinvent much of UIViewController&#8217;s behavior (<em>-viewWillAppear:</em> and <em>-viewDidDisappear:</em> style lifecycle methods, unloading and reloading of views on demand, transformation of views in response to device rotations) or abuse UIViewController and risk producing unstable apps.</p>
<p><code><br />
@protocol ViewController<br />
    - (void)viewDidAppear:(BOOL)animated;<br />
    - (void)viewDidDisappear:(BOOL)animated;<br />
    - (void)viewWillAppear:(BOOL)animated;<br />
    - (void)viewWillDisappear:(BOOL)animated;<br />
    -(UIView *)view;<br />
@end</p>
<p>@interface SampleController : NSObject  {<br />
}<br />
@end</p>
<p>@interface SampleContainerViewController : UIViewController {<br />
}<br />
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated;<br />
@property(nonatomic, copy) NSArray *viewControllers;<br />
@end<br />
</code></p>
<p>For now I have found that the best solution is to stay within the supported constraints of UIViewController and build custom non-UIViewController controllers as necessary. Have you found a better alternative, chosen to use UIViewControllers anyway, or avoided this problem entirely?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2011/03/09/abusing-uiviewcontrollers/feed/</wfw:commentRss>
		<slash:comments>55</slash:comments>
		</item>
		<item>
		<title>iPhone Distributed Computing Fallacy #7: transport cost is zero</title>
		<link>http://blog.carbonfive.com/2010/12/03/iphone-distributed-computing-fallacy-7-transport-cost-is-zero/</link>
		<comments>http://blog.carbonfive.com/2010/12/03/iphone-distributed-computing-fallacy-7-transport-cost-is-zero/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 19:00:18 +0000</pubDate>
		<dc:creator>Jonah Williams</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[Software Design]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=1702</guid>
		<description><![CDATA[Reviewing the 8 classic &#8220;fallacies of distributed computing&#8221; and how we can avoid them when writing iOS applications. The fallacies of distributed computing The network is reliable. Latency is zero. Bandwidth is infinite. The network is secure. Topology doesn&#8217;t change. &#8230; <a href="http://blog.carbonfive.com/2010/12/03/iphone-distributed-computing-fallacy-7-transport-cost-is-zero/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Reviewing the 8 classic &#8220;<a href="http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing">fallacies of distributed computing</a>&#8221; and how we can avoid them when writing iOS applications.</p>
<p><em>The fallacies of distributed computing</em></p>
<ol>
<li><a href="http://blog.carbonfive.com/2010/11/iphone/fallacy-1-the-network-is-reliabl">The network is reliable.</a></li>
<li><a href="http://blog.carbonfive.com/2010/11/iphone/fallacy-2-latency-is-zero">Latency is zero.</a></li>
<li><a href="http://blog.carbonfive.com/2010/11/iphone/iphone-distributed-computing-fallacy-3-bandwidth-is-infinite">Bandwidth is infinite.</a></li>
<li><a href="http://blog.carbonfive.com/2010/11/iphone/iphone-distributed-computing-fallacy-4-the-network-is-secure">The network is secure.</a></li>
<li><a href="http://blog.carbonfive.com/2010/12/iphone/iphone-distributed-computing-fallacy-5-topology-doesnt-change">Topology doesn&#8217;t change.</a></li>
<li><a href="http://blog.carbonfive.com/2010/12/iphone/iphone-distributed-computing-fallacy-6-there-is-one-administrator">There is one administrator.</a></li>
<li><strong>Transport cost is zero.</strong></li>
<li><a href="http://blog.carbonfive.com/2010/12/06/iphone-distributed-computing-fallacy-8-the-network-is-homogeneous/">The network is homogeneous.</a></li>
</ol>
<p><span id="more-1702"></span><br />
Fallacy #7: &#8220;transport cost is zero&#8221;.</p>
<p>Arnon Rotem-Gal-Oz&#8217;s <a href="http://www.rgoarchitects.com/Files/fallacies.pdf">explanation</a> of this fallacy points out two possible interpretations, both of which can be problematic mistakes.</p>
<p>First you can consider the cost of moving data between your application and the network interface. The performance impact of serializing objects or parsing data add a cost above and beyond the limitations of bandwidth and latency. Apple&#8217;s <a href="http://developer.apple.com/videos/wwdc/2010/">2010 WWDC session 117</a> &#8220;building a server-driven user experience&#8221; for their comparison of the size and load time of data in xml, json, and plists (slide #40 &amp; 41 at ~27:30). While the size of each format was similar the time required to parse the result varied tremendously; 812ms for xml, 416ms for json, 140ms for an ascii plist and only 19ms for a binary plist.</p>
<p>Secondly you can consider the cost of maintaining network services and infrastructure. How much load does each user place on your servers and what do they cost to run? How many concurrent requests can your servers actually handle and what does it cost to scale those systems? What does using your app cost your users who live with monthly data limits or pay on a per-kilobyte basis?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/12/03/iphone-distributed-computing-fallacy-7-transport-cost-is-zero/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone Distributed Computing Fallacy #5: topology doesn&#8217;t change</title>
		<link>http://blog.carbonfive.com/2010/12/02/iphone-distributed-computing-fallacy-5-topology-doesnt-change/</link>
		<comments>http://blog.carbonfive.com/2010/12/02/iphone-distributed-computing-fallacy-5-topology-doesnt-change/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 22:00:09 +0000</pubDate>
		<dc:creator>Jonah Williams</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[Software Design]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=1691</guid>
		<description><![CDATA[Reviewing the 8 classic &#8220;fallacies of distributed computing&#8221; and how we can avoid them when writing iOS applications. The fallacies of distributed computing The network is reliable. Latency is zero. Bandwidth is infinite. The network is secure. Topology doesn&#8217;t change. &#8230; <a href="http://blog.carbonfive.com/2010/12/02/iphone-distributed-computing-fallacy-5-topology-doesnt-change/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Reviewing the 8 classic &#8220;<a href="http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing">fallacies of distributed computing</a>&#8221; and how we can avoid them when writing iOS applications.</p>
<p><em>The fallacies of distributed computing</em></p>
<ol>
<li><a href="http://blog.carbonfive.com/2010/11/iphone/fallacy-1-the-network-is-reliabl">The network is reliable.</a></li>
<li><a href="http://blog.carbonfive.com/2010/11/iphone/fallacy-2-latency-is-zero">Latency is zero.</a></li>
<li><a href="http://blog.carbonfive.com/2010/11/iphone/iphone-distributed-computing-fallacy-3-bandwidth-is-infinite">Bandwidth is infinite.</a></li>
<li><a href="http://blog.carbonfive.com/2010/11/iphone/iphone-distributed-computing-fallacy-4-the-network-is-secure">The network is secure.</a></li>
<li><strong>Topology doesn&#8217;t change.</strong></li>
<li><a href="http://blog.carbonfive.com/2010/12/iphone/iphone-distributed-computing-fallacy-6-there-is-one-administrator">There is one administrator.</a></li>
<li><a href="http://blog.carbonfive.com/2010/12/03/iphone-distributed-computing-fallacy-7-transport-cost-is-zero/">Transport cost is zero.</a></li>
<li><a href="http://blog.carbonfive.com/2010/12/06/iphone-distributed-computing-fallacy-8-the-network-is-homogeneous/">The network is homogeneous.</a></li>
</ol>
<p><span id="more-1691"></span><br />
Fallacy #5: &#8220;topology doesn&#8217;t change&#8221;.</p>
<p>WWAN connections use significantly more power than WiFi connections. This becomes important when working with long lived connections or streaming media. A connection established over the WWAN will keep that interface active even if a WiFi network becomes available. To avoid running both interfaces it is up to the app to close and re-establish any active connections on the newly available network interface. Use Apple&#8217;s Reachability example to monitor changes in available interfaces and react as necessary. Also take a look at Paul Danbold&#8217;s &#8220;<a href="http://developer.apple.com/videos/iphone/#video-advanced-networking">Advanced networking</a>&#8221; talk from the 2009 Tech Talk World Tour.</p>
<p>Those changes to the network are also likely to result in changes to the device&#8217;s available bandwidth and latency so apps which make decisions based on those characteristics may need to monitor their connections and adapt to changing conditions. Since apps which stream significant amounts of audio or video are required to use <a href="http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008332-CH1-DontLinkElementID_30">http live streaming</a> they can automatically switch between available streams designed for higher or lower bandwidth connections as network conditions change.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/12/02/iphone-distributed-computing-fallacy-5-topology-doesnt-change/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone Distributed Computing Fallacy #4: the network is secure</title>
		<link>http://blog.carbonfive.com/2010/11/29/iphone-distributed-computing-fallacy-4-the-network-is-secure/</link>
		<comments>http://blog.carbonfive.com/2010/11/29/iphone-distributed-computing-fallacy-4-the-network-is-secure/#comments</comments>
		<pubDate>Tue, 30 Nov 2010 06:34:24 +0000</pubDate>
		<dc:creator>Jonah Williams</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[Software Design]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=1679</guid>
		<description><![CDATA[Reviewing the 8 classic &#8220;fallacies of distributed computing&#8221; and how we can avoid them when writing iOS applications. The fallacies of distributed computing The network is reliable. Latency is zero. Bandwidth is infinite. The network is secure. Topology doesn&#8217;t change. &#8230; <a href="http://blog.carbonfive.com/2010/11/29/iphone-distributed-computing-fallacy-4-the-network-is-secure/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Reviewing the 8 classic &#8220;<a href="http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing">fallacies of distributed computing</a>&#8221; and how we can avoid them when writing iOS applications.</p>
<p><em>The fallacies of distributed computing</em></p>
<ol>
<li><a href="http://blog.carbonfive.com/2010/11/iphone/fallacy-1-the-network-is-reliabl">The network is reliable.</a></li>
<li><a href="http://blog.carbonfive.com/2010/11/iphone/fallacy-2-latency-is-zero">Latency is zero.</a></li>
<li><a href="http://blog.carbonfive.com/2010/11/iphone/iphone-distributed-computing-fallacy-3-bandwidth-is-infinite">Bandwidth is infinite.</a></li>
<li><strong>The network is secure.</strong></li>
<li><a href="http://blog.carbonfive.com/2010/12/iphone/iphone-distributed-computing-fallacy-5-topology-doesnt-change">Topology doesn&#8217;t change.</a></li>
<li><a href="http://blog.carbonfive.com/2010/12/iphone/iphone-distributed-computing-fallacy-6-there-is-one-administrator">There is one administrator.</a></li>
<li><a href="http://blog.carbonfive.com/2010/12/03/iphone-distributed-computing-fallacy-7-transport-cost-is-zero/">Transport cost is zero.</a></li>
<li><a href="http://blog.carbonfive.com/2010/12/06/iphone-distributed-computing-fallacy-8-the-network-is-homogeneous/">The network is homogeneous.</a></li>
</ol>
<p><span id="more-1679"></span><br />
Fallacy #4: &#8220;the network is secure&#8221;.</p>
<p>Any network service needs to consider security as part of its design and services built for use by iOS applications are no exception. All of the basic attacks a web service needs to consider still apply; session hijacking, stolen credentials, code injection, and so on. Securing a web service is a much larger topic but let&#8217;s consider a couple of areas specific to iOS client applications.</p>
<p>User&#8217;s devices are only as trustworthy as the users themselves. Anyone with a copy of your app can inspect both the contents of your application&#8217;s bundle and the traffic it sends. Don&#8217;t rely on your app storing a shared secret (credentials to access your web service, certificates, encryption keys, and so on) without revealing it to your users.</p>
<p>UDIDs are unfortunately a poor mechanism for user authentication. They are convenient as a unique identifier available without needing to walk users through any sort of account creation and I&#8217;ve worked on apps which use them as a temporary form of identification but they don&#8217;t work well as permanent identifiers. UDIDs are effectively user provided data and can be changed; either deliberately which might allow one user to masquerade as another or unintentionally when a user upgrades their device or installs an app on a second device.  A UDID identifies a device, not a user.</p>
<p>Mobile devices are even more likely than general web traffic to be used on public access points and networks which can easily include malicious users. Any data your app sends in the clear can be read by other members of the network. If you or your users consider that data sensitive it really needs to be sent over an encrypted connection. Apple provides the <a href="http://developer.apple.com/library/ios/#samplecode/AdvancedURLConnections/Introduction/Intro.html">Advanced URLConnection</a> sample application which demonstrates establishing connections using http basic auth, and certificates (including self-signed certificates if you want to issue your own for your web services).<br />
As a simplistic example a NSURLConnection can support https requests with the addition of just two additional delegate methods.</p>
<pre class="brush: objc; light: true; title: ; wrap-lines: false; notranslate">
- (void) httpsConnection {
    self.connection = [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@&amp;quot;https://encrypted.google.com/&amp;quot;]] delegate:self];
    [self.connection start];
}

-(BOOL) connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace authenticationMethod] == NSURLProtectionSpaceHTTPS;
}

-(void) connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if ([challenge previousFailureCount] == 0) {
        if ([challenge proposedCredential] == nil) {
            NSURLProtectionSpace *protectionSpace = [challenge protectionSpace];
            SecTrustRef trust = [protectionSpace serverTrust];
            SecTrustResultType trustResult;
            SecTrustEvaluate(trust, &amp;amp;trustResult);
            if (trustResult == kSecTrustResultProceed) {
                NSURLCredential *credential = [NSURLCredential credentialForTrust:trust];
                [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
            }
            else {
                [[challenge sender] cancelAuthenticationChallenge:challenge];
            }
        }
        else {
            [[challenge sender] cancelAuthenticationChallenge:challenge];
        }
    }
    else {
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/11/29/iphone-distributed-computing-fallacy-4-the-network-is-secure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

