<?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><![CDATA[Corporation Unknown]]></title>
	<atom:link href="http://corporationunknown.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://corporationunknown.com/blog</link>
	<description></description>
	<lastBuildDate>Wed, 02 Jan 2013 18:45:52 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://octopress.org/</generator>
  
		<item>
		<title><![CDATA[My E-Reading Quirks]]></title>
		<link>http://corporationunknown.com/blog/2015/01/04/my-e-reading-quirks/</link>
		<comments>http://corporationunknown.com/blog/2015/01/04/my-e-reading-quirks/#comments</comments>
		<pubDate>Sun, 04 Jan 2015 19:17:22 -0800</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://corporationunknown.com/blog/2015/01/04/my-e-reading-quirks</guid>
		<description><![CDATA[<p>I love paper books, but I&rsquo;m not a fetishist. I&rsquo;ve gone almost entirely digital for my technical books since they tend to be relatively massive and become outdated quickly.</p>

<p>E-Readers are such different experiences from paper books, but we seem to have already settled on interface paradigms that carry over so much paper baggage. For a while now I&rsquo;ve noticed that I have adopted a few counter-intuitive e-reading practices that others haven&rsquo;t.</p>

]]></description>
				<content:encoded><![CDATA[<p>I love paper books, but I&rsquo;m not a fetishist. I&rsquo;ve gone almost entirely digital for my technical books since they tend to be relatively massive and become outdated quickly.</p>

<p>E-Readers are such different experiences from paper books, but we seem to have already settled on interface paradigms that carry over so much paper baggage. For a while now I&rsquo;ve noticed that I have adopted a few counter-intuitive e-reading practices that others haven&rsquo;t.</p>

<!-- more -->


<h2>&ldquo;Both Margins Advance&rdquo;</h2>

<p>The typical e-reader paradigm is to swipe right-to-left or left-to-right to turn the page forward or back, respectively, and to tap the right or left margins to advance or page back. &ldquo;Duh, obvious,&rdquo; right? But is this really needed?</p>

<p>By my (highly scientific, trust me!) estimate, more than 95% of reading is moving forward&mdash;why should half of the interface be devoted to moving back? If you are right-handed, have you <em>tried</em> holding the iPad in your left hand and advancing pages while enjoying a fresh cup of coffee? Swiping is possible, but it&rsquo;s awkward.</p>

<p>iBooks has a &ldquo;Both Margins Advance&rdquo; option in its Settings.app bundle. I don&rsquo;t know if this was a sop to lefties, but for me it has become a defining feature for any good e-reader. By enabling this option, tapping either the left <em>or</em> right margin advances the page. You still have left-to-right swipe capability for the exceptional instances when you need to go back. Tapping either margin allows for comfortable ambidextrous one-hand reading while enjoying a tasty beverage or (as in my original use case when I discovered this) holding a sleeping infant.</p>

<h2>On the iPhone, Read <em>Less</em> Not More</h2>

<p>If you read on your iPhone but it&rsquo;s not your primary reading device, go make your e-reader font bigger. No, bigger than that.</p>

<p>No&hellip;still bigger. Really.</p>

<p>On my iPhone 5, my font is set so I typically only see 13 lines of body text per screen. That&rsquo;s not much; you&rsquo;ve probably actively been going the other direction trying to squeeze in a &ldquo;page&rdquo; per screen. While I initially made this adjustment due to getting older and denying that I needed reading glasses, it&rsquo;s turned out to be more generally useful.</p>

<p>When I&rsquo;m comfortably settled in for reading, I use my iPad. I really only read on my iPhone when I&rsquo;m on the go, which turns out to be highly interruptible: I&rsquo;m frequently glancing up to see if the bus is coming, or if it&rsquo;s my turn to speak to a clerk. Larger fonts don&rsquo;t necessarily help so much with the <em>reading</em> of text on iPhone as much as they help you <em>return to reading</em> after an interruption. You have much less positioning on screen to remember and can return to where you were much quicker. If this describes your reading conditions, give this tip a try&mdash;trust me, you&rsquo;ll quickly get used to the more frequent paging required.</p>

<h2>Wish List Items</h2>

<p>I wish iBooks gave me better control of styles. Most notably, I&rsquo;d like to be able to reduce the size of chapter and section headings so they don&rsquo;t overwhelm the iPhone screen at my larger font size.</p>

<p>I&rsquo;d like the ability for the screen to be <em>less</em> reactive while I&rsquo;m reading. I&rsquo;ve only dabbled in speed reading practices, but one of the first techniques they all promote is to guide your eye along the text with your finger. This is pretty impractical when it can so easily be recognized as a page-turning swipe. I&rsquo;m not really interested in getting into a pros and cons of speed reading discussion, but it is an example case where one would want to be more hands-on with the text than most e-readers allow.</p>

<p>I&rsquo;m really glad e-reading has advanced from when I first started reading on a tiny Handspring Visor. I admire those experimenting with exploring it as its own expressive medium, but I also want developers to continue to question and improve <em>how</em> we read standard texts.</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2015/01/04/my-e-reading-quirks/feed/</wfw:commentRss>
		</item>
  
		<item>
		<title><![CDATA[Preloading Development Data Into Your iOS App]]></title>
		<link>http://corporationunknown.com/blog/2014/07/10/preloading-development-data-into-your-ios-app/</link>
		<comments>http://corporationunknown.com/blog/2014/07/10/preloading-development-data-into-your-ios-app/#comments</comments>
		<pubDate>Thu, 10 Jul 2014 16:36:40 -0700</pubDate>
		<dc:creator>Paul Goracke</dc:creator>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Software Development]]></category>
		
		<guid isPermaLink="false">http://corporationunknown.com/blog/2014/07/10/preloading-development-data-into-your-ios-app</guid>
		<description><![CDATA[<p>When it comes to Core Data, many application developers don&rsquo;t even think about migration between versions. Even for those who do consider it, most testing usually ends up limited to a few simplistic scenarios: It&rsquo;s tedious to repeatedly set up a single known state for a data store, and working against a full matrix of viable scenarios is just onerous.</p>

<p>Fortunately, there is functionality within Xcode to make it easier to manage and maintain a number of scenarios and restore them readily. This functionality will allow you to test your migration code from any past data model version to the current version, debug custom migrations, even profile migrations in Instruments.</p>

<p>Unfortunately, it&rsquo;s not very well documented and, while you can preload to a device or simulator, the data package must first be created on a device.</p>

<blockquote><p><em>Update 2015-04-20:</em> This worked great in Xcode 5. Unfortunately Xcode 6 (through 6.3 as of this writing) does not behave as described for the Simulator (it does load a device just fine). Versions &lt;6.3 will tell you &ldquo;The application data package will be installed the next time you run your app in the Simulator&rdquo;&mdash;every time. Version 6.3 will just silently fail to load the package. I have reported this as <a href="rdar://20622011">rdar://20622011</a> / <a href="http://www.openradar.me/radar?id=4545448916287488">Open Radar</a></p></blockquote>

]]></description>
				<content:encoded><![CDATA[<p>When it comes to Core Data, many application developers don&rsquo;t even think about migration between versions. Even for those who do consider it, most testing usually ends up limited to a few simplistic scenarios: It&rsquo;s tedious to repeatedly set up a single known state for a data store, and working against a full matrix of viable scenarios is just onerous.</p>

<p>Fortunately, there is functionality within Xcode to make it easier to manage and maintain a number of scenarios and restore them readily. This functionality will allow you to test your migration code from any past data model version to the current version, debug custom migrations, even profile migrations in Instruments.</p>

<p>Unfortunately, it&rsquo;s not very well documented and, while you can preload to a device or simulator, the data package must first be created on a device.</p>

<blockquote><p><em>Update 2015-04-20:</em> This worked great in Xcode 5. Unfortunately Xcode 6 (through 6.3 as of this writing) does not behave as described for the Simulator (it does load a device just fine). Versions &lt;6.3 will tell you &ldquo;The application data package will be installed the next time you run your app in the Simulator&rdquo;&mdash;every time. Version 6.3 will just silently fail to load the package. I have reported this as <a href="rdar://20622011">rdar://20622011</a> / <a href="http://www.openradar.me/radar?id=4545448916287488">Open Radar</a></p></blockquote>

<!-- more -->


<h2>Your Friend the .xcappdata Package</h2>

<p>You&rsquo;ve probably encountered an <code>.xcappdata</code> package before, although you most likely think of it as a one-way data extraction method. Let&rsquo;s walk through this with as simple a demo application as possible:</p>

<ol>
<li>Create a new project. As much as I despise Apple&rsquo;s template Core Data stack, it will suffice for this example, so create a new &ldquo;Master-Detail Application&rdquo; that uses Core Data.</li>
<li>Run the application on a device.</li>
<li><p>Add 5 items.</p>

<p> <img src="http://corporationunknown.com/blog/images/2014/screenshot.png" alt="App Screenshot" /></p></li>
<li>You may stop running the application on your device&mdash;the following steps aren&rsquo;t affected by it running or not.</li>
<li><p>Open the Xcode Organizer, select the &ldquo;Applications&rdquo; section of your device under the Devices tab.</p>

<p> <img src="http://corporationunknown.com/blog/images/2014/organizer.png" alt="Xcode Organizer" /></p></li>
<li>Select your test application. You should see a bunch of folders and files populate the &ldquo;Data files in Sandbox&rdquo;. (This may not populate right away, so be patient.)</li>
<li>Click the &ldquo;Download&rdquo; button at the bottom and save the xcappdata package to your Desktop, giving it a descriptive name like <code>v0 - 5 items.xcappdata</code>.</li>
<li>Click &ldquo;Delete&rdquo; to remove the application from the device&mdash;we will try to start with a clean install for the next steps.</li>
</ol>


<p>Here comes the magic:</p>

<ol>
<li>Create a new Group in your project. I name mine &ldquo;Test Data&rdquo;.</li>
<li>Add <code>v0 - 5 items.xcappdata</code> to the group.

<ol>
<li>Select &ldquo;Copy items into group folder&rdquo;.</li>
<li>Do <em>not</em> add it to any targets.</li>
</ol>


<p> <img src="http://corporationunknown.com/blog/images/2014/project.png" alt="Project Layout" /></p></li>
<li><p>Launch the app while holding the Option key&mdash;either Option-clicking the Run button, or Option-Command-R. A scheme configuration sheet will appear.</p>

<p> <img src="http://corporationunknown.com/blog/images/2014/app_data.png" alt="Choosing Launch Options" /></p></li>
<li>In the Options tab, select <code>v0 - 5 items.xcappdata</code> from the Application Data menu and click &ldquo;Run&rdquo;.</li>
</ol>


<p>Voilá, your app has launched a clean install, but with five items in the database&mdash;Xcode has pre-configured your application with the data files from your xcappdata package.</p>

<h2>Exploring the .xcappdata Package</h2>

<p>In the Finder, Control-click the <code>.xcappdata</code> package and select &ldquo;Show Package Contents&rdquo; from the contextual menu. Inside you will find an <code>AppDataInfo.plist</code> file and an <code>AppData</code> folder. Inside the <code>AppData</code> folder are the <code>Documents</code>, <code>Library</code>, and <code>tmp</code> folders that were downloaded from the device.</p>

<p><img src="http://corporationunknown.com/blog/images/2014/package.png" alt="Package Contents" /></p>

<p>Any changes you make to these folders will be reflected the next time you launch the app with this scheme loading the application data. Let&rsquo;s make a &ldquo;clean launch&rdquo; data set:</p>

<ol>
<li><p>Duplicate <code>v0 - 5 items.xcappdata</code> in the Finder and rename it to <code>Clean Launch.xcappdata</code>.</p>

<p> <img src="http://corporationunknown.com/blog/images/2014/copy_rename.png" alt="Renaming Package" /></p></li>
<li>Open Terminal and Command-drag your <code>Clean Launch.xcappdata</code> onto it to make the package&rsquo;s path your current directory.</li>
<li>Execute <code>rm AppData/Documents/*sqlite*</code> to remove the Core Data store and supporting files.</li>
<li>Execute <code>rm -rf AppData/Library/Caches/*/.CoreDataCaches</code>. This clears out the invisible directory containing all your <code>NSFetchedResultsController</code> caches. If these are out of sync with the data store, you will encounter crashes and other frustrating behavior.</li>
<li>Add <code>Clean Launch.xcappdata</code> to your project, again remembering not to add it to any targets.</li>
</ol>


<p>Now you have a way to start from scratch whenever you want without having to delete the app first.</p>

<h2>Testing Implications</h2>

<p>Every public release version of your app should be the time to freeze the version of your Core Data model. When you release the next version of your app, you will need to account for migrating the data your users currently have to the new version&rsquo;s data model. (There may not actually be any version-to-version changes, but you should assume there will be.)</p>

<p>So as part of every release you should take a few xcappdata snapshots:</p>

<ul>
<li>Empty database. This is <em>not</em> the Clean Launch, this is the default database Core Data would generate, including anything your app automatically constructs. This is the state your app would be in if a user launched it once, didn&rsquo;t do anything, and (horrors!) forgot about your app until launching an updated version.</li>
<li>&ldquo;Typical&rdquo; user database. Run the app for a while as a typical usage scenario, then download the data package. You may have multiple &ldquo;typical&rdquo; users&mdash;make snapshots for all you can define.</li>
<li>&ldquo;Extreme&rdquo; user database. This is your chance to stress test; this is your chance to ensure that your migrations can satisfy even the most outrageous user of your application. If you need to, create a command-line tool to create a large data store using the model then copy that into the package.</li>
</ul>


<p>Add these to your project so they&rsquo;re available to use. Give them descriptive names that include at least the revision (&ldquo;v1&rdquo;, &ldquo;v2&rdquo;) and scenario (&ldquo;base&rdquo;, &ldquo;userA&rdquo;, &ldquo;extreme&rdquo;). Adding them to project groups will help organization, but the scheme menu only lists the package name so make it identifiable.</p>

<p>At some point during the development of your next release, any model updates will have settled down. Use these data sets to verify that:</p>

<ul>
<li>Migration of old versions happens</li>
<li>Migration happens correctly</li>
<li>Migration happens quickly</li>
</ul>


<p>The first two points can be tested in the simulator. If you need to write custom migration code, you will automatically start from the same point every time you launch the app after making code changes.</p>

<p>The last point of verification, though, needs to be run on real devices so you know that users will successfully migrate without having the launch watchdog kill the app launch and launch again.</p>

<p>Keep in mind that successfully migrating in the allotted launch time isn&rsquo;t enough. If the app is to all intents and purposes locked during that time, the user may choose to be the Final Watchdog and terminate your app with extreme prejudice. This is your chance to ensure a positive user experience.</p>

<h2>Manually Updating the Package</h2>

<p>You can manually update the files in an xcappdata package to create a new snapshot, but beware of a few things:</p>

<ul>
<li>&ldquo;Modern&rdquo; SQLite adds <code>.sqlite-shm</code> and <code>.sqlite-wal</code> files next to the <code>.sqlite</code> file for write-ahead logging. Be sure to keep all these files in sync with a changed <code>.sqlite</code> file by using an editor that understands these files (I recommend <a href="http://menial.co.uk/base/">Base</a>, I&rsquo;m sure there are others), or copying/replacing these auxilliary files if you replace one <code>.sqlite</code> file with another.</li>
<li><code>NSFetchedResultsController</code> caches need to stay in sync with data store changes, too. Delete the <code>.CoreDataCaches</code> directory from the package, run this package on a device long enough to exercise all the <code>NSFetchedResultsControllers</code>, then download that package as the one to keep.</li>
<li>Your app is probably more complex than the example shown. Ensure that documents stored external to the SQLite files are where they are expected, and in sync with any other changes.</li>
<li>If you can get a data file from a user or tester who is experiencing problems, that is golden. Migrate that data file into its own package and name it something like <code>v3-bug16002</code> to enshrine it in your migration testing history. Not only will this help you debug it, you will have it available going forward to avoid regressions.</li>
</ul>


<h2>Notes and Tips</h2>

<ul>
<li>The demo app saves the context every time an item is added. If your real code does not do that, be sure <code>-save:</code> is invoked at some point before you try downloading the xcappdata or you will not have the data you thought you had.</li>
<li>Application Data settings persist with the scheme. I find it useful to create a new scheme named &ldquo;Migration Testing&rdquo; and only test migrations with that scheme. This isn&rsquo;t necessary, but it&rsquo;s good to know that when you&rsquo;re using the app&rsquo;s self-titled scheme, you aren&rsquo;t accidentally resetting the data every launch.</li>
<li>Git for one doesn&rsquo;t track empty directories. In my experience it isn&rsquo;t worth worrying about because the app&rsquo;s sandbox gets laid out correctly even without directories like <code>/tmp</code> in the xcappdata package.</li>
<li>Be sure you don&rsquo;t add the packages to the app targets. This just copies them into the app bundle as resources and bloats the app.</li>
</ul>


<h2>Radars</h2>

<ul>
<li>rdar://17495757 &ndash; <a href="http://openradar.appspot.com/radar?id=5876854351200256">iOS NSFetchedResultsController: Stop hiding caches directory</a></li>
<li>rdar://17539241 &ndash; <a href="http://openradar.appspot.com/radar?id=5792266580918272">Xcode: Allow creation of .xcappdata packages from Simulator</a></li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2014/07/10/preloading-development-data-into-your-ios-app/feed/</wfw:commentRss>
		</item>
  
		<item>
		<title><![CDATA[To NSStringFromSelector or Not]]></title>
		<link>http://corporationunknown.com/blog/2014/03/24/to-nsstringfromselector-or-not/</link>
		<comments>http://corporationunknown.com/blog/2014/03/24/to-nsstringfromselector-or-not/#comments</comments>
		<pubDate>Mon, 24 Mar 2014 00:19:17 -0700</pubDate>
		<dc:creator>Paul Goracke</dc:creator>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Software Development]]></category>
		
		<guid isPermaLink="false">http://corporationunknown.com/blog/2014/03/24/to-nsstringfromselector-or-not</guid>
		<description><![CDATA[<p>In my <a href="http://corporationunknown.com/blog/2014/02/16/core-data-potpourri/">&ldquo;Core Data Potpourri&rdquo; talk</a>, I recommend declaring constant NSStrings of NSManagedObject attributes (that&rsquo;s the correct Core Data term, but I&rsquo;m just going to call them &ldquo;properties&rdquo; from here on out) for use in NSPredicates and KVC. Via Twitter, Riley Testut suggested an alternative:</p>

<blockquote class="twitter-tweet" lang="en"><p><a href="https://twitter.com/pgor">@pgor</a> have you considered using NSStringFromSelector(<a href="https://twitter.com/Selector">@selector</a>(property)) when having to hardcode a property string? Seems cleanest to me</p>&mdash; Riley Testut (@rileytestut) <a href="https://twitter.com/rileytestut/statuses/447251332399771649">March 22, 2014</a></blockquote>


<script async src="http://corporationunknown.com//platform.twitter.com/widgets.js" charset="utf-8"></script>


<p>This <em>does</em> look like it would be cleaner. There&rsquo;s not a &ldquo;magic string&rdquo; involved, and with the &ldquo;Undeclared Selector&rdquo; warning (GCC_WARN_UNDECLARED_SELECTOR) you would be warned if a property changed and your @selector wasn&rsquo;t updated. Upon closer examination, though, there are a few problems.</p>

]]></description>
				<content:encoded><![CDATA[<p>In my <a href="http://corporationunknown.com/blog/2014/02/16/core-data-potpourri/">&ldquo;Core Data Potpourri&rdquo; talk</a>, I recommend declaring constant NSStrings of NSManagedObject attributes (that&rsquo;s the correct Core Data term, but I&rsquo;m just going to call them &ldquo;properties&rdquo; from here on out) for use in NSPredicates and KVC. Via Twitter, Riley Testut suggested an alternative:</p>

<blockquote class="twitter-tweet" lang="en"><p><a href="https://twitter.com/pgor">@pgor</a> have you considered using NSStringFromSelector(<a href="https://twitter.com/Selector">@selector</a>(property)) when having to hardcode a property string? Seems cleanest to me</p>&mdash; Riley Testut (@rileytestut) <a href="https://twitter.com/rileytestut/statuses/447251332399771649">March 22, 2014</a></blockquote>


<script async src="http://corporationunknown.com//platform.twitter.com/widgets.js" charset="utf-8"></script>


<p>This <em>does</em> look like it would be cleaner. There&rsquo;s not a &ldquo;magic string&rdquo; involved, and with the &ldquo;Undeclared Selector&rdquo; warning (GCC_WARN_UNDECLARED_SELECTOR) you would be warned if a property changed and your @selector wasn&rsquo;t updated. Upon closer examination, though, there are a few problems.</p>

<!-- more -->


<h1>Problem the First: Declaration</h1>

<p>The proposed construct is not a compile-time constant, so I can&rsquo;t just change my</p>

<div>
  <pre><code class='objective-c'>NSString* const EventKeyTimeStamp = @&quot;timeStamp&quot;;</code></pre>
</div>


<p>line to</p>

<div>
  <pre><code class='objective-c'>NSString* const EventKeyTimeStamp = NSStringFromSelector(@selector(timeStamp));</code></pre>
</div>


<p>There might be a way to pull out some compiler attribute-fu to initialize this properly, but I doubt it would be able to keep the <code>const</code> qualifier that makes me feel safe.</p>

<p>The next step would be to eschew the constant variable declaration and just use a <code>#define</code> in the header:</p>

<div>
  <pre><code class='objective-c'>#define EventKeyTimeStamp NSStringFromSelector(@selector(timeStamp))</code></pre>
</div>


<p>I&rsquo;m not a fan of having actual <em>code</em> in #defines. They always seem to end up causing more trouble and obfuscation than they&rsquo;re worth, particularly when <em>I</em> write them. I&rsquo;d much rather just write a boring function or method that I can breakpoint and walk through as a normal part of my applicaton.</p>

<p>But what the heck, let&rsquo;s go with the precompiler for this one. It works. It substitutes the proper string for KVC and predicates. If you rename the <code>timeStamp</code> property to <code>timestamp</code> it will complain if you don&rsquo;t change the @selector. All looks well.</p>

<h1>Problem the Second: Indiscriminate Selectors</h1>

<p>The confidence we gain from this method is based on the undefined selector warning firing if we change the target property name. Simple testing bears that out but unfortunately that&rsquo;s not the case.</p>

<p>The undefined selector warning will be satisfied if it sees a matching selector anywhere in the current compilation unit. You may think that because our #define is in the NSManagedObject&rsquo;s header, that compilation unit is just the MO and the (hopefully limited) #imports from that header. Unfortunately, #defines are first substituted into the code in-place <em>then</em> evaluated. So when evaluated, its compilation unit includes every header the client code has imported&mdash;if any object in that unit has a matching selector, the warning will be satisfied.</p>

<p>If we rename -timeStamp to -timestamp and <em>any</em> object in the current compilation unit has a -timeStamp method, we will not be warned that we did not update this constant and it will fail in KVC and predicates at runtime.</p>

<p><em>Any</em> object.</p>

<p>If you can <em>guarantee</em> that you can create some code in your project that will never experience that kind of cross-contamination, it can be the alert system for validating your property constants. If not, the confidence using NSStringFromSelector in this case is sadly most likely false confidence.</p>

<p>At this point, I see no benefit to NSStringFromSelector in this manner. Admittedly, my constant string mechanism is no more reliable in alerting me of these problems, but my aversion to code in #define statements will keep me using constant strings.</p>

<h1>Unit Tests!</h1>

<p>If you really want safety for this (and you should), I still believe that unit tests are the most reliable way to do it.</p>

<div>
  <pre><code class='objective-c'>- (void) setUp
{
  [super setUp];
  self.managedObjectContext = [MyTestContext createInMemory];
}

- (void) testAttributes
{
  Event* event = [Event insertNewObjectInManagedObjectContext:self.managedObjectContext];
  
  NSDate* testDate = [NSDate date];
  event.timeStamp = testDate;
  XCTAssertEqualObjects(event.timeStamp, testDate, @&quot;timeStamp property failed to store properly&quot;);
  XCTAssertNoThrow([event valueForKey:EventKeyTimeStamp], @&quot;KVO property '%@' doesn't exist&quot;, EventKeyTimeStamp);
  XCTAssertEqualObjects([event valueForKey:EventKeyTimeStamp], event.timeStamp, @&quot;KVO value differs from property&quot;);
}</code></pre>
</div>



]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2014/03/24/to-nsstringfromselector-or-not/feed/</wfw:commentRss>
		</item>
  
		<item>
		<title><![CDATA[For the Record]]></title>
		<link>http://corporationunknown.com/blog/2014/02/28/for-the-record/</link>
		<comments>http://corporationunknown.com/blog/2014/02/28/for-the-record/#comments</comments>
		<pubDate>Fri, 28 Feb 2014 11:54:04 -0800</pubDate>
		<dc:creator>Paul Goracke</dc:creator>
		<category><![CDATA[Mac Community]]></category>
		
		<guid isPermaLink="false">http://corporationunknown.com/blog/2014/02/28/for-the-record</guid>
		<description><![CDATA[<p>I am honored to be on the latest installment of &ldquo;<a href="http://therecord.co/2014/02/28/paul_goracke">The Record</a>&rdquo; podcast with Brent Simmons and Chris Parrish. Since they interviewed me last summer, I&rsquo;ve been eagerly waiting to hear what they talked about with <em>other</em> interviewees. The first four episodes with Luke Adamson, John Nack, Greg Robbins, and Gus Mueller have been great. It&rsquo;s rather intimidating to think that I might be counted among them.</p>

<p>I don&rsquo;t remember most of what we discussed; I didn&rsquo;t even remember much of it immediately afterward, it flowed so smoothly. One thing I <em>do</em> remember is that I said Metrowerks was integral to the Intel transition&mdash;instead, they were part of the earlier PowerPC transition. I&rsquo;m not a historian of any kind and I don&rsquo;t pretend to be. I misspoke and know it, so I don&rsquo;t need to be set straight. Thanks.</p>

<p>Now I guess I should listen to the episode to be reminded of what I said, even if it involves the agony of listening to my own recorded voice.</p>

<p><em>Update:</em> Huh, I <em>did</em> correctly say &ldquo;PowerPC&rdquo;. See, I&rsquo;m not even a good historian of things that happened less than a year ago.</p>
]]></description>
				<content:encoded><![CDATA[<p>I am honored to be on the latest installment of &ldquo;<a href="http://therecord.co/2014/02/28/paul_goracke">The Record</a>&rdquo; podcast with Brent Simmons and Chris Parrish. Since they interviewed me last summer, I&rsquo;ve been eagerly waiting to hear what they talked about with <em>other</em> interviewees. The first four episodes with Luke Adamson, John Nack, Greg Robbins, and Gus Mueller have been great. It&rsquo;s rather intimidating to think that I might be counted among them.</p>

<p>I don&rsquo;t remember most of what we discussed; I didn&rsquo;t even remember much of it immediately afterward, it flowed so smoothly. One thing I <em>do</em> remember is that I said Metrowerks was integral to the Intel transition&mdash;instead, they were part of the earlier PowerPC transition. I&rsquo;m not a historian of any kind and I don&rsquo;t pretend to be. I misspoke and know it, so I don&rsquo;t need to be set straight. Thanks.</p>

<p>Now I guess I should listen to the episode to be reminded of what I said, even if it involves the agony of listening to my own recorded voice.</p>

<p><em>Update:</em> Huh, I <em>did</em> correctly say &ldquo;PowerPC&rdquo;. See, I&rsquo;m not even a good historian of things that happened less than a year ago.</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2014/02/28/for-the-record/feed/</wfw:commentRss>
		</item>
  
		<item>
		<title><![CDATA[Core Data Potpourri]]></title>
		<link>http://corporationunknown.com/blog/2014/02/16/core-data-potpourri/</link>
		<comments>http://corporationunknown.com/blog/2014/02/16/core-data-potpourri/#comments</comments>
		<pubDate>Sun, 16 Feb 2014 14:55:51 -0800</pubDate>
		<dc:creator>Paul Goracke</dc:creator>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Core Data]]></category>
		<category><![CDATA[Software Development]]></category>
		
		<guid isPermaLink="false">http://corporationunknown.com/blog/2014/02/16/core-data-potpourri</guid>
		<description><![CDATA[<p>Last Thursday (Feb 13, 2014) I presented a talk to <a href="http://seattlexcoders.org">Seattle Xcoders</a> entitled &ldquo;Core Data Potpourri&rdquo;. On Friday I posted a <a href="http://corporationunknown.com/presentations/Core%20Data%20Potpourri.pdf">PDF version of the slides</a>, primarily so those in attendance would have them. These slides aren&rsquo;t really intended to stand alone&mdash;hell, I wrote them up the day of the presentation&mdash;so I didn&rsquo;t intend to announce them outside Xcoders until the <a href="http://vimeo.com/seattlexcoders">video was posted</a>. (I&rsquo;m not in charge of the encoding, so I don&rsquo;t know yet when it will be posted.)</p>

<p><em>Update:</em> <a href="https://vimeo.com/89370886">Video is now live</a>. <em>-18mar14</em></p>

<p>Then <a href="http://inessential.com/2014/02/14/pauls_talk_on_core_data">Brent Simmons linked to them</a> and I feel like I&rsquo;ve been fielding questions, comments, and a pleasant number of kudos ever since. I feel like I should post some clarifications here now.</p>

<p>This talk was pretty much a <em>complete last minute change</em> from what I&rsquo;d prepared and presented internally to <a href="http://blackpixel.com/">Black Pixel</a> coworkers two days earlier because I wasn&rsquo;t happy with the boring textbook feel of that talk. If you don&rsquo;t feel it was a polished set of slides, you&rsquo;re absolutely correct.</p>

<h1>Multithreading</h1>

<p>Please keep in mind the last few slides on Core Data multithreading are woefully inadequate. I&rsquo;d intended to cover it more thoroughly as part of the &ldquo;potpourri&rdquo; concept but the list of &ldquo;best practices&rdquo; grew to pretty much be a list of many things I&rsquo;ve been ranting about to others for the last year or so, and that I&rsquo;d been sprinkling throughout client projects. I was tempted to ignore it (like I did the empty slides on performance optimization and multiple persistent stores) but felt I should reward people for sticking it out through the talk.</p>

<p>I warned the audience before discussing it that there would be a lot of handwaving and no code examples were ready&mdash;but that surely doesn&rsquo;t come across in static slides.</p>

<h1>Mogenerator</h1>

<p>The &ldquo;Why Not mogenerator&rdquo; slide has been the lightning rod, as I&rsquo;d feared&mdash;I&rsquo;ve learned you can expect that whenever you call something out in <em>any</em> negative light. Hopefully when you see the actual talk, it will come across as I intended: A response for when someone asks me why I do this &ldquo;by hand&rdquo;, not a screed trying to wipe mogenerator from the face of the Earth.</p>

<p>By the way, there&rsquo;s one response to &ldquo;how do you handle when you have to regenerate classes&rdquo; that I didn&rsquo;t even manage to get out during the presentation: Git diff. Honestly.</p>

<h1>Parent-Child Contexts</h1>

<p>This is multifold. First, I consider my &ldquo;enlightenment&rdquo; regarding multithreaded Core Data to have come during a project targeting iOS 5.1. The new contexts weren&rsquo;t an option on the project, and seeing coworkers fight the nightmares of that initial release of contexts convinced me to not bother looking into it for a while. Since then, I&rsquo;ve become comfortable enough in the &ldquo;one reader context, multiple serial writer contexts&rdquo; mechanism that I haven&rsquo;t found many compelling reasons to make parent-child my default.</p>

<p>Second, I strongly believe that <em>understanding</em> the implications and combinations of the rules &ldquo;each MO belongs to only one MOC&rdquo;, &ldquo;MOCs are not threadsafe&rdquo;, and&mdash;perhaps most importantly&mdash;&ldquo;loaded MOs need to refresh somehow&rdquo; are key to writing successful multithreaded code. After that, parent-child contexts can make great tools but too many developers treat them as the cure-all that will let them just ignore these aspects. Parent-child and thread containment can work together, it doesn&rsquo;t have to be either-or.</p>

<h1>Miscellaneous</h1>

<p>It was pointed out after the talk that my &ldquo;+newInstance&hellip;&rdquo; method for managed objects returns an autoreleased object and will break MRC conventions. Totally correct. This is mostly due to me having tried to clear out MRC space in my brain for new knowledge, but also because I threw together the talk with code examples from numerous different projects, and my naming conventions have tended to change over time. I&rsquo;m sure there are other such problems in the slides&mdash;you&rsquo;re free to &ldquo;Be Better Than Sample Code&rdquo;. :)</p>

<p>&ldquo;NSManagedObject Is the Real Top of the Stack&rdquo; might imply that you don&rsquo;t have to worry about keeping a strong reference to that parent MOC. Don&rsquo;t forget that -managedObjectContext is a weak reference and if a MOC is deallocated, any of its MOs are now invalid. In practice, I rarely have an issue with this since I&rsquo;m keeping one readonly MOC around for all my UI needs, but this is definitely something to be aware of. I still feel it&rsquo;s not worth the confusion of passing/configuring them separately.</p>

<p>I hope this clarifies some issues people have had. I hope you watch the video when it&rsquo;s released but be warned that it will probably run about 100 minutes with talk and Q&amp;A. (I&rsquo;m told Q&amp;A was actually truncated due to SD card storage limits.)</p>
]]></description>
				<content:encoded><![CDATA[<p>Last Thursday (Feb 13, 2014) I presented a talk to <a href="http://seattlexcoders.org">Seattle Xcoders</a> entitled &ldquo;Core Data Potpourri&rdquo;. On Friday I posted a <a href="http://corporationunknown.com/presentations/Core%20Data%20Potpourri.pdf">PDF version of the slides</a>, primarily so those in attendance would have them. These slides aren&rsquo;t really intended to stand alone&mdash;hell, I wrote them up the day of the presentation&mdash;so I didn&rsquo;t intend to announce them outside Xcoders until the <a href="http://vimeo.com/seattlexcoders">video was posted</a>. (I&rsquo;m not in charge of the encoding, so I don&rsquo;t know yet when it will be posted.)</p>

<p><em>Update:</em> <a href="https://vimeo.com/89370886">Video is now live</a>. <em>-18mar14</em></p>

<p>Then <a href="http://inessential.com/2014/02/14/pauls_talk_on_core_data">Brent Simmons linked to them</a> and I feel like I&rsquo;ve been fielding questions, comments, and a pleasant number of kudos ever since. I feel like I should post some clarifications here now.</p>

<p>This talk was pretty much a <em>complete last minute change</em> from what I&rsquo;d prepared and presented internally to <a href="http://blackpixel.com/">Black Pixel</a> coworkers two days earlier because I wasn&rsquo;t happy with the boring textbook feel of that talk. If you don&rsquo;t feel it was a polished set of slides, you&rsquo;re absolutely correct.</p>

<h1>Multithreading</h1>

<p>Please keep in mind the last few slides on Core Data multithreading are woefully inadequate. I&rsquo;d intended to cover it more thoroughly as part of the &ldquo;potpourri&rdquo; concept but the list of &ldquo;best practices&rdquo; grew to pretty much be a list of many things I&rsquo;ve been ranting about to others for the last year or so, and that I&rsquo;d been sprinkling throughout client projects. I was tempted to ignore it (like I did the empty slides on performance optimization and multiple persistent stores) but felt I should reward people for sticking it out through the talk.</p>

<p>I warned the audience before discussing it that there would be a lot of handwaving and no code examples were ready&mdash;but that surely doesn&rsquo;t come across in static slides.</p>

<h1>Mogenerator</h1>

<p>The &ldquo;Why Not mogenerator&rdquo; slide has been the lightning rod, as I&rsquo;d feared&mdash;I&rsquo;ve learned you can expect that whenever you call something out in <em>any</em> negative light. Hopefully when you see the actual talk, it will come across as I intended: A response for when someone asks me why I do this &ldquo;by hand&rdquo;, not a screed trying to wipe mogenerator from the face of the Earth.</p>

<p>By the way, there&rsquo;s one response to &ldquo;how do you handle when you have to regenerate classes&rdquo; that I didn&rsquo;t even manage to get out during the presentation: Git diff. Honestly.</p>

<h1>Parent-Child Contexts</h1>

<p>This is multifold. First, I consider my &ldquo;enlightenment&rdquo; regarding multithreaded Core Data to have come during a project targeting iOS 5.1. The new contexts weren&rsquo;t an option on the project, and seeing coworkers fight the nightmares of that initial release of contexts convinced me to not bother looking into it for a while. Since then, I&rsquo;ve become comfortable enough in the &ldquo;one reader context, multiple serial writer contexts&rdquo; mechanism that I haven&rsquo;t found many compelling reasons to make parent-child my default.</p>

<p>Second, I strongly believe that <em>understanding</em> the implications and combinations of the rules &ldquo;each MO belongs to only one MOC&rdquo;, &ldquo;MOCs are not threadsafe&rdquo;, and&mdash;perhaps most importantly&mdash;&ldquo;loaded MOs need to refresh somehow&rdquo; are key to writing successful multithreaded code. After that, parent-child contexts can make great tools but too many developers treat them as the cure-all that will let them just ignore these aspects. Parent-child and thread containment can work together, it doesn&rsquo;t have to be either-or.</p>

<h1>Miscellaneous</h1>

<p>It was pointed out after the talk that my &ldquo;+newInstance&hellip;&rdquo; method for managed objects returns an autoreleased object and will break MRC conventions. Totally correct. This is mostly due to me having tried to clear out MRC space in my brain for new knowledge, but also because I threw together the talk with code examples from numerous different projects, and my naming conventions have tended to change over time. I&rsquo;m sure there are other such problems in the slides&mdash;you&rsquo;re free to &ldquo;Be Better Than Sample Code&rdquo;. :)</p>

<p>&ldquo;NSManagedObject Is the Real Top of the Stack&rdquo; might imply that you don&rsquo;t have to worry about keeping a strong reference to that parent MOC. Don&rsquo;t forget that -managedObjectContext is a weak reference and if a MOC is deallocated, any of its MOs are now invalid. In practice, I rarely have an issue with this since I&rsquo;m keeping one readonly MOC around for all my UI needs, but this is definitely something to be aware of. I still feel it&rsquo;s not worth the confusion of passing/configuring them separately.</p>

<p>I hope this clarifies some issues people have had. I hope you watch the video when it&rsquo;s released but be warned that it will probably run about 100 minutes with talk and Q&amp;A. (I&rsquo;m told Q&amp;A was actually truncated due to SD card storage limits.)</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2014/02/16/core-data-potpourri/feed/</wfw:commentRss>
		</item>
  
		<item>
		<title><![CDATA[UITableViewCell Is Not a Controller, But…]]></title>
		<link>http://corporationunknown.com/blog/2013/01/01/uitableviewcell-is-not-a-controller-but/</link>
		<comments>http://corporationunknown.com/blog/2013/01/01/uitableviewcell-is-not-a-controller-but/#comments</comments>
		<pubDate>Tue, 01 Jan 2013 19:53:42 -0800</pubDate>
		<dc:creator>Paul Goracke</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=328</guid>
		<description><![CDATA[<p>Brent Simmons wrote a <a href="http://inessential.com/2012/12/31/uitableviewcell_is_not_a_controller">great defense of his proposed &ldquo;Cocoa Sin&rdquo; of &ldquo;Passing model objects to a UITableViewCell subclass&rdquo;</a>, expanding on the one apparently contentious item in his <a href="http://inessential.com/2012/12/31/coders_in_the_hands_of_an_angry_god">great list of 20 sins</a>. Go read both posts, he&rsquo;s so completely right.</p>

<p>Except I disagree.]]></description>
				<content:encoded><![CDATA[<p>Brent Simmons wrote a <a href="http://inessential.com/2012/12/31/uitableviewcell_is_not_a_controller">great defense of his proposed &ldquo;Cocoa Sin&rdquo; of &ldquo;Passing model objects to a UITableViewCell subclass&rdquo;</a>, expanding on the one apparently contentious item in his <a href="http://inessential.com/2012/12/31/coders_in_the_hands_of_an_angry_god">great list of 20 sins</a>. Go read both posts, he&rsquo;s so completely right.</p>

<p>Except I disagree.<!-- more --> I&rsquo;ve been down a number of <code>UITableViewCell</code> paths that bit me in the end, many of which Brent seems to have experienced as well, but I have ended up settling on creating <code>UITableViewCell</code> subclasses which take the model object they&rsquo;re intended to display and break out the properties to the individual subviews so the controller doesn&rsquo;t have to.</p>

<p>At its core, I&rsquo;m taking code Brent would write like this:</p>

<div>
  <pre><code class='objective-c'>- (void) updateCell:(MyTableViewCell*)cell 
     forModelObject:(Model*)object 
{
   cell.nameLabel.text = object.name;
   cell.valueLabel.text = object.value;
}</code></pre>
</div>


<p>out of the controller and moving it to the cell as</p>

<div>
  <pre><code class='objective-c'>- (void) updateForModelObject:(Model*)object 
{
   self.nameLabel.text = object.name;
   self.valueLabel.text = object.value;
}</code></pre>
</div>


<p>(Yes, he defines it as <code>-updateCell:forIndexPath:</code> but <code>-updateCell:forModelObject:</code> can always be refactored out of that once the object is found for the indexPath.)</p>

<p>There may be some additional smarts in there: The color of valueLabel may get changed at a threshold value, the name text may need some truncation or transformation, an icon may change from sun to moon depending on a timestamp in the object. I&rsquo;ve left them out of the example for simplicity.</p>

<p>At this simplistic level, they look identical. Yet I still feel putting the logic in the cell is superior. Why?</p>

<h1>Polymorphism</h1>

<p>Look a bit closer at <code>-updateCell:forModelObject:</code>. You may not even have noticed it, but there&rsquo;s a distinct absence of the keyword <code>self</code>. This isn&rsquo;t encapsulation; this method is really just a utility method, which could just as easily be written in C: </p>

<div>
  <pre><code class='objective-c'>void UpdateCellForModelObject( MyTableViewCell* cell, ModelObject* object );</code></pre>
</div>


<p>Why is this bad? It throws away polymorphism, one of my favorite aspects of object-oriented programming. Let&rsquo;s start with a theming example: We want to allow the user to chose between a set of differently-styled themes in which to display this homogeneous set of data.</p>

<p>This is fairly simple if it&rsquo;s limited to colors, fonts, and other style-only changes in the themes&mdash;change the style in <code>-tableView:cellForRowAtIndexPath:</code> and continue as before. What if one theme &ldquo;FirstLast&rdquo; should display my name as &ldquo;Paul Goracke&rdquo; and theme &ldquo;LastFirst&rdquo; should display as &ldquo;Goracke, Paul&rdquo;? The table view controller needs to know this difference. It&rsquo;s an implementation detail of the theme, but under this design the controller doesn&rsquo;t just need to know about it&mdash;it needs to <em>implement</em> it.</p>

<p>It will need to implement the quirks of <em>every</em> theme supported. Not bad enough for you? How about this: It also needs to determine which set of theme quirks to use <em>each and every invocation</em> of <code>-updateCell:forModelObject:</code>. Why would you want to do this? I don&rsquo;t.</p>

<p>By putting the logic in the cell, you only check the theme in <code>-tableView:cellForIndexPath:</code>.</p>

<ol>
<li><p> Dequeue or create a cell of the appropriate type <code>MyFirstLastTableViewCell</code> or <code>MyLastFirstTableViewCell</code>.</p></li>
<li><p> Call <code>-[cell updateForModelObject:]</code> and the receiver cell will update as appropriate for the single theme it implements.</p></li>
<li><p> There is no Step 3.</p></li>
</ol>


<p>This is the glory of polymorphism: No matter how many crazy themes I make, the table view controller only needs to know which class to make for the specified theme because the subclass knows its specific implementation. If I decide to sunset a theme, I don&rsquo;t have to worry about code cruft hanging about in the controller to handle that obsolete theme.</p>

<h1>Polymorphism with Heterogeneous Model Objects</h1>

<p>A heterogeneous data set in and of itself wouldn&rsquo;t be a problem as long as all objects provide the core set of properties the cell requires to display the items uniformly. (Such would be the case with Brent&rsquo;s Twitter app example.) Your cell(s) now take <code>-updateForModelObject:(id&lt;ModelObjectProtocol&gt;)</code>, they don&rsquo;t care which particular protocol implementor you pass them as long as they provide the properties needed to display them, and you move on.</p>

<p>But what of a heteregeneous set where each object type needs to display differently?</p>

<p>Once again, the logic of which cell subclass to create lies with <code>-tableView:cellForRowAtindexPath:</code>. After that, updating the cell&rsquo;s display of model object property changes is handled by the cell. If the model object at that indexPath were to change type, call <code>-reloadRowsAtIndexPaths:withRowAnimation:</code> on the table view to have it ask for a new or dequeued cell of the type appropriate for the model object&rsquo;s new type. </p>

<h1>What Makes a Controller a Controller?</h1>

<p>Unfortunately, Apple seems to have unintentionally muddied the MVC waters by naming their main controller class <code>UIViewController</code>. Many developers now have an extreme view of a controller: If it touches both a view and model object at all it needs to be a <code>UIViewController</code>. Nothing could be further from the truth. Unless you need lazy view loading and view appear/disappear lifecycle management, creating a <code>UIViewController</code> just overcomplicates matters.</p>

<p>Let&rsquo;s look at Apple&rsquo;s schematic of MVC, even though it should already be burned into every Cocoa and iOS developer&rsquo;s brain:</p>

<p><img src="http://corporationunknown.com/blog/images/2013/MVC2.png" alt="Model-View-Controller" /></p>

<p>It&rsquo;s easy to get caught up in defining these objects based on their positions in the diagram, but what really defines them is their <em>role</em> within the system and how updates propagate. Keep in mind that these arrows are not object references, but interactions via updates and notifications—think of them as IBActions more than IBOutlets.</p>

<p>When a <code>UITableViewCell</code> subclass accepts a model object parameter and updates its constituent subviews as I have described, it is behaving as a data transformer, <em>not</em> a controller. It does not care about any future updates to the model unless the <em>controller</em> tells it to transform the updated model object, or to transform a completely different model instance.</p>

<h1>Keys to Success</h1>

<ul>
<li><p>Avoid the temptation to bypass the controller and start key-value observing (notifications are also verboten) on the received model object. This is the hubris that will lead to your MVC downfall (been there, done that). Leave <em>all</em> of the updating logic to the &ldquo;true&rdquo; view controller, and your cell subclass will remain a happy and healthy data transformer.</p></li>
<li><p>Don&rsquo;t even keep a reference to the received model object. Not only will this help avoid the KVO temptation, but it will encourage you to quickly move the property values into the appropriate subviews and let them take care of drawing, caching and refreshing.</p></li>
<li><p>You&rsquo;re a UITableViewCell&mdash;you&rsquo;re displaying only one in a possibly innumerable collection of model objects. Leave the handling of the set of model objects to your <code>UIViewController&lt;UITableViewDataSource&gt;</code> which should be invoking tableView updates based on responding to <code>UIFetchedResultsController</code> or KVO, but there may be other update logic involved. That is, after all, the purpose of a controller.</p></li>
<li><p>Keep your cells stupid. Brent&rsquo;s examples of loading image or web service data asynchronously is still something to be avoided in the cell.</p></li>
<li><p>Keep your cells simple. Many developers try to handle all possible configurations of a cell in one. They have numerous views which are hidden or displayed based on some model object criteria, which leaves a number of unused outlets lying around; this becomes confusing and hard to maintain. Using polymorphic cell subclasses, you can dedicate one cell subclass to each distinct configuration, avoiding unused views and code maintenance overhead.</p></li>
</ul>


<h1>Conclusion</h1>

<p>There is absolutely nothing wrong with Brent&rsquo;s minimalist guidelines. They will serve you well in many situations. But once your code base gets more complicated, I think you&rsquo;ll be better served by not fearing better encapsulation of behaviors. Passing a model object to your cell is really only a venial sin.</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2013/01/01/uitableviewcell-is-not-a-controller-but/feed/</wfw:commentRss>
		</item>
  
		<item>
		<title><![CDATA[Define "Success"]]></title>
		<link>http://corporationunknown.com/blog/2012/02/20/define-success/</link>
		<comments>http://corporationunknown.com/blog/2012/02/20/define-success/#comments</comments>
		<pubDate>Mon, 20 Feb 2012 21:47:59 -0800</pubDate>
		<dc:creator>Paul Goracke</dc:creator>
		<category><![CDATA[Software Development]]></category>
		
		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=310</guid>
		<description><![CDATA[<p>What comes to mind when I say the word &ldquo;success&rdquo;?</p>

]]></description>
				<content:encoded><![CDATA[<p>What comes to mind when I say the word &ldquo;success&rdquo;?</p>

<!-- more -->


<p>Everyone has their own definition: Advancing in one&rsquo;s career; saving enough to retire; finding a significant other with whom to build a happy, healthy family. Complicating matters further, &ldquo;success&rdquo; has much finer-grained contexts: Each successive day of kicking a bad habit; completing a project milestone; passing a test in school. Many &ldquo;personal improvement&rdquo; programs would even propose that &ldquo;success&rdquo; is only measurable as a continuing accumulation of completed milestones, not any one observable point in time.</p>

<p>So why in the world do you think you can capture &ldquo;success&rdquo; in a boolean?</p>

<div>
  <pre><code class='objective-c'>BOOL success = [self doSomething];</code></pre>
</div>


<p>That method you just called actually did something, and it did something concrete: It deleted (or saved) a file on disk; parsed some JSON; validated an encrypted string.</p>

<p>Don&rsquo;t try to capture success in a variable. Name your booleans for what the code actually accomplishes and you&rsquo;ll find the following logic is much more readable with a decreased likelihood of logic bugs.</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2012/02/20/define-success/feed/</wfw:commentRss>
		</item>
  
		<item>
		<title><![CDATA[Gotcher Address Book!]]></title>
		<link>http://corporationunknown.com/blog/2012/02/09/gotcher-address-book/</link>
		<comments>http://corporationunknown.com/blog/2012/02/09/gotcher-address-book/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 14:25:20 -0800</pubDate>
		<dc:creator>Paul Goracke</dc:creator>
		<category><![CDATA[Mac Community]]></category>
		<category><![CDATA[Misc]]></category>
		
		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=302</guid>
		<description><![CDATA[<p>Even though I installed the Path app and set up an account, I never really used it. It never really clicked with me; I really only signed up because many people I know were trying/using it. So it wasn&rsquo;t anything close to a &ldquo;hardship&rdquo; for me to ask them to delete my account when it was <a href="http://mclov.in/2012/02/08/path-uploads-your-entire-address-book-to-their-servers.html">revealed that they were uploading the contents of my address book to their servers.</a> Still, I&rsquo;m disappointed.</p>

<p>Last fall, we were in the crunch-time week for a client&rsquo;s app before the iOS 5.0 submission deadline. I was profiling it in Instruments, trying to find where we could improve its launch-time performance, when I found a noticeable amount of time was spent in Address Book queries by a third-party video tracking library.</p>

]]></description>
				<content:encoded><![CDATA[<p>Even though I installed the Path app and set up an account, I never really used it. It never really clicked with me; I really only signed up because many people I know were trying/using it. So it wasn&rsquo;t anything close to a &ldquo;hardship&rdquo; for me to ask them to delete my account when it was <a href="http://mclov.in/2012/02/08/path-uploads-your-entire-address-book-to-their-servers.html">revealed that they were uploading the contents of my address book to their servers.</a> Still, I&rsquo;m disappointed.</p>

<p>Last fall, we were in the crunch-time week for a client&rsquo;s app before the iOS 5.0 submission deadline. I was profiling it in Instruments, trying to find where we could improve its launch-time performance, when I found a noticeable amount of time was spent in Address Book queries by a third-party video tracking library.</p>

<!-- more -->


<p>Not only was this behavior slowing down our launch, it was unexpected and&mdash;since it was a binary library without source code provided&mdash;we had no idea what it was doing with that information. A red flag was raised, and to my surprise the client even expressed willingness to cut the functionality until the questions could be answered.</p>

<p>As explained, the usage was almost clever: By adding a defined contact to your address book, you would unlock additional debug logging and reporting options for their SDK. They claimed that there were numerous applications already approved with this SDK, and I don&rsquo;t feel the need to question their veracity. Most importantly, they offered a build without that functionality, provided it quickly, and that&rsquo;s what shipped.</p>

<p>So it disappoints me that after my own personal experience of trying to keep code out of the Address Book, there are developers out there who apparently don&rsquo;t think twice about slurping all of your contacts and sending them to their servers without your express permission.</p>

<p>This has <a href="http://isource.com/2008/07/23/aurora-feint-removed-from-app-store-over-privacy-concerns-hopefully-to-return-soon/">happened before with Aurora Feint.</a> It forever tainted my opinion of Open Feint, which came out of that. I had been under the impression that Apple was much more strict about this type of behavior&mdash;&ldquo;chance of rejection&rdquo; was one of the main reasons I brought attention to the library&rsquo;s unexpected access. So I&rsquo;m disappointed in Apple, too.</p>

<p>There have been calls for Apple to add required guards and notifications to the API&rsquo;s access, similar to how Location Services is handled. That would probably be good, but at a certain point all the notifications just become &ldquo;Grant Access?&rdquo; alerts that users don&rsquo;t think about. I think there&rsquo;s a simpler way to do it, at least for a first attempt:</p>

<ol>
<li><p>When submitting an app to iTunes Connect, ask &ldquo;Do you access and transmit Address Book data?&rdquo; similar to the existing question about using encryption.</p></li>
<li><p>Answering &ldquo;yes&rdquo; is a flag to the review team to verify that the developers have implemented their own reasonable opt-in mechanism, and maybe even a bit more scrutiny of their network traffic.</p></li>
<li><p>If an app is found to be violating this, terminate the developer&rsquo;s account.</p></li>
</ol>


<p>Yes, I feel that violating this expectation after making it clear that you are expected to be transparent about using this kind of information is worthy of booting you out of the App Store.</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2012/02/09/gotcher-address-book/feed/</wfw:commentRss>
		</item>
  
		<item>
		<title><![CDATA[Farewell, Steve Jobs]]></title>
		<link>http://corporationunknown.com/blog/2011/10/05/farewell-steve-jobs/</link>
		<comments>http://corporationunknown.com/blog/2011/10/05/farewell-steve-jobs/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 18:56:38 -0700</pubDate>
		<dc:creator>Paul Goracke</dc:creator>
		<category><![CDATA[Mac Community]]></category>
		
		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=298</guid>
		<description><![CDATA[<p>Few depart this world having left a piece of themselves in so many others. I shall cherish my tiny share.</p>

<p>Thank you, Mr. Jobs. Thank you, Jobs family, for sharing him with us.</p>
]]></description>
				<content:encoded><![CDATA[<p>Few depart this world having left a piece of themselves in so many others. I shall cherish my tiny share.</p>

<p>Thank you, Mr. Jobs. Thank you, Jobs family, for sharing him with us.</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2011/10/05/farewell-steve-jobs/feed/</wfw:commentRss>
		</item>
  
		<item>
		<title><![CDATA[How to Fix Patents]]></title>
		<link>http://corporationunknown.com/blog/2011/05/18/how-to-fix-patents/</link>
		<comments>http://corporationunknown.com/blog/2011/05/18/how-to-fix-patents/#comments</comments>
		<pubDate>Wed, 18 May 2011 09:49:43 -0700</pubDate>
		<dc:creator>Paul Goracke</dc:creator>
		<category><![CDATA[Misc]]></category>
		
		<guid isPermaLink="false">http://corporationunknown.com/blog/?p=294</guid>
		<description><![CDATA[<p>As I understand it, the intent of a patent is to protect the value of the invention to the inventor by giving them exclusive control of the rights to use said invention. In return, they are asked to encourage future innovation by sharing that information with the world instead of keeping it a proprietary secret. Pretty simple and straightforward, and I really have a hard time disagreeing with that being a desirable goal.</p>

<p>Most of the complaints about the patent system being &ldquo;broken&rdquo; come down to a few points:</p>

]]></description>
				<content:encoded><![CDATA[<p>As I understand it, the intent of a patent is to protect the value of the invention to the inventor by giving them exclusive control of the rights to use said invention. In return, they are asked to encourage future innovation by sharing that information with the world instead of keeping it a proprietary secret. Pretty simple and straightforward, and I really have a hard time disagreeing with that being a desirable goal.</p>

<p>Most of the complaints about the patent system being &ldquo;broken&rdquo; come down to a few points:</p>

<!-- more -->


<ol>
<li><p>The patent is not novel; it&rsquo;s an obvious method to anyone spending any mental effort on the problem space.</p></li>
<li><p>The patent is too broad; It could cover any number of possible techniques without taking a stand on one (or a handful). This usually seems to be done to get around the requirement of sharing the information, keeping aspects proprietary. One might also consider this related to &ldquo;not novel.&rdquo;</p></li>
<li><p>The inventor (or, usually, reassigned rights holder commonly referred to as &ldquo;patent troll&rdquo;) has done nothing with their rights to the patent on their own. On its own, there is nothing wrong with this&mdash;it would be perfectly legitimate to have a sole licensee. When combined with items 1 or 2, though, most people agree that it&rsquo;s is predatory and stifles innovation rather than encouraging it.</p></li>
</ol>


<p>My Proposal: Within a defined grace period after patent status is granted (I&rsquo;m envisioning 5 years, maybe 7), the patent holder must show measurable revenue due to a concrete implementation of the patent, or that it is a recognizable part of another product which generates recognizable revenue. This revenue may be recognized directly by the inventor, or by licensees of the patent. If such evidence is not given within the grace period, the patent is considered fallow and control rights are revoked.</p>

<p>A patent that does not result in a concrete implementation within a reasonable period of time is hard to consider as &ldquo;benefitting society&rdquo; and thus unworthy of the rights exclusivity granted by the society in exchange.</p>
]]></content:encoded>
			<wfw:commentRss>http://corporationunknown.com/blog/2011/05/18/how-to-fix-patents/feed/</wfw:commentRss>
		</item>
  
	</channel>
</rss>

