<?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>Corporation Unknown &#187; iPhone</title>
	<atom:link href="http://corporationunknown.com/blog/category/iphone/feed/" rel="self" type="application/rss+xml" />
	<link>http://corporationunknown.com/blog</link>
	<description></description>
	<lastBuildDate>Thu, 08 Jul 2010 18:51:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>My Accessorizer Configuration</title>
		<link>http://corporationunknown.com/blog/2010/06/27/my-accessorizer-configuration/</link>
		<comments>http://corporationunknown.com/blog/2010/06/27/my-accessorizer-configuration/#comments</comments>
		<pubDate>Sun, 27 Jun 2010 19:52:28 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=216</guid>
		<description><![CDATA[Due to &#8220;overwhelming demand,&#8221; I am sharing my configuration set for Accessorizer here. I think there needs to be some explanation to many of the decisions, though, so here you go. This is not intended to be an interminable discussion of coding style and practices, though&#8211;if you disagree, go ahead and make your own configuration [...]]]></description>
			<content:encoded><![CDATA[<p>Due to &#8220;overwhelming demand,&#8221; I am sharing my configuration set for Accessorizer here. I think there needs to be some explanation to many of the decisions, though, so here you go. This is not intended to be an interminable discussion of coding style and practices, though&#8211;if you disagree, go ahead and make your own configuration based on mine. This is also not intended as comprehensive documentation for Accessorizer&#8211;read its included documentation, explore tooltips, and experiment freely.</p>
<p><span id="more-216"></span><br />
<blockquote>
<p>Download the <a title="CorporationUnknown.azcf.zip" href="http://corporationunknown.com/blog/wp-content/uploads/2010/06/CorporationUnknown.azcf_.zip">Corporation Unknown configuration</a> for Accessorizer.</p>
</blockquote>
<p>At a previous employer, we ran into issues where newcomers were confused by Objective-C&#8217;s memory management, especially the differences between using properties (and dot notation) and directly accessing the ivar. As you might expect, this led to many memory-related problems. I&#8217;ve long been a proponent of only using accessors to access a member unless you have a darn good reason. (And Cocoa&#8217;s ? automatic key-value observing makes it even more difficult to have a good reason not to.) In order to visibly identify accessor-vs-direct access, we instituted a naming convention to make <a href="http://www.joelonsoftware.com/articles/Wrong.html">direct access look wrong</a>: ivars are named with an underscore prefix (&#8220;_ivar&#8221;) and properties are not. To make this even more obvious that ivars are implementation details, we declared them @private.</p>
<p>You may disagree with this methodology; that&#8217;s fine. But without this context, you might have a hard time understanding my configuration decisions&#8211;and why Accessorizer especially rocks in this setup.</p>
<p>When I first started using Accessorizer, I thought of it as a code generator, and it&#8217;s hard not to chafe at your disagreements with how code generators generate code. I&#8217;ve found that thinking of it as a code <em>template</em> generator makes it easier: Generate the majority of stuff you use, omit the stuff you don&#8217;t normally use, and be comfortable with the knowledge that you will regularly have to tweak its output&#8211;it&#8217;s still better than writing it from scratch every time.</p>
<h1>Accessor Style</h1>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://corporationunknown.com/blog/wp-content/uploads/2010/06/Accessorizer-Properties.png" border="0" alt="Accessorizer Properties" width="316" height="116" /></p>
<ul>
<li>&#8220;ObjC 2.0 Properties&#8221; is always turned on. Period.</li>
<li>I always use the Defaults Table (more about that later).</li>
<li>&#8220;Detect IBOutlets&#8221; automatically inserts the &#8220;IBOutlet&#8221; declaration into recognized subclasses. Sometimes it doesn&#8217;t identify a class I want to be an IBOutlet, but I find this to be right much more often than it is wrong.</li>
<li>&#8220;Append self.view=nil&#8221; is a somewhat strangely worded option. Checking it will generate code to nil those properties identified as IBOutlets. Combined with the &#8220;-(void)viewDidUnload&#8221; checkbox to its right, it will generate a full viewDidUnload method to release your IBOutlets.</li>
<li>&#8220;Assign delegates&#8221; automatically overrides your assign/retain/copy property generation setting to be &#8220;assign&#8221; for any &#8220;id&#8221; property (or others identified as a delegate form; again, I find more often right than wrong).</li>
<li>I uncheck &#8220;Omit assign for scalars&#8221;. True, the &#8220;assign&#8221; is not necessary, but I find it easier to scan for &#8220;assign&#8221; when I&#8217;m code reviewing than have to think about each type and whether it is handled appropriately. (According to Apple&#8217;s documentation, &#8220;assign&#8221; is also required for garbage collection but I haven&#8217;t written any GC code yet.)</li>
<li>&#8220;Assign IBOutlets&#8221; is unchecked. I guess I&#8217;m still in the &#8220;retain outlets&#8221; camp, until I bother to change my mind.</li>
<li>&#8220;BOOL getter=isValue&#8221; automatically identifies a &#8220;BOOL running&#8221; property and defines the getter as &#8220;isRunning&#8221;, just as Apple recommends.</li>
</ul>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://corporationunknown.com/blog/wp-content/uploads/2010/06/AccessorizerProps2.png" border="0" alt="Accessorizer Properties 2" width="498" height="111" /></p>
<ul>
<li>Since I&#8217;ve primarily been coding for iOS lately, I declare my properties &#8220;nonatomic&#8221;. If/when you&#8217;re working on the desktop, you probably want &#8220;omit this&#8221;&#8211;change it or create a &#8220;desktop&#8221; configuration.</li>
<li>I omit readonly/readwrite. Most of the readonly properties I create are not backed by ivars, so I find I don&#8217;t need to override this behavior often.</li>
<li>I haven&#8217;t been much concerned about __weak or __strong, so I omit it. You may decide otherwise.</li>
<li>&#8220;@synthesize&#8221; will create appropriate @synthesize statements when generation the Implementation. (Be sure to check &#8220;generate getter/setter&#8221;, even though it applies to @dynamic&#8211;I&#8217;ll explain later when talking about Defaults Table.)</li>
</ul>
<h2>Getter/Setter settings</h2>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://corporationunknown.com/blog/wp-content/uploads/2010/06/AccessorizerGetterSetter.png" border="0" alt="Accessorizer Getters and Setters" width="417" height="121" /></p>
<p>Not much to say about these settings other than &#8220;Use Defaults Table&#8221;. They don&#8217;t come into play very often, since I mainly use @synthesized properties but these settings work for me when I don&#8217;t. To see the effects on generated code, temporarily switch your properties generation to @dynamic with &#8220;generate getter/setter&#8221; checked and Implementation being generated&#8211;changes will be reflected as you make them.</p>
<h2>Dealloc</h2>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://corporationunknown.com/blog/wp-content/uploads/2010/06/AccessorizerDealloc.png" border="0" alt="Accessorizer Dealloc" width="378" height="123" /></p>
<ul>
<li>I default to &#8220;self.property = nil&#8221; behavior; I know others disagree. If you&#8217;re one of them, simply change the option to &#8220;release&#8221; in your configuration. If you do agree, or simply want to give this way a try, make a point of removing any related KVO or NSNotification observers before these generated lines or you will receive notifications of the nil settings and you most likely don&#8217;t want that.</li>
<li>&#8220;dealloc full block&#8221; is the primary reason I am not just making my configuration available without comment. If you were to just take my configuration and copy the generated code, it would break your build because I leave this deselected so it&#8217;s not in a code block. As I develop my classes, I add ivars and use Accessorizer to generate the related code. Most of the code is pretty easy to wholesale copy-n-paste, but I tend to have more logic in dealloc than Accessorizer can know about (KVO and NSNotification removal, setting delegates to nil, etc.) and I find it easier to copy this generated dealloc code into an existing method than to use this as a dealloc method and move existing behaviors into it. If you want a full dealloc method, just check the box.</li>
</ul>
<h2>Init and Undo</h2>
<p>I&#8217;m not sure why, but I still tend to write my own init methods. Someday I&#8217;ll explore using Accessorizer for this and Undo registration more fully; until then, you&#8217;re on your own.</p>
<h1>Defaults Table</h1>
<p>The defaults table is used to override the &#8220;one size fits all&#8221; property generation based on the ivar&#8217;s type. I have configured every superclass of &#8220;NSMutable&lt;Something&gt;&#8221; to default to &#8220;copy&#8221; instead of the default &#8220;retain&#8221; in order to avoid holding reference to a mutable object when I&#8217;m expecting immutable. (This is explained in <a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17-SW27">Apple&#8217;s documentation</a>.) I don&#8217;t even use some of these classes, but when I do I don&#8217;t want to be surprised. I&#8217;m always free to edit the declaration on a case-by-case basis, but this is the behavior I want ninety-some percent of the time.</p>
<p>Another fun feature of the Defaults Table is the &#8220;generation&#8221; setting. If you have a class type whose behavior you tend to override often, define its generation as &#8220;dynamic&#8221;. Every time you use that class type, Accessorizer will generate an @dynamic declaration&#8211;and the accessor methods for you to use as a starting template. (This is why I check the &#8220;generate getter/setter&#8221; in the Accessor tab even though it normally won&#8217;t do anything.)</p>
<h1>Custom Table</h1>
<p>I don&#8217;t really use this tab, and I don&#8217;t believe any of it gets saved into a configuration set since it&#8217;s primarily for point-and-click tweaking of behavior on an ivar-by-ivar basis.</p>
<h1>Coding Style</h1>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://corporationunknown.com/blog/wp-content/uploads/2010/06/AccessorizerCodingStyle.png" border="0" alt="Accessorizer ivar Prefix and Suffix" width="195" height="217" /></p>
<p>As I mentioned, I prefix my ivars with an underscore, so here is where I define that. By defining my ivar Prefix as &#8220;_&#8221; and Suffix as &#8220;none&#8221;, Accessorizer automatically recognizes that underscore and strips it when declaring the property. It also properly declares the backing ivar in the @synthesize directive.</p>
<ul>
<li>The Argument Prefix is used when generating methods like -initWith{&#8230;}. I vacillate between &#8220;a&#8221; and &#8220;none&#8221;.</li>
<li>Formatting Properties: new to 2.0 is the ability to tweak whitespace in declarations more than you could in previous versions. I&#8217;m happy because now I can use my preferred &#8220;NSString* title&#8221; form; I know many others still hew to the &#8220;asterisk must bind the the variable, not type&#8221; but you&#8217;re free to change it for yourself.</li>
<li>Formatting Methods: Configure the display to generate some accessor methods and experiment with these settings to see which layout you prefer. The &#8220;Tight&#8221; spacing option is actually more compressed than I like, but I find the &#8220;Spaced&#8221; option way too spread out (and I&#8217;m someone who loves whitespace). Therefore, I default to &#8220;Tight&#8221; because it&#8217;s easier to insert the few spaces I prefer than delete all the ones I don&#8217;t.</li>
<li>Formatting Pragma Marks: I love me some pragma marks, but try not to go overboard with them. Feel free to experiment.</li>
<li>Init Style: Apparently, &#8220;self = [super init]&#8221; is the current Apple-approved format. I&#8217;m ambivalent.</li>
</ul>
<h1>Collection Accessors, Keyed Archiving, KVO, Locking, Singleton, General and Sort</h1>
<p>Most of these tabs are more hands-on generation of code. You need to enter a class name, and it will generate code right there&#8211;I don&#8217;t use these as frequently as accessor generation, and you can tweak the layout more directly when you do need it. At some point, I may have changed my settings from the defaults you would encounter in a new install, but I don&#8217;t really have strong suggestions for you here.</p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2010/06/27/my-accessorizer-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Accessorizer 2.0 Configuration Sets</title>
		<link>http://corporationunknown.com/blog/2010/05/31/accessorizer-2-0-configuration-sets/</link>
		<comments>http://corporationunknown.com/blog/2010/05/31/accessorizer-2-0-configuration-sets/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 02:26:00 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=212</guid>
		<description><![CDATA[The new version of Accessorizer is out! I&#8217;m still amazed at how many Cocoa (including iPhoneOS) developers I encounter who don&#8217;t know of this awesome utility. Here are just a few things this app does:

As its name suggests, it will generate the getters and setters for ivars you point it at. It will do this [...]]]></description>
			<content:encoded><![CDATA[<p>The new version of <a href="http://www.kevincallahan.org/software/accessorizer.html">Accessorizer</a> is out! I&#8217;m still amazed at how many Cocoa (including iPhoneOS) developers I encounter who don&#8217;t know of this awesome utility. Here are just a few things this app does:</p>
<ol>
<li>As its name suggests, it will generate the getters and setters for ivars you point it at. It will do this using Objective-C 2.0 @property syntax if you specify it. (I use the 2.0 syntax and revert when I want to customize a getter or setter so i can start with a &#8220;standard&#8221; usage style.)</li>
<li>Automatically recognize UIKit and AppKit classes and mark the properties as IBOutlets.</li>
<li>Recognize non-object ivars and set their properties as &#8220;assign&#8221; instead of &#8220;retain&#8221;.</li>
<li>You can configure defaults for ivar classes (all my NSString and NSData properties default to &#8220;copy&#8221; instead of &#8220;retain&#8221;).</li>
<li>Generate all the methods for collections to be nicely Key-Value Observing compliant.</li>
<li>Generate Keyed Archiving and Unarchiving methods for your ivars.</li>
<li>Generate template code for a Singleton class.</li>
</ol>
<p>That&#8217;s really just scratching the surface, but it&#8217;s the main functionality I use. As a Cocoa developer, you truly do owe it to yourself to check it out.</p>
<p>What makes me (rather selfishly) consider 2.0 an awesome update, though, is a feature I requested: Configuration Sets. The request grew partly out of encountering co-workers at contracting gigs who didn&#8217;t use Accessorizer. There are so many items to customize in the application, a first use could be daunting. If I can say, &#8220;Here&#8217;s my configuration to get you started,&#8221; and pass along my exported Configuration, they&#8217;re more likely to use it. (It also helps that they can now feel confident that they can revert after experimenting with settings.)</p>
<p>If I&#8217;m working on multiple projects with multiple clients, I can save their specific formatting requirements and switch between Configuration Sets when I change between projects.</p>
<p>If your company has defined formatting standards for the aspects Accessorizer can generate, standardizing with a Configuration Set allows you to quickly bring a new team member up to speed and into compliance.</p>
<p>There are more aspects to Configuration Sets I&#8217;d like to see, but they fall on the &#8220;magical&#8221; end of the spectrum; Kevin has done a great job of implementing the (more than) 80% part of it.</p>
<p>Seriously: Why aren&#8217;t you using Accessorizer?</p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2010/05/31/accessorizer-2-0-configuration-sets/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Clean Up Your Actions</title>
		<link>http://corporationunknown.com/blog/2010/01/21/clean-up-your-actions/</link>
		<comments>http://corporationunknown.com/blog/2010/01/21/clean-up-your-actions/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 16:33:54 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=162</guid>
		<description><![CDATA[We all know how to define an IBAction:

- (IBAction) sliderChanged:(id)sender;

For the iPhone, you can even define it without the sender if the method won&#8217;t use it:

- (IBAction) sliderChanged;

The annoyance comes when implementing the method&#8211;that generic id parameter needs to be cast to the class you usually already know it to be, resulting in either casts [...]]]></description>
			<content:encoded><![CDATA[<p>We all know how to define an IBAction:</p>
<pre class="code">
- (IBAction) sliderChanged:(id)sender;
</pre>
<p>For the iPhone, you can even define it without the <code>sender</code> if the method won&#8217;t use it:</p>
<pre class="code">
- (IBAction) sliderChanged;
</pre>
<p>The annoyance comes when implementing the method&#8211;that generic <code>id</code> parameter needs to be cast to the class you usually already <em>know</em> it to be, resulting in either casts all over:</p>
<pre class="code">
- (IBAction) sliderChanged:(id)sender {
   int progressAsInt = (int)([(UISlider*)sender value] + 0.5f);
   float minValue = [(UISlider*)sender minimumValue];
   float maxValue = [(UISlider*)sender maximumValue];
}
</pre>
<p>or the use of a local variable whose sole purpose is to hold the pre-cast parameter:</p>
<pre class="code">
- (IBAction) sliderChanged:(id)sender {
   UISlider* slider = (UISlider*)sender;
   int progressAsInt = (int)([slider value] + 0.5f);
   float minValue = [slider minimumValue];
   float maxValue = [slider maximumValue];
}
</pre>
<h2>Clean it up</h2>
<p>The key to cleaning up your IBActions lies in Objective-C&#8217;s behavior of treating all objects as <code>id</code> at heart: Declaring a type for an object is really only beneficial to you at compilation time, warning you of possible mistyping. (It also enables autocompletion.) But that&#8217;s not a limitation, it&#8217;s something to leverage!</p>
<p>When you know the single class (or superclass of the family of classes), declare it in the method signature:</p>
<pre class="code">
- (IBAction) sliderChanged:(UISlider*)slider {
   int progressAsInt = (int)([slider value] + 0.5f);
   float minValue = [slider minimumValue];
   float maxValue = [slider maximumValue];
}
</pre>
<p>If you&#8217;re one of those (crazy) people who call the action method in code, you will now be warned when trying to pass an unexpected control (e.g. a <code>UISwitch</code> instead of <code>UISlider</code>).</p>
<p>Added bonus: By declaring the action with a specific parameter type in the header, Interface Builder will use that information to filter available connections. Not only will you have a shorter list of actions to choose from when connecting, you won&#8217;t even be <em>allowed</em> to accidentally connect a <code>UISwitch</code> to an action expecting a <code>UISlider</code>.</p>
<blockquote><p><strong>Note:</strong> If you do clean up actions in this way for existing projects, verify your nibs afterward. Interface Builder will display a warning icon in the lower right corner of the nib window, but the CompileXIB build phase is not configured to generate these warnings by default.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2010/01/21/clean-up-your-actions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Practical XML Parsing</title>
		<link>http://corporationunknown.com/blog/2009/09/17/practical-xml-parsing/</link>
		<comments>http://corporationunknown.com/blog/2009/09/17/practical-xml-parsing/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 16:48:36 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Mac Community]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=147</guid>
		<description><![CDATA[I presented &#8220;Practical XML Parsing&#8221; at the September 10, 2009 meeting of Seattle Xcoders. While there is still a touch of the initially intended distaste for parsing XML with DOM, it evolved into more of an overview and brief introduction of NSXMLDocument and NSXMLParser.
After cleaning out large copyrighted material (part of a Justin Timberlake song [...]]]></description>
			<content:encoded><![CDATA[<p>I presented &#8220;Practical XML Parsing&#8221; at the September 10, 2009 meeting of <a href="http://www.seattlexcoders.org/">Seattle Xcoders</a>. While there is still a touch of the initially intended distaste for parsing XML with DOM, it evolved into more of an overview and brief introduction of NSXMLDocument and NSXMLParser.</p>
<p>After cleaning out large copyrighted material (part of a Justin Timberlake song on the title screen and a Star Wars snippet on the XQuery screen) and removing many of the Keynote build animations I like to use but which translate poorly to static images, I have made the presentation available. I didn&#8217;t record the audio, so the text may seem more terse than it really was.</p>
<ul>
<li><a href="http://corporationunknown.com/presentations/practical_xml_parsing.html">HTML export</a> with most of the animations still intact</li>
<li><a href="http://seattlexcoders.org/shared/Practical%20XML%20Parsing.zip">Zipped archive</a> containing:
<ul>
<li>Keynote 09 file</li>
<li>PDF export</li>
<li>XMLDemo source serving as the examples I showed</li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2009/09/17/practical-xml-parsing/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Happy Birthday</title>
		<link>http://corporationunknown.com/blog/2009/08/21/happy-birthday/</link>
		<comments>http://corporationunknown.com/blog/2009/08/21/happy-birthday/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 21:32:19 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=96</guid>
		<description><![CDATA[They say the best gifts are handmade. For my wife&#8217;s birthday last year, I came up with the idea to write a simple little &#8220;birthday card&#8221; application and slip it on her iPhone to surprise her. I scanned in some graphics from a real birthday card and digitally chopped it up and added some animation [...]]]></description>
			<content:encoded><![CDATA[<p>They say the best gifts are handmade. For my wife&#8217;s birthday last year, I came up with the idea to write a simple little &#8220;birthday card&#8221; application and slip it on her iPhone to surprise her. I scanned in some graphics from a real birthday card and digitally chopped it up and added some animation to give it that true &#8220;Made in Flash&#8221; feel, and stayed up until 1 AM working to get ad hoc provisioning working on her phone. I even had it register a protocol handler so I could send her an email while she was at work saying &#8220;click this link: &lt;happy://birthday&gt; from your iPhone email&#8221; and it would launch the application. It was a hit.</p>
<p>The one thing I had planned but couldn&#8217;t get working was for the appliction to play a song. Core Animation took enough of my brainpower at the time, and the idea of learning AudioUnit in such a short time was quickly dismissed&#8211;I would have to &#8220;ship&#8221; without that feature. But a recent <a href="http://www.mobileorchard.com/easy-audio-playback-with-avaudioplayer/">post by Mobile Orchard&#8217;s Dan Grigsby</a> showing the simplicity of AVAudioPlayer prompted me to pull the code off the shelf and give it an update.</p>
<p>What a dusty shelf <em>that</em> was. The project was configured for SDK 2.1(!) and some of the code was indicative of &#8220;tweaking until it works.&#8221; As I was updating the project for 3.0, moving code to Interface Builder and swapping lots of Core Animation code for UIView animations, it dawned on me that this has surprisingly many little tidbits of code and would be good to share.</p>
<p><span id="more-96"></span>Before even providing the download link, I will warn that this version is somewhat &#8220;build your own.&#8221; My personal version looks like this:</p>
<p><script type="text/javascript">// < ![CDATA[
	QT_WritePoster_XHTML('Click to Play', 'http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyBirthdaySound/HappyBirthdaySound-poster.jpg',
		'http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyBirthdaySound/HappyBirthdaySound.mov',
		'370', '386', '',
		'controller', 'true',
		'autoplay', 'true',
		'bgcolor', 'black',
		'scale', 'aspect');
// ]]&gt;</script></p>
<p><noscript><br />
<object classid="clsid:02bf25d5-8c17-4b23-bc80-d3488abddc6b" width="370" height="386" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="src" value="http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyBirthdaySound/HappyBirthdaySound-poster.jpg" /><param name="href" value="http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyBirthdaySound/HappyBirthdaySound.mov" /><param name="target" value="myself" /><param name="controller" value="false" /><param name="autoplay" value="false" /><param name="scale" value="aspect" /><embed type="video/quicktime" width="370" height="386" src="http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyBirthdaySound/HappyBirthdaySound-poster.jpg" scale="aspect" autoplay="false" controller="false" target="myself" href="http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyBirthdaySound/HappyBirthdaySound.mov"></embed></object><br />
</noscript></p>
<p>But since I don&#8217;t have distribution rights for the song or art, this version will get &#8220;art&#8221; (disabusing you of any notion of hiring me as a Graphic Artist) created by me, and not have a song to play. A fresh build will look like this:</p>
<p><script type="text/javascript">// < ![CDATA[
	QT_WritePoster_XHTML('Click to Play', 'http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyClean/HappyClean-poster.jpg',
		'http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyClean/HappyClean.mov',
		'366', '386', '',
		'controller', 'true',
		'autoplay', 'true',
		'bgcolor', 'black',
		'scale', 'aspect');
// ]]&gt;</script></p>
<p><noscript><br />
<object classid="clsid:02bf25d5-8c17-4b23-bc80-d3488abddc6b" width="366" height="386" codebase="http://www.apple.com/qtactivex/qtplugin.cab"><param name="src" value="http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyClean/HappyClean-poster.jpg" /><param name="href" value="http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyClean/HappyClean.mov" /><param name="target" value="myself" /><param name="controller" value="false" /><param name="autoplay" value="false" /><param name="scale" value="aspect" /><embed type="video/quicktime" width="366" height="386" src="http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyClean/HappyClean-poster.jpg" scale="aspect" autoplay="false" controller="false" target="myself" href="http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyClean/HappyClean.mov"></embed></object><br />
</noscript></p>
<p>When you replace the graphics with your own, and add a song named &#8220;Happy Birthday.mp3&#8243; you will have your own customized version.</p>
<p>Features this little application demonstrates:</p>
<ul>
<li>Animate view fade in and out transitions.</li>
<li>Add repeating animations to views so they &#8220;wobble&#8221;.</li>
<li>Launch in full screen without status bar.</li>
<li>Register a protocol handler so any &#8220;happy://&#8221; url will launch it.</li>
<li>Play a bundled mp3 (taken directly from the Mobile Orchard post).</li>
<li>Autorotate view using autoresizing properties.</li>
</ul>
<p>(Ad Hoc installation before 1 AM is left as an exercise for the reader.)</p>
<blockquote><p><a href="http://corporationunknown.com/public/projects/Happy.zip">Download Happy.zip</a></p></blockquote>
<p>The code is BSD Licensed. Feel free to explore it, enjoy it a bit and maybe even pleasantly surprise your own significant other.</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2009/08/21/happy-birthday/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyBirthdaySound/HappyBirthdaySound.mov" length="299" type="video/quicktime" />
<enclosure url="http://corporationunknown.com/blog/wp-content/uploads/2009/08/HappyClean/HappyClean.mov" length="275" type="video/quicktime" />
		</item>
		<item>
		<title>iPhone Development Course</title>
		<link>http://corporationunknown.com/blog/2009/03/14/iphone-development-course/</link>
		<comments>http://corporationunknown.com/blog/2009/03/14/iphone-development-course/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 21:10:21 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=84</guid>
		<description><![CDATA[Local Xcoders founder Joe Heck has just announced his 2-day iPhone course/workshop here in Seattle.
Joe has a very solid grip on the topic, and a seemingly boundless desire to both share what he&#8217;s learned and learn from others. Writing for the iPhone can be a bit disorienting at first, especially if you&#8217;re not already familiar [...]]]></description>
			<content:encoded><![CDATA[<p>Local <a href="http://www.seattlexcoders.org/">Xcoders</a> founder <a href="http://www.rhonabwy.com/wp/2009/03/13/iphone-development-course-apr-25-26-in-seattle/">Joe Heck has just announced his 2-day iPhone course/workshop here in Seattle.</a></p>
<p>Joe has a very solid grip on the topic, and a seemingly boundless desire to both share what he&#8217;s learned and learn from others. Writing for the iPhone can be a bit disorienting at first, especially if you&#8217;re not already familiar with Cocoa; Joe is an ideal sounding board for questions you may worry might mark you as a &#8220;rookie.&#8221;</p>
<p>We got a preview of the course at last month&#8217;s Xcoders meeting, and I highly recommend it for anyone wanting to get up to speed on iPhone development. (Especially if you can get the discount he mentions in his post.)</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2009/03/14/iphone-development-course/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My iPhone App Submission Journey</title>
		<link>http://corporationunknown.com/blog/2009/03/14/my-iphone-app-submission-journey/</link>
		<comments>http://corporationunknown.com/blog/2009/03/14/my-iphone-app-submission-journey/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 15:15:19 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=46</guid>
		<description><![CDATA[I submitted my first iPhone app to Apple for review on Thursday. The process didn&#8217;t go smoothly; there were issues I probably should have known about, and issues that seemed to have been compounded by using my client&#8217;s keys to release under their developer account. Now that it&#8217;s in Apple&#8217;s hands, I feel I should [...]]]></description>
			<content:encoded><![CDATA[<p>I submitted my first iPhone app to Apple for review on Thursday. The process didn&#8217;t go smoothly; there were issues I probably should have known about, and issues that seemed to have been compounded by using my client&#8217;s keys to release under their developer account. Now that it&#8217;s in Apple&#8217;s hands, I feel I should write down the issues and resolutions I encountered, even at the risk of looking like a doofus at times. To be trite, if it helps just one future developer have a smoother release it will be worth it&#8211;odds are, that future developer will be me.</p>
<p><strong>Warning:</strong> If you are not an iPhone developer and don&#8217;t plan to be, you should consider skipping this post. It&#8217;s minutia you will never use, and I don&#8217;t offer a refund for your time or brain cells spent reading this.<span id="more-46"></span><br />
<h2>Profile Fun</h2>
<p>The session started off with the client stating that he couldn&#8217;t get the code running with his Developer and Ad Hoc profile on his phone (I had been giving him milestone releases signed with my Ad Hoc profile which (mostly) worked just fine). I&#8217;m still not convinced that the combination of both Developer and Ad Hoc is desirable, let alone valid, but that&#8217;s beside the point&#8211;in the absence of being able to convince myself it was invalid such that I could convince <em>him</em> it was, I would do my best to make it happen.</p>
<p>I got it working with the Developer profile pretty easily, but Ad Hoc was elusive. I installed clean copies of the mobileprovision files a few times, with and without restarting Xcode to &#8220;be sure,&#8221; but still no joy.</p>
<div class="tip">
<p><strong>Where are my profiles?</strong></p>
<p>It&#8217;s best to trust the Xcode Organizer to manage the provisions, but there are times when you feel the need to directly manipulate. Installed mobileprovision files are found in <code>~/Library/MobileDevice/Provisioning Profiles/</code> but if you don&#8217;t remember that, Spotlight doesn&#8217;t help because it doesn&#8217;t return results from the <code>~/Library/</code> hierarchy without some contortions. You can use <code>mdfind "kMDItemContentType=com.apple.iphone.mobileprovision"</code> to find all the profiles on your machine. The documentation in the <a href="http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/128-Managing_Devices/devices.html#//apple_ref/doc/uid/TP40007959-CH4-SW2">iPhone Development Guide</a> is currently out of date, claiming the directory to be <code>~/Library/MobileDevice/Provisions</code> (the error reporting page threw errors when I tried to file a bug on it&#8211;I&#8217;ll try again later).
</div>
<p>The real problem? The profile was for App Store Distribution, not Ad Hoc. Both kinds of profile say &#8220;iPhone Distribution&#8221; in Xcode, so no information gained there. I found it suspicious that his profile didn&#8217;t list any devices, but didn&#8217;t feel I could assume that just because he hadn&#8217;t added a device to the provision implied that it was for the App Store. As it turns out, that assumption <i>is</i> correct: App Store profiles can&#8217;t have devices specified, and the Program Portal won&#8217;t let you create an Ad Hoc profile without at least one device specified.</p>
<div class="tip">
<p><strong>Is my mobileprovision file for Ad Hoc or App Store?</strong></p>
<p>Do one of the following:</p>
<ul>
<li>Within the Program Portal, go to Provisioning > Distribution and find the profile in question. Click Edit on the far right of that row, then choose Modify from the menu that appears. You will be shown the page you used to initially set up the profile, including the Distribution Method.</li>
<li>Grep the mobileprovision file for &#8220;ProvisionedDevices&#8221;. The presence of that key indicates an Ad Hoc profile, otherwise it&#8217;s for App Store.</li>
</ul>
</div>
<p>At this point, some of you may be rolling your eyes at my client&#8211;please stop. I don&#8217;t know anyone who has felt that this process and the Dev-vs-AdHoc-vs-AppStore distinction were clear when they first encountered it. Working with profiles isn&#8217;t an everyday thing; once you get it working you tend to just use it the way it is and as a result that knowledge doesn&#8217;t necessarily stay in long-term memory. Creating your own profiles also allows you to name the profile descriptively, whereas trying to determine whether someone else did it &#8220;right&#8221; is not immediately obvious. This was an interesting challenge for me, but I don&#8217;t fault him at all.</p>
<h2>Submitting the App to iTunes Connect</h2>
<p>So, we&#8217;ve determined that we&#8217;re working with an App Store profile not Ad Hoc, and at this point have decided to skip attempting the Ad Hoc and move on to submitting for review. The first task is to find iTunes Connect; the Program Portal User Guide says you &#8220;will find a link to iTunes Connect in the &#8216;Distribution&#8217; section of the Program Portal&#8221;&#8230;but it&#8217;s a bit more hidden than that.</p>
<div class="tip">
<p><strong>Getting to iTunes Connect</strong></p>
<p>Do one of the following:</p>
<ul>
<li>In the Program Portal, go to Distribution > App Store. Click &#8220;Learn More&#8221; in the &#8220;App Store&#8221; section of the text to reveal more steps to follow. Step 2 has a &#8220;Go to iTunes Connect&#8221; link.</li>
<li>Or just go straight to <a href="http://itunesconnect.apple.com/">http://itunesconnect.apple.com/</a> (which is definitely a &#8220;duh!&#8221; moment once you know).</li>
</ul>
</div>
<p>Fill out the overview form. Liberally click the circled question marks for descriptive help.</p>
<div class="tip">
<p><strong>Upload Gotchas I Encountered</strong></p>
<ul>
<li>The application&#8217;s zip archive to upload cannot have a space in the name. From now on, I plan to rename all my application zips to CamelCased alphanumeric only.</li>
<li>The screenshots need to be .jpg or .tif even though the screenshots obtained in Organizer are .png. I realize <a href="http://www.mikeash.com/?page=pyblog/the-iphone-development-story.html">I&#8217;m not the first person to observe this</a>, but I serve as evidence that it bears repeating.</li>
</ul>
</div>
<p>When I uploaded the application zip, I would be told that the application was invalid, so I clicked the &#8220;Check here to upload your binary later&#8221; checkbox to allow me to upload all the (corrected) images and continue setting information about the application. Most of that was self-explanatory, or at least answerable by my client (&#8220;How much do you want to charge?&#8221;). That checkbox is pretty magical&#8211;you can fill out everything about your app <em>but</em> the app itself and leave that to the last step. I plan on making that my modus operandi for every future app.</p>
<h2>Fix the App Signing</h2>
<p>There were still two more layers of the app submission onion I needed to peel away. The first was to figure out why my app archive was &#8220;invalid.&#8221; Once again, I did numerous clean-and-build cycles to check that the Build Output window looked like it was signing correctly and generating the files as expected. I downloaded &#8220;fresh&#8221; copies of the mobileprovision files and reinstalled them in Xcode in case all the twiddling I&#8217;d done earlier had corrupted something.</p>
<p>Then I finally slapped my forehead when I realized that the signing had continued to use &#8220;iPhone Developer&#8221; not &#8220;iPhone Distribution&#8221;. In the mass of build output text, I&#8217;d mentally reduced to &#8220;iPhone D&#8221; and called it a match. I went to the target&#8217;s build settings in Xcode, changed the Code Signing Entity to the &#8220;iPhone Distribution&#8221; entry, cleaned all targets, rebuilt and&#8230;it was still signing with &#8220;Developer&#8221;. No matter how many times I toggled the build setting, it refused to use a different profile.</p>
<p>Searching the web, I mostly found suggestions to delete lines in the pbxproj file where PROVISIONING_PROFILE and CODE_SIGN_IDENTITY were defined. After making a backup of the file, I went for the nuclear option and stripped the lines. I started Xcode back up and reconfigured the now-empty Code Signing Entity setting, cleaned targets, rebuilt and&#8230;it signed with &#8220;Distribution&#8221; finally!</p>
<p>As I said, I consider this a nuclear option. Future releases and projects will probably follow <a href="http://furbo.org/2009/02/26/sharing-iphone-projects/">Craig Hockenberry&#8217;s advice for sharing projects</a> once I get my brain wrapped around it better. Until then, &#8220;<code>grep -v PROVISIONING_PROFILE MyApp.pbxproj | grev -v CODE_SIGN_IDENTITY > MyAppStripped.pbxproj</code>&#8221; will help me out.</p>
<p>Zip the application, camelCase the zip file, upload to iTunes Connect&#8230;and the app is valid! But one more hurdle: I am told that the bundle identifier contains disallowed characters. This is relatively easy to troubleshoot: The project template of &#8220;<code>com.yourcompany.${PRODUCT_NAME:identifier}</code>&#8221; translates spaces in multi-word product names to an underscore (&#8220;My App&#8221; becomes &#8220;My_App&#8221;) which is not allowed. Simple troubleshoot, simple fix: As much as I would like to figure a correct way of using the variable substitution (this app changed names a few times during development), at this point I&#8217;m willing to just hardcode that last piece of the identifier to a camelCased version of the product name.</p>
<p>Cleaned targets, rebuilt, zipped the application, camelCased the zip file, uploaded to iTunes Connect&#8230;</p>
<h2>SUCCESS!</h2>
<p>So there the app sits, with a little yellow &#8220;In Review&#8221; globe in the status field. I plan to do a post discussing what I learned during the development of the app, but will wait until it&#8217;s actually approved by Apple since numerous changes and learning opportunities may still be in store.</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2009/03/14/my-iphone-app-submission-journey/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>iPhone SDK NDA Lifted!</title>
		<link>http://corporationunknown.com/blog/2008/10/01/iphone-sdk-nda-lifted/</link>
		<comments>http://corporationunknown.com/blog/2008/10/01/iphone-sdk-nda-lifted/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 18:11:43 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=30</guid>
		<description><![CDATA[Hooray, Apple has decided to lift the long-in-the-tooth NDA on the iPhone SDK!
I can&#8217;t imagine anyone will be hearing that news from this blog first, but I do want to acknowledge and take advantage of it. My last post felt a bit vague, even to me, about my definition of &#8220;iPhone black&#8221; and that was [...]]]></description>
			<content:encoded><![CDATA[<p>Hooray, Apple has decided to lift the long-in-the-tooth NDA on the iPhone SDK!</p>
<p>I can&#8217;t imagine anyone will be hearing that news from this blog first, but I do want to acknowledge and take advantage of it. <a href="http://corporationunknown.com/blog/2008/09/28/iphone-black-brushed-metal/">My last post</a> felt a bit vague, even to me, about my definition of &#8220;iPhone black&#8221; and that was partly due to dancing around the NDA. While it was really tempting to be provocative, I felt it would be irresponsible for my current contract work to risk getting smacked with an NDA violation (even though I have yet to hear of an instance) and have the client&#8217;s product suffer as a result. I considered screenshots, but felt they were either singling out someone else&#8217;s application, or a simplistic straw man if I just used an Interface Builder mockup.</p>
<p>The definition I had in mind of &#8220;iPhone black UI&#8221; is not simply &#8220;any view whose background is black&#8221;; it is a <code>UINavigationController</code> whose <code>UINavigationBar's</code> <code>barStyle</code> is <code>UIBarStyleBlackOpaque</code> (instead of <code>UIBarStyleDefault</code>) and is controlling a <code>UITableViewController</code> whose controlled <code>UITableView's</code> rows have either a white or black background. If a <code>UIToolbar</code> is present, its <code>barStyle</code> is also <code>UIBarStyleBlackOpaque</code>. I think most people understood that, but I still prefer to be explicit.</p>
<p>Wow, that feels great to type all those <code>UI*</code> prefixes in public&#8211;I encourage everyone to do so!</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2008/10/01/iphone-sdk-nda-lifted/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone Black == Brushed Metal?</title>
		<link>http://corporationunknown.com/blog/2008/09/28/iphone-black-brushed-metal/</link>
		<comments>http://corporationunknown.com/blog/2008/09/28/iphone-black-brushed-metal/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 23:13:02 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=25</guid>
		<description><![CDATA[Yesterday I tweeted: &#8220;Sorry, but I still feel black iPhone UIs are the equivalent of brushed metal.&#8221; I was aware that people I know personally are writing applications that this would seem to disparage. I also knew that I should follow it up with more explanation than can fit in 140-character chunks.
Brushed Metal
When Apple introduced [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I <a href="http://twitter.com/pgor/statuses/937211896">tweeted</a>: &#8220;Sorry, but I still feel black iPhone UIs are the equivalent of brushed metal.&#8221; I was aware that people I know personally are writing applications that this would seem to disparage. I also knew that I should follow it up with more explanation than can fit in 140-character chunks.<span id="more-25"></span><br />
<h1>Brushed Metal</h1>
<p>When Apple introduced brushed metal, I was fine with it. I was fine with it for the QuickTime Player (partly because I rarely use it on its own); I was fine with it for iTunes and Calculator. </p>
<p>When other apps started using brushed metal (it was as simple as a checked setting in Interface Builder) and didn&#8217;t follow the guideline of &#8220;re-creat[ing] a familiar physical device,&#8221; I would actually try to find another app. I think many of these developers tried to use brushed metal to make their app stand out, but I agreed with Apple&#8217;s HIG that it made many apps look &#8220;too heavy&#8221; and, while I can&#8217;t recall specific examples, I remember it just not behaving as well for visual cues of backgrounded windows.</p>
<p>When brushed metal <a href="http://daringfireball.net/2004/10/brushedmetal">bled into Safari</a> and iChat, I started hacking their nibs to disable the brushed metal; when it infected the Finder I discovered <a href="http://gui.interacto.net/">UNO</a> and disabled it across the board (UNO also had the advantage of enabling the then-nascent &#8220;unified toolbar&#8221; interface look, which I really liked).</p>
<p>I rather like the idea of a &#8220;look&#8221; or &#8220;mode&#8221; which adds contextual information about the app itself, but when people use it with abandon, it loses its contextual purpose. In interior design, there is the concept of an <a href="http://www.hgtv.com/dc-design-colors/cant-miss-color-tips-from-david-bromstad/pictures/page-6.html">accent wall</a>: A wall (usually) painted a bolder color than the other walls to draw attention and break up the uniformity of the room without domination of the bold color. More than one accent wall in a room, and the room is split-color; <em>all</em> of the walls the accent color, and it&#8217;s no longer the accent color&#8211;it <em>is</em> the room color. This is what I feel happened with brushed metal.</p>
<h1>iPhone Black</h1>
<p>If you can remember back that far, think about a stock iPhone devoid of App Store purchases. Phone, Mail, Text, Calendar, Maps, Safari, Settings, and half the tabs in Clock&#8211;gray status bar, blue navigation and toolbars. Black is used in the tab bars, and indicates that the icons here behave differently from a toolbar (again, modes). Yes, there are a few &#8220;variants&#8221;&#8211;the Stopwatch and Timer tabs of Clock, Photos, and iPod while playing. These are all fullscreen uses, with the apparent intent to blend the controls into an unobtrusive background.</p>
<p>But notice how even the iPod application uses blue navigation bars when in table/list mode. I don&#8217;t believe there is a single Apple application with a black navigation or toolbar displaying a table view. Yet, that is exactly what many third-party applications are doing.</p>
<p>I must confess that when the App Store finally opened, I hadn&#8217;t really dived into the SDK very deeply. When I saw the first &#8220;black UI&#8221; app, I was amused at the work the developer must have done to override the standard color just to make it &#8220;sexy black.&#8221; Obviously, I didn&#8217;t know at the time that black was just another option in Interface Builder. Now I know, and it&#8217;s apparent by the large number of applications with the black UI.</p>
<h1>WWAD?</h1>
<p>As an iPhone user, I appreciate the consistency of interface among the applications. Gratuitous use of a black UI only serves to distance an application from this smooth interface flow&#8211;maybe not as bad as a yellow, green or pale blue background, or an application that doesn&#8217;t even use standard navigation, tool and tab bars&#8211;but distanced nonetheless. Ironically, as more applications use the black UI, any one app using it is no longer differentiated&#8211;it&#8217;s now just noticeably &#8220;not Apple.&#8221;</p>
<p>Maybe I&#8217;m just not good enough about developing bleeding edge user interface; I consider myself to be more in line with &#8220;WWAD?&#8221; than &#8220;<a href="http://www.gusmueller.com/blog/archives/2006/2/7.html#1428">WWPD?</a>&#8221; I&#8217;m not going to call out any specific apps as looking bad because of this, but I will give one positive comment: I think <a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284540316&#038;mt=8">Twitterrific</a> is one app that has a really good all-black look although I appreciate and prefer the &#8220;light background&#8221; preference (which I&#8217;d still like to see go all the way to standard colors).</p>
<p>I certainly wish Apple&#8217;s HIG had more guidance on this topic, but until then whenever I see a black UI app that doesn&#8217;t exhibit a <em>need</em> to take the user into a different mental mode, I consider it just as gratuitous as brushed metal.</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2008/09/28/iphone-black-brushed-metal/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
