<?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; Cocoa</title>
	<atom:link href="http://corporationunknown.com/blog/category/cocoa/feed/" rel="self" type="application/rss+xml" />
	<link>http://corporationunknown.com/blog</link>
	<description></description>
	<lastBuildDate>Tue, 21 Feb 2012 06:21:38 +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>You Got Your License In My Keychain!</title>
		<link>http://corporationunknown.com/blog/2011/04/13/you-got-your-license-in-my-keychain/</link>
		<comments>http://corporationunknown.com/blog/2011/04/13/you-got-your-license-in-my-keychain/#comments</comments>
		<pubDate>Wed, 13 Apr 2011 16:18:21 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=278</guid>
		<description><![CDATA[The One In Which Paul Talks Out His Hat (metaphorically, since he and hats don&#8217;t get along). During an entertaining aside in Andy Ihnatko&#8216;s keynote at this weekend&#8217;s Voices That Matter conference, I was reminded of a thought I&#8217;d had a while ago: Why don&#8217;t Mac desktop applications store their license info in the Keychain? [...]]]></description>
			<content:encoded><![CDATA[<p><em>The One In Which Paul Talks Out His Hat (metaphorically, since he and hats don&#8217;t get along).</em></p>
<p>During an entertaining aside in <a href="http://ihnatko.com/">Andy Ihnatko</a>&#8216;s keynote at this weekend&#8217;s <a href="http://iphonespring2011.crowdvine.com/">Voices That Matter conference</a>, I was reminded of a thought I&#8217;d had a while ago: Why don&#8217;t Mac desktop applications store their license info in the <a href="http://developer.apple.com/library/ios/#documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html">Keychain</a>?</p>
<p>Complaining about restoring license keys should be just as trite of a humor topic as little bags of peanuts on flights, but it still holds true. Go to restore a machine, or move to a new one with a clean install, and you can write off at least an afternoon launching and entering at least two text fields per application.</p>
<p>Maybe I&#8217;m the only one who feels quite comfortable with syncing to MobileMe&#8211;I actually consider it <em>the</em> feature that keeps me coming back. (I do know there are people who have frustrating issues, and I truly feel for them, but I continue to believe they are in the minority.) Given that setup, here&#8217;s how I&#8217;d see setting up a new laptop:</p>
<ol>
<li>Configure my MobileMe account and sync down the data, setting up my Mail accounts, Address Book and Calendar&#8211;and Keychain.</li>
<li>Launch a new copy of my licensed application.</li>
<li>There is no Step Three. Go on your merry way.</li>
</ol>
<p>I&#8217;m not expert enough to suggest that it would improve security of your key, but it sure would discourage casual tweaking more than the plist or hidden file schemes you&#8217;d need to develop on your own. Also, separation of license key from a preferences file (hopefully developers are already doing this) allows a user to delete the preferences and start fresh without having to worry about relicensing.</p>
<p>I understand that Keychain development can be convoluted, but is that reason enough to not make the user&#8217;s life a little bit easier and your support burden of finding a lost license a little less frequent?</p>
<p>As I said at the top, I realize I&#8217;m talking out of my&#8230;hat here. I don&#8217;t have experience doing this (yet), so I am interested in hearing reasoned arguments. Until and unless this is proven untenable, simply consider it a feature request for your next release.</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2011/04/13/you-got-your-license-in-my-keychain/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Sudden Termination</title>
		<link>http://corporationunknown.com/blog/2010/10/30/sudden-termination/</link>
		<comments>http://corporationunknown.com/blog/2010/10/30/sudden-termination/#comments</comments>
		<pubDate>Sat, 30 Oct 2010 22:19:42 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=247</guid>
		<description><![CDATA[Today, Tim Bray commented about Android applications needing to frequently save their restore state and be ready and able to gracefully terminate without notice. (This behavior also applies to iOS apps, of which I have much more experience than Android.) At some point, after I’d explained a few times why you have to write software [...]]]></description>
			<content:encoded><![CDATA[<p>Today, <a href="http://www.tbray.org/ongoing/When/201x/2010/10/30/Three-Android-Software-Rules">Tim Bray commented</a> about Android applications needing to frequently save their restore state and be ready and able to gracefully terminate without notice. (This behavior also applies to iOS apps, of which I have much more experience than Android.)</p>
<blockquote><p>At some point, after I’d explained a few times why you have to write software this way on Android, I started wondering why all software, without exception, isn’t written this way by default.
</p></blockquote>
<p>As of 10.6, Apple added <code>enableSuddenTermination</code> and <code>disableSuddenTermination</code> calls to the <a href="http://developer.apple.com/library/mac/releasenotes/MacOSX/WhatsNewInOSX/Articles/MacOSX10_6.html#//apple_ref/doc/uid/TP40008898-SW22">NSProcessInfo API</a> to allow you to implement similar behavior on the desktop. At its most simplistic description, you can inform the system your application doesn&#8217;t need to have its memory paged back in just to destroy it all&#8211;just kill the process and you will be sure it behaves properly on relaunch.</p>
<p>I encourage all fellow iOS developers who have already acquired a &#8220;sudden termination&#8221; design style to make note of this when developing a desktop Cocoa application; I also encourage desktop Cocoa developers to start thinking about how they would design with this paradigm, as it will be one more portable technique when and if you decide to go mobile.</p>
<p>(<a href="http://developer.apple.com/library/mac/#technotes/CachingPurgeableMemory/Introduction/Introduction.html">NSCache and Purgeable Memory</a> is another new-to-10.6 mechanism I consider similar to iOS&#8217; <code>didReceiveMemoryWarning</code>, only giving the OS permission to purge memory instead of it requesting you clean up.)</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2010/10/30/sudden-termination/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Software Development]]></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[iPhone]]></category>
		<category><![CDATA[Software Development]]></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 [...]]]></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[iPhone]]></category>
		<category><![CDATA[Software Development]]></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, [...]]]></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[iPhone]]></category>
		<category><![CDATA[Mac Community]]></category>
		<category><![CDATA[Software Development]]></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 [...]]]></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>13</slash:comments>
		</item>
		<item>
		<title>Cocotron</title>
		<link>http://corporationunknown.com/blog/2008/10/27/cocotron/</link>
		<comments>http://corporationunknown.com/blog/2008/10/27/cocotron/#comments</comments>
		<pubDate>Tue, 28 Oct 2008 03:44:01 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=34</guid>
		<description><![CDATA[I don&#8217;t intend for this to become a link blog&#8211;not because of some high-falutin&#8217; ideals, but because I assume most potential readers are at least as connected into the Mac dev community as I am and will have already heard the latest cool news. But the latest post by Glen Aspeslagh describes Ecamm Network&#8217;s usage [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t intend for this to become a link blog&#8211;not because of some high-falutin&#8217; ideals, but because I assume most potential readers are at least as connected into the Mac dev community as I am and will have already heard the latest cool news.</p>
<p>But the <a href="http://macdaddyworld.com/2008/10/27/adventures-in-cocotron/">latest post by Glen Aspeslagh</a> describes Ecamm Network&#8217;s usage of a project which seems to deserve increased exposure: <a href="http://www.cocotron.org/">Cocotron</a>, &#8220;an open source project which aims to implement a cross-platform Objective-C API similar to that described by Apple Inc.&#8217;s Cocoa documentation.&#8221; Or, as glibly summarized by the Ecammeratus: &#8220;Wrote a Cocoa app? Just add a new Xcode target, hit compile and out shoots a Windows version.&#8221;</p>
<p>Sure, it doesn&#8217;t work perfectly, but Glen&#8217;s warts-and-all description sounds promising. If you have a product that could benefit from a Windows equivalent please give Cocotron a look and contribute code&#8211;so it will be easier for me to use when I come up with a product that could benefit from it.</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2008/10/27/cocotron/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Adding Frameworks in Xcode 3.1</title>
		<link>http://corporationunknown.com/blog/2008/07/29/adding-frameworks-in-xcode-31/</link>
		<comments>http://corporationunknown.com/blog/2008/07/29/adding-frameworks-in-xcode-31/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 21:37:36 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=13</guid>
		<description><![CDATA[This is one of those cool little tidbits I learned during a WWDC session and can share now that Xcode 3.1 is out: Xcode 3.1 has changed the way you should add Apple-supplied frameworks. Although Apple claims in the Release Notes (you have read them, haven&#8217;t you?) that the process has been &#8220;simplified,&#8221; the method [...]]]></description>
			<content:encoded><![CDATA[<p>This is one of those cool little tidbits I learned during a WWDC session and can share now that Xcode 3.1 is out: Xcode 3.1 has changed the way you should add Apple-supplied frameworks. Although Apple claims in the Release Notes (you have read them, haven&#8217;t you?) that the process has been &#8220;simplified,&#8221; the method isn&#8217;t really apparent from within Xcode.<br />
<span id="more-13"></span></p>
<p>Previously, you would add frameworks to the Files panel by selecting the &#8220;Existing Frameworks&#8230;&#8221; item from the &#8220;Add&#8221; contextual menu, or the &#8220;Add to Project&#8230;&#8221; item of the top Project menu. (These methods are still available in Xcode 3.1.)</p>
<div style="text-align:center;"><img src="http://corporationunknown.com/blog/wp-content/uploads/2008/07/existingframework-sm.png" alt="'Add &gt; Existing Frameworks' Contextual Menu" border="0" width="346" height="342" /></div>
<p>Both options bring up a file dialog, allowing you to choose your framework from /System/Library/Frameworks or an SDK subdirectory or anywhere else on your computer. Because of the numerous copies of system frameworks, I have never been completely confident that I&#8217;m choosing the correct copy of the framework and won&#8217;t run into some really frustrating compatibility bug.</p>
<p>Since Xcode 2.5, Apple has been working to make SDKs more self-contained and swappable. Xcode 3.1 has even added an &#8220;Active SDK&#8221; submenu next to Active Configuration, Target, Executable and Architecture&#8211;you can now dynamically swap between SDK frameworks, but you must avoid the file selection dialog path for frameworks to swap between SDKs.</p>
<p>To use the new method, choose the desired Target (<em>not</em> File Group) and select &#8220;Existing Frameworks&#8230;&#8221; from the &#8220;Add&#8221; contextual menu. In 3.0 this will give you the same file dialog as before, but in 3.1 it will bring up the Target&#8217;s Get Info panel to the General tab. The bottom portion of this pane shows the Target&#8217;s Linked Libraries. Clicking the &#8220;+&#8221; button beneath the list will bring up a list of known frameworks for the active SDK. </p>
<div style="text-align:center;"><img src="http://corporationunknown.com/blog/wp-content/uploads/2008/07/frameworkadd-sm.png" alt="The New 'Add Framework' List" border="0" width="304" height="453" /></div>
<p>Choose from the list and you will not only gain the confidence that you have selected the appropriate version of the framework for your current SDK, but Xcode will be as smart as it can about automatically selecting the appropriate version of the framework if and when you target a different SDK.</p>
<p>(You can also get to this panel by double-clicking the Target, or selecting &#8220;Get Info&#8221; from the Target&#8217;s contextual menu, then selecting the General tab&#8211;it&#8217;s just more direct from the Existing Frameworks contextual menu item.)</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2008/07/29/adding-frameworks-in-xcode-31/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>NSArray and stringWithFormat:</title>
		<link>http://corporationunknown.com/blog/2008/05/27/nsarray-and-stringwithformat/</link>
		<comments>http://corporationunknown.com/blog/2008/05/27/nsarray-and-stringwithformat/#comments</comments>
		<pubDate>Wed, 28 May 2008 04:25:29 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Cocoa]]></category>

		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=5</guid>
		<description><![CDATA[The standard Cocoa method for a string with multiple replacements is [NSString&#160;stringWithFormat:]. To build a standard analogy string from the SATs: hand : palm :: foot : sole you would break out each of the replaceable elements into separate strings and replace them in the format string with the placeholder &#8216;%@&#8217;. (There are many other [...]]]></description>
			<content:encoded><![CDATA[<p>The standard Cocoa method for a string with multiple replacements is [NSString&nbsp;stringWithFormat:]. To build a standard analogy string from the SATs:</p>
<pre>
	hand : palm :: foot : sole
</pre>
<p>you would break out each of the replaceable elements into separate strings and replace them in the format string with the placeholder &#8216;%@&#8217;. (There are many other format specifiers&#8211;look up printf()&#8211;but &#8216;%@&#8217; is very common in Cocoa since it specifies an Objective-C object, not just a simple number or C null-terminated string.)</p>
<pre class="code">
	NSString * format = @"%@ : %@ :: %@ : %@";
</pre>
<p>To create the desired string:</p>
<pre class="code">
	NSString * myString =
	   [NSString stringWithFormat:format,
	                              @"hand",
	                              @"palm",
	                              @"foot",
	                              @"sole",
	                              nil];
</pre>
<p>If you want to create a different analogy string, just call stringWithFormat: again, using the same format string but different parameters following it.</p>
<p>The stringWithFormat: method takes a list of objects, and the nil parameter indicates the end of the list. If you want to manage the list of substitution parameters, though, you shouldn&#8217;t need that nil since NSArray knows how many elements it contains. Unfortunately, there isn&#8217;t a method like stringWithFormat: which takes an NSArray instead of a list of objects; there also doesn&#8217;t seem to be a simple way to convert the contents of an NSArray to a nil-terminated parameter list.</p>
<p>How then can you make this templating more dynamic at runtime by storing the list in an NSArray?</p>
<p><span id="more-5"></span></p>
<p>If you wanted to promote the list to an NSArray, your first attempt might look like:</p>
<pre class="code">
	NSArray * analogy =
	   [NSArray arrayWithObjects:@"hand",
	                             @"palm",
	                             @"foot",
	                             @"sole",
	                             nil];
	NSString * myString =
	   [NSString stringWithFormat:format, analogy];
</pre>
<p>As someone currently working in Perl, that is the idiom I would like to see, but trust me, this doesn&#8217;t work. If you&#8217;re lucky, you get the value of [analogy description] in the first placeholder and nothing (or garbage) in the rest&#8211;but usually you will just crash hard.</p>
<p>You could do a bunch of [string appendWithFormat:] calls, adding one element at a time, but that obscures the desired output in the code, and ties you to the position of elements in the array: With a format, you can flip the analogies with a format string of @&#8221;%3$@ : %4$@ :: %1$@ : %2$@&#8221; and that&#8217;s a very powerful piece of functionality which should not be readily tossed aside.</p>
<p>I searched the web for help; there are a number of instances of this question of &#8220;how can I use NSArray with stringWithFormat:?&#8221; but no solution. So I started dredging up almost-forgotten memories of ANSI C, and found something that works. For a single stringWithFormat-for-NSArray invocation:</p>
<pre class="code">
	// allocate a C array with the same number of elements as array
	id args[ [analogy count] ];
	NSUInteger index = 0;
	// copy the object pointers from NSArray to C array
	for ( id item in analogy ) {
	   args[ index++ ] = item;
	}

	NSString * myString =
	   [[NSString alloc] initWithFormat:format
	                          arguments:(va_list)args];
</pre>
<p>(As much as I dislike casts, I dislike compiler warnings even more: The cast to (va_list) appears to be safe in this case and eliminates the warning of &#8220;warning: passing argument 2 of &#8216;initWithFormat:arguments:&#8217; from incompatible pointer type.&#8221;)</p>
<p>Note that this solution uses initWithFormat:arguments: instead of the more common stringWithFormat: or even initWithFormat:&#8211;this technique only works when passing the format and arguments separately. Be aware, then, that this is not an autoreleased object&#8211;you will be responsible for releasing the resultant string.</p>
<p>This technique does have a couple drawbacks:</p>
<ul>
<li>You can&#8217;t use primitives as arguments. Then again, NSArrays only hold objects, not primitives, so that turns out to be a non-issue.</li>
<li>There seems to be no way to pre-flight the format string and ensure there are enough arguments. This isn&#8217;t any more problematic than mismatched argument lists built at compile time, but the flexibility of using an NSArray may increase the likelihood of mismatch instances.</li>
<li>Even though it would seem reasonable to assume so, I see no guarantees that the memory layout of an array will always match that of passed parameters. This has been tested on 32-bit PPC and Intel, but not 64-bit.</li>
</ul>
<p>But it also has the advantage of being able to use a well-known powerful syntax, without having to create yet another templating language (yet).</p>
<p>Now you finally have the flexibility to apply a choice of format strings to multiple objects. If you have a list of analogy &#8220;objects&#8221; to print out:</p>
<pre class="code">
	NSArray * analogies =
	   [NSArray arrayWithObjects:
	      [NSArray arrayWithObjects:@"hand",
	                                @"palm",
	                                @"foot",
	                                @"sole",
	                                nil],
	      [NSArray arrayWithObjects:@"color",
	                                @"spectrum",
	                                @"tone",
	                                @"scale",
	                                nil],
	      [NSArray arrayWithObjects:@"lawyer",
	                                @"courtroom",
	                                @"gladiator",
	                                @"arena",
	                                nil],
	      [NSArray arrayWithObjects:@"frugal",
	                                @"miserly",
	                                @"confident",
	                                @"arrogant",
	                                nil],
	   nil];
	NSArray * formats =
	   [NSArray arrayWithObjects:
	      @"analogy: %@ : %@ :: %@ : %@",
	      @"reverse: %3$@ : %4$@ :: %1$@ : %2$@",
	      @"as text: '%@' is to '%@' as '%@' is to '%@'",
	      nil];

	for ( NSArray * analogy in analogies ) {
	   id args[ [analogy count] ];
	   NSUInteger index = 0;
	   // copy the object pointers from NSArray to C array
	   for ( id item in analogy ) {
	      args[ index++ ] = item;
	   }

	   // print this analogy with multiple formats
	   for ( NSString * format in formats ) {
	      NSString * myString =
	         [[NSString alloc] initWithFormat:format
	                                arguments:(va_list)args];
	      NSLog( @"%@", myString );
	      [myString release];
	   }
	}
</pre>
<p>There you go. Now feel free to throw it into your own method, or create a category on NSArray to allow you to write code like:</p>
<pre class="code">
	for ( NSArray * analogy in analogies ) {
	   for ( NSString * format in formats ) {
	      NSLog( @"%@", [analogy myStringWithFormat:format];
	   }
	}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2008/05/27/nsarray-and-stringwithformat/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 13/16 queries in 0.005 seconds using disk: basic

Served from: corporationunknown.com @ 2012-05-18 13:47:23 -->
