<?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>Cocoa Is My Girlfriend &#187; Uncategorized</title>
	<atom:link href="http://www.cimgf.com/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cimgf.com</link>
	<description>Taglines are for Windows programmers</description>
	<lastBuildDate>Thu, 15 Jul 2010 21:20:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>WWDC 2010 T-Shirts</title>
		<link>http://www.cimgf.com/2010/05/12/wwdc-2010-t-shirts/</link>
		<comments>http://www.cimgf.com/2010/05/12/wwdc-2010-t-shirts/#comments</comments>
		<pubDate>Thu, 13 May 2010 02:19:03 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=1008</guid>
		<description><![CDATA[In celebration of the late notice of WWDC this year; CIMGF is offering late notice on our T-shirts! In previous years I took orders and then delivered them to you at WWDC. I discovered something from that it. It was a huge pita for everyone involved. Therefore, this year I am going to do it [...]]]></description>
			<content:encoded><![CDATA[<p>In celebration of the late notice of WWDC this year; CIMGF is offering late notice on our T-shirts!</p>

<p>In previous years I took orders and then delivered them to you at WWDC.  I discovered something from that it.  It was a huge pita for everyone involved.  Therefore, this year I am going to do it differently.</p>

<p>I have created a storefront on <a href="http://213200.spreadshirt.com/">SpreadShirt</a> where you can order one of several different T-shirts (and a jacket) for this year&#8217;s WWDC.  The new shirts include the new CIMGF logo which will soon adorn this beloved site.</p>

<p>I hope to see many of you wearing the T-Shirts this year in San Francisco!
<a href="http://www.cimgf.com/wp-content/uploads/2010/05/T-Shirt1.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2010/05/T-Shirt1.png" alt="WWDC 2010 T-Shirt" title="WWDC2010TShirt" width="100" class="alignright" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2010/05/12/wwdc-2010-t-shirts/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MacBook Pro looking for a good home</title>
		<link>http://www.cimgf.com/2009/05/08/macbook-pro-looking-for-a-good-home/</link>
		<comments>http://www.cimgf.com/2009/05/08/macbook-pro-looking-for-a-good-home/#comments</comments>
		<pubDate>Fri, 08 May 2009 15:08:48 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=563</guid>
		<description><![CDATA[Having finally decided that I prefer the 1920&#215;1200 display of the 17&#8243; Macbook Pros I am finally committing to one size of laptop. To help force myself into that commitment I am going to be selling my gently used late 2008 15&#8243; Macbook Pro. The specs are: 2.53 Ghz Intel Core Duo 4GB RAM 320 [...]]]></description>
			<content:encoded><![CDATA[<p>Having finally decided that I prefer the 1920&#215;1200 display of the 17&#8243; Macbook Pros I am finally committing to one size of laptop.  To help force myself into that commitment I am going to be selling my gently used late 2008 15&#8243; Macbook Pro.</p>

<p>The specs are:</p>

<ul>
<li>2.53 Ghz Intel Core Duo</li>
<li>4GB RAM</li>
<li>320 GB Harddrive</li>
<li>512 Nvidia Video cards (9400 and 9600)</li>
<li>2 USB</li>
<li>1 FW/800</li>
</ul>

<p>All of the original hardware and equipment are included.</p>

<p>The asking price is $1,800.00 plus shipping.</p>

<p>The machine is in perfect condition as shown in these photos on flickr (http://tr.im/kQ11).</p>

<p>If you are interested in this machine please contact me at marcus at cimgf dot com.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2009/05/08/macbook-pro-looking-for-a-good-home/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Core Data and Plug-ins</title>
		<link>http://www.cimgf.com/2009/05/03/core-data-and-plug-ins/</link>
		<comments>http://www.cimgf.com/2009/05/03/core-data-and-plug-ins/#comments</comments>
		<pubDate>Mon, 04 May 2009 03:14:40 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=512</guid>
		<description><![CDATA[Thanks to the ability to have configurations in a Core Data Managed Object Model and being able to save data to multiple Persistent Stores, it is possible to have a Core Data Model that is constructed from not only an internal model, but from the models of all the plug-ins that are loaded into the [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to the ability to have configurations in a Core Data Managed Object Model and being able to save data to multiple Persistent Stores, it is possible to have a Core Data Model that is constructed from not only an internal model, but from the models of all the plug-ins that are loaded into the application.  </p>

<p>In this example we are going to build a basic application with the following requirements:</p>

<ul>
<li>A plug-in framework</li>
<li>Plug-ins can extend the managed object model of the application</li>
<li>Removal of a plug-in should not corrupt the persistent store.</li>
</ul>

<p><span id="more-512"></span></p>

<h2 id="the_concept">The Concept</h2>

<p>Core Data allows a NSManagedObjectModel to be constructed from multiple &#8220;sub&#8221; models.  Therefore we can load up all of our plug-ins and ask them for their NSManagedObjectModel references.  Using those plus the models included with the application we can build a composite model.</p>

<p>However this would still save into a single file which would then become fragile if a plug-in disappeared.  Instead we will use Core Data Configurations.  By declaring a configuration for each model, we can specify a different file on disk for each configuration and thereby be able to split the persistent store by model on disk.  If a plug-in disappears, the configuration is not loaded and its corresponding persistent store is not loaded and therefore the integrity of the persistent store stays intact.</p>

<h2 id="the_plug_in_framework">The Plug-in Framework</h2>

<p>In this example we are not going to explore Plug-in design in too much depth.  That subject has been covered elsewhere.  Our plug-in for this design is going to use a framework to host the shared code and both the application and the bundles will link to it and import from it.</p>

<p>Our framework is going to consist of a header file that defines the protocol that the plug-ins must implement to be loaded.  The header is as follows:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@protocol</span> ZSPlugin &lt;NSObject&gt;
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>name;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>modelConfigurationName;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSManagedObjectModel</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>managedObjectModel;
&nbsp;
<span style="color: #a61390;">@end</span></pre></div></div>


<h2 id="the_example_plug_in">The Example Plug-in</h2>

<p>To test this we need to include at least one plug-in.  That plug-in will consist of a principal class along with a data model.  The plug-in does not need to stand up a Core Data stack because its model will be included in the primary application&#8217;s Core Data stack.  Therefore we just need to implement the methods in the protocol.</p>

<h3 id="_name">-name</h3>

<p>The name method in this example just returns a string.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>name;
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">return</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Example Plugin v1.0&quot;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<h3 id="_modelconfigurationname">-modelConfigurationName</h3>

<p>Like the name method above, the <code>-modelConfigurationName</code> method only returns a string.  In a more robust solution we would check in the plug-in manager to confirm that this name is unique and does not conflict with the configuration of the base application.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>modelConfigurationName;
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">return</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;ExamplePlugin&quot;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<h3 id="_managedobjectmodel">-managedObjectModel</h3>

<p>The final method that we declare in the protocol returns the NSManagedObjectModel for the plug-in.  This method does a simple load from the plug-ins bundle.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSManagedObjectModel</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>managedObjectModel;
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>managedObjectModel<span style="color: #002200;">&#41;</span> <span style="color: #a61390;">return</span> managedObjectModel;
&nbsp;
  <span style="color: #400080;">NSBundle</span> <span style="color: #002200;">*</span>myBundle <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSBundle</span> bundleForClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>bundles <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSArray</span> arrayWithObject<span style="color: #002200;">:</span>myBundle<span style="color: #002200;">&#93;</span>;
  managedObjectModel <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSManagedObjectModel</span> mergedModelFromBundles<span style="color: #002200;">:</span>bundles<span style="color: #002200;">&#93;</span> retain<span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">return</span> managedObjectModel;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>The one interesting part of this code is that we need to get a reference to the NSBundle for the plug-in from its principal class.  This is because the call [NSBundle mainBundle] will return the application&#8217;s bundle instead.  </p>

<h2 id="the_plug_in_manager">The Plug-in Manager</h2>

<p>The plug-in manager loads all of the available plug-ins on launch.  In this example we do not allow dynamic plug-in loading.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;ZSPlugin/ZSPlugin.h&gt;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> ZSPluginManager <span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span> 
<span style="color: #002200;">&#123;</span>
  <span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>loadedPlugins;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>retain<span style="color: #002200;">&#41;</span> <span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>loadedPlugins;
&nbsp;
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>shared;
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSArray</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>pluginModels;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSArray</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>modelConfigurations;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>applicationSupportFolder;
&nbsp;
<span style="color: #a61390;">@end</span></pre></div></div>


<h3 id="_init"><code>-init</code></h3>

<p>The plug-in manager is a singleton that initializes itself and loads all of the existing plug-ins upon first request.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>init
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>self <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>super init<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #a61390;">return</span> <span style="color: #a61390;">nil</span>;
&nbsp;
  <span style="color: #11740a; font-style: italic;">//Find the plugins</span>
  <span style="color: #400080;">NSFileManager</span> <span style="color: #002200;">*</span>fileManager <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSFileManager</span> defaultManager<span style="color: #002200;">&#93;</span>;
  <span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>plugins <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>fileManager directoryContentsAtPath<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self applicationSupportFolder<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>plugins count<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@:%s No plugins found&quot;</span>, <span style="color: #002200;">&#91;</span>self class<span style="color: #002200;">&#93;</span>, _cmd<span style="color: #002200;">&#41;</span>;
    <span style="color: #a61390;">return</span> self;
  <span style="color: #002200;">&#125;</span>
&nbsp;
  <span style="color: #11740a; font-style: italic;">//Load all of the plugins</span>
  <span style="color: #400080;">NSMutableArray</span> <span style="color: #002200;">*</span>loadArray <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableArray</span> array<span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>pluginPath <span style="color: #a61390;">in</span> plugins<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>pluginPath hasSuffix<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;.bundle&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #a61390;">continue</span>;
    <span style="color: #400080;">NSBundle</span> <span style="color: #002200;">*</span>pluginBundle <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSBundle</span> bundleWithPath<span style="color: #002200;">:</span>pluginPath<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">Class</span> principalClass <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>pluginBundle principalClass<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>principalClass conformsToProtocol<span style="color: #002200;">:</span><span style="color: #a61390;">@protocol</span><span style="color: #002200;">&#40;</span>ZSPlugin<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Invalid plug-in, does not conform to the ZSPlugin Protocol: %@&quot;</span>, pluginPath<span style="color: #002200;">&#41;</span>;
      <span style="color: #a61390;">continue</span>;
    <span style="color: #002200;">&#125;</span>
    id&lt;ZSPlugin&gt; plugin <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>principalClass alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>loadArray addObject<span style="color: #002200;">:</span>plugin<span style="color: #002200;">&#93;</span>;
    NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Plug-in Loaded: %@&quot;</span>, <span style="color: #002200;">&#91;</span>plugin name<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#91;</span>plugin release<span style="color: #002200;">&#93;</span>, plugin <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
  <span style="color: #002200;">&#125;</span>
  <span style="color: #002200;">&#91;</span>self setLoadedPlugins<span style="color: #002200;">:</span>loadArray<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #a61390;">return</span> self;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>In the <code>-init</code> method we first find all of the files in the Application Support directory.  If there are no files then we quickly return self.  If there are files then we start looping over them.  On each iteration we check to see if the file is a plug-in and if it is not we skip to the next loop.  If it is then we look-up its principal class and confirm that it conforms to the ZSPlugin protocol.  If it does not we warn the developer and skip to the next loop.</p>

<p>Once we pass all of the integrity checks we then call alloc and init on the plug-in and add it to the array of loaded plug-ins.</p>

<h3 id="_pluginmodels"><code>-pluginModels</code></h3>

<p>To help the main application initialize we have a couple of helper methods in the plug-in manager.  The first is a method that returns all of the plug-in models.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSArray</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>pluginModels;
<span style="color: #002200;">&#123;</span>
  <span style="color: #400080;">NSMutableArray</span> <span style="color: #002200;">*</span>array <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableArray</span> array<span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span>id&lt;ZSPlugin&gt; plugin <span style="color: #a61390;">in</span> <span style="color: #002200;">&#91;</span>self loadedPlugins<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>array addObject<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>plugin managedObjectModel<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#125;</span>
  <span style="color: #a61390;">return</span> array;
<span style="color: #002200;">&#125;</span></pre></div></div>


<h3 id="_modelconfigurations"><code>-modelConfigurations</code></h3>

<p>The second helper method returns an <code>NSArray</code> of the configuration names used by the plug-ins.  These names will be used both to load the configurations and to decide on the persistent store&#8217;s file name.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSArray</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>modelConfigurations;
<span style="color: #002200;">&#123;</span>
  <span style="color: #400080;">NSMutableArray</span> <span style="color: #002200;">*</span>array <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableArray</span> array<span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span>id&lt;ZSPlugin&gt; plugin <span style="color: #a61390;">in</span> <span style="color: #002200;">&#91;</span>self loadedPlugins<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>array addObject<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>plugin modelConfigurationName<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#125;</span>
  <span style="color: #a61390;">return</span> array;
<span style="color: #002200;">&#125;</span></pre></div></div>


<h2 id="the_primary_application">The Primary Application</h2>

<p>With our quick walkthrough of the plug-in structure complete we need to review the changes to the application itself.  All of the changes are limited to the Core Data methods.</p>

<h3 id="_managedobjectmodel"><code>-managedObjectModel</code></h3>

<p>The first change we need to make is how we load the <code>NSManagedObjectModel</code>.  Normally we would just call <code>[NSManagedObjectModel mergedModelFromBundles:nil]</code> and be done.  However we want to load not only the models within the application itself but also merge with all of the models in the plug-ins.  Therefore a couple of extra steps are required.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSManagedObjectModel</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>managedObjectModel 
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>managedObjectModel<span style="color: #002200;">&#41;</span> <span style="color: #a61390;">return</span> managedObjectModel;
&nbsp;
  <span style="color: #400080;">NSMutableArray</span> <span style="color: #002200;">*</span>models <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableArray</span> array<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>models addObject<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSManagedObjectModel</span> mergedModelFromBundles<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>models addObjectsFromArray<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>ZSPluginManager shared<span style="color: #002200;">&#93;</span> pluginModels<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  managedObjectModel <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSManagedObjectModel</span> modelByMergingModels<span style="color: #002200;">:</span>models<span style="color: #002200;">&#93;</span> retain<span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">return</span> managedObjectModel;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>In this method we start with the <code>NSManagedObjectModel</code> from the Application itself and add it to a <code>NSMutableArray</code>.  We then request an array of all the models from the plug-ins via the <code>ZSPluginManager</code> and add those models to the <code>NSMutableArray</code>.  Once we have all of the models together we call <code>+modelByMergingModels:</code> and merge all of the models into one super model.  We retain that model and return it to the caller.</p>

<h3 id="_persistentstorecoordinator"><code>-persistentStoreCoordinator</code></h3>

<p>The second and last change we need to make to the Core Data stack is the way that we handle the <code>NSPersistentStoreCoordinator</code>.  </p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSPersistentStoreCoordinator</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>persistentStoreCoordinator 
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>persistentStoreCoordinator<span style="color: #002200;">&#41;</span> <span style="color: #a61390;">return</span> persistentStoreCoordinator;
&nbsp;
  <span style="color: #400080;">NSFileManager</span> <span style="color: #002200;">*</span>fileManager;
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>applicationSupportFolder <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
  <span style="color: #400080;">NSURL</span> <span style="color: #002200;">*</span>url <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
  <span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>error <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>filePath <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
&nbsp;
  fileManager <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSFileManager</span> defaultManager<span style="color: #002200;">&#93;</span>;
  applicationSupportFolder <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>ZSPluginManager shared<span style="color: #002200;">&#93;</span> applicationSupportFolder<span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>fileManager fileExistsAtPath<span style="color: #002200;">:</span>applicationSupportFolder isDirectory<span style="color: #002200;">:</span><span style="color: #a61390;">NULL</span><span style="color: #002200;">&#93;</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>fileManager createDirectoryAtPath<span style="color: #002200;">:</span>applicationSupportFolder attributes<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@:%s Failed to create app support directory&quot;</span>, <span style="color: #002200;">&#91;</span>self class<span style="color: #002200;">&#93;</span>, _cmd<span style="color: #002200;">&#41;</span>;
      <span style="color: #a61390;">return</span> <span style="color: #a61390;">nil</span>;
    <span style="color: #002200;">&#125;</span>
  <span style="color: #002200;">&#125;</span>
&nbsp;
  <span style="color: #400080;">NSManagedObjectModel</span> <span style="color: #002200;">*</span>mom <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self managedObjectModel<span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>mom<span style="color: #002200;">&#41;</span> <span style="color: #a61390;">return</span> <span style="color: #a61390;">nil</span>;
  <span style="color: #400080;">NSPersistentStoreCoordinator</span> <span style="color: #002200;">*</span>psc <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
  psc <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSPersistentStoreCoordinator</span> alloc<span style="color: #002200;">&#93;</span> initWithManagedObjectModel<span style="color: #002200;">:</span>mom<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #400080;">NSMutableArray</span> <span style="color: #002200;">*</span>configArray <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableArray</span> array<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>configArray addObject<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Core&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>configArray addObjectsFromArray<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>ZSPluginManager shared<span style="color: #002200;">&#93;</span> modelConfigurations<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span>configName <span style="color: #a61390;">in</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>ZSPluginManager shared<span style="color: #002200;">&#93;</span> loadedPlugins<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    filePath <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>configName stringByAppendingPathExtension<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;sqlite&quot;</span><span style="color: #002200;">&#93;</span>;
    filePath <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>applicationSupportFolder stringByAppendingPathComponent<span style="color: #002200;">:</span>filePath<span style="color: #002200;">&#93;</span>;
    url <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSURL</span> fileURLWithPath<span style="color: #002200;">:</span>filePath<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>psc addPersistentStoreWithType<span style="color: #002200;">:</span>NSSQLiteStoreType 
                           configuration<span style="color: #002200;">:</span>configName 
                                     URL<span style="color: #002200;">:</span>url 
                                 options<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span> 
                                   error<span style="color: #002200;">:&amp;</span>amp;error<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
      <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSApplication</span> sharedApplication<span style="color: #002200;">&#93;</span> presentError<span style="color: #002200;">:</span>error<span style="color: #002200;">&#93;</span>;
      <span style="color: #002200;">&#91;</span>psc release<span style="color: #002200;">&#93;</span>, psc <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
      <span style="color: #a61390;">return</span> <span style="color: #a61390;">nil</span>;
    <span style="color: #002200;">&#125;</span>
  <span style="color: #002200;">&#125;</span>
&nbsp;
  persistentStoreCoordinator <span style="color: #002200;">=</span> psc;
  <span style="color: #a61390;">return</span> persistentStoreCoordinator;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>The first half of the method is almost straight out of the template.  However once we have the application support directory created and the raw NSPersistentStoreCoordinator initialized it is time to deviate.</p>

<p>The first then we do is construct a <code>NSMutableArray</code> and add our application model&#8217;s configuration name to it.  In this example I called it &#8220;Core&#8221;.  With the array initialized we then grab all of the configuration names from the plug-ins via the <code>ZSPluginManager</code> and add them to the array.</p>

<p>With the array fully populated it is time to iterate over it.  Within each iteration we do the following:</p>

<ol>
<li><p>We construct a file path for the configuration using the application support folder and the configuration name.  We add a &#8220;sqlite&#8221; extension to it although in a production system you should use an application specific extension.</p></li>
<li><p>We then add the newly constructed file path to the <code>NSPersistentStoreCoordinator</code> re-using the configuration name and checking for failure.  If we fail we present an error and abort.</p></li>
</ol>

<h2 id="conclusion">Conclusion</h2>

<p>That is all there is to it!  Core Data takes over from there and automatically saves the correct objects into the correct store files for us.  If a plug-in goes away we don&#8217;t load its model and we don&#8217;t reference it&#8217;s store so integrity remains.</p>

<p>In the included example application I have also built a UI which lists the entities that are available in the model.  If you run it straight from the zip file you will see the following UI:</p>

<p><img src="http://img.skitch.com/20090504-xp4ck1t9w42kw2cj5t6xsjus25.png"/></p>

<p>However, if after building the application, you copy the example plugin into your ~/Library/Application Support/CDPlugins directory and run the application again you will see the following.</p>

<p><img src="http://img.skitch.com/20090504-g17d82yxc2sf9k7mia448cx7rn.png"/></p>

<p>Which shows that not only is the plug-in loaded but that it&#8217;s entity (Widget) has been included in the Core Data stack.  This can even be extended to create widgets and then remove the plug-in to confirm that integrity is maintained.</p>

<p><a href='http://zds.s3.amazonaws.com/CDPlugins.zip'><img src="http://www.cimgf.com/wp-content/uploads/2008/03/xcode.png" alt="xcode.png" border="0" width="64"/><br />Plug-in Demo Project</a>
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2009/05/03/core-data-and-plug-ins/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t Blindly Trust D.E.B.B.</title>
		<link>http://www.cimgf.com/2009/03/26/dont-blindly-trust-debb/</link>
		<comments>http://www.cimgf.com/2009/03/26/dont-blindly-trust-debb/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 01:34:11 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=496</guid>
		<description><![CDATA[In some recent discussions I have been shocked to realize that many developers treat DEBB as gospel. This is a terrible idea. DEBB is written by people like me and I am a moron. The Definition Of D.E.B.B. In the original version of this article my use of the term &#8220;documentation&#8221; was not interpreted in [...]]]></description>
			<content:encoded><![CDATA[<p>In some recent discussions I have been shocked to realize that many developers treat DEBB as gospel.  This is a terrible idea.  DEBB is written by people like me and I am a moron.</p>

<p><span id="more-496"></span></p>

<h2>The Definition Of D.E.B.B.</h2>

<p>In the original version of this article my use of the term &#8220;documentation&#8221; was not interpreted in the way I had intended.  That original article offended a great number of people and for that I am truly sorry.  It was not my intention in any way, shape or form.  The goal of this blog is not to kick sand on anyone else&#8217;s shoes but to share information and to help educate.  That does not mean I will suddenly become politically correct (that would be bad for my health) but it does mean that I am not setting out to piss on anybody.</p>

<p>Within this article we are going to use a new acronym; DEBB.  DEBB is not just class documentation but encompasses all of the normal sources we use when trying to understand an API.  DEBB stands for Documentation, Examples, Blogs and Books.  There is no one word that properly encompasses all of those sources.  Therefore I am using a new acronym.  Feel free to share it.</p>

<h2>I Am A Moron</h2>

<p><img src="http://www.cimgf.com/wp-content/uploads/2009/03/chimp.png" alt="chimp.png" border="0" width="266" height="200" align="right" /></p>

<p>I think that this declaration requires some explanation before we continue with the primary focus of this article.  Just like most of the people who read this blog, I write code for a living.  Even when I am writing code by myself, there are actually three people working with that code.</p>

<p>First, there is me.  I am a clever and talented programmer.  I know to keep my code clean and easy to read.  I try to do things the right way and I know that if old code is wrong that I am better off fixing it now then trying to code around it.</p>

<p>Second, there is past me.  This guy is a fracking moron.  He pisses me off on a daily basis as I am having to constant re-write his code.  He is generally clueless and causes me more headaches than anyone else.</p>

<p>Finally there is the future me.  This guy is smarter than I am, has seen more than I have and has done more.  My goal, in addition to making sure my code works, is to make sure that my intentions are clear for him so that I don&#8217;t piss him off too badly.</p>

<p>When I claim to be a moron, it is a matter of perspective.  Compared to my 8 year old self, I am brilliant. Compared to myself in 10 years; not so much.  Therefore, it is safe to say that anything I wrote in the past was written by someone dumber than I am.</p>

<h2>DEBB Was Written By Morons</h2>

<p>All DEBB is written by humans who are by definition dumber than their current counterparts.  Until we develop and implement technology that automatically reads a developer&#8217;s mind and updates DEBB in real time, DEBB is written by morons.</p>

<p>I write this with such a strong word intentionally to shock you.  DEBB is a great resource to <em>start with</em>.  But, unfortunately, far too many people <em>stop there too</em>.  That is the mistake.  Imagine if DEBB was so accurate that we could write our code without compiling it and just trust that what DEBB says will happen actually does happen.  Would you release code that has not been compiled but is only compared with DEBB?  I wouldn&#8217;t.</p>

<h2>Most DEBB Was Not Written By People With Access To The Source</h2>

<p>The DEBB that we use is not necessarily written by developers who have had access to the source code for the APIs that we are using.  When we read an example or how-to article about writing code there is a very good chance that the person who wrote that has never seen the source code nor has any insider information.</p>

<p>Sit back and let that sink in a bit.</p>

<p>The person who wrote that example or snippet of code probably (hopefully) has more experience with that particular problem that you are reviewing but there is no guarantee.  He may very well have never released a piece of software nor even compiled the example!</p>

<p>Consider this as well: I have written hundreds of pages on Core Data and I have never seen the source code.  I would love to, but that is unlikely to ever happen.  Should you assume that every line of code I write about Core Data is 100% accurate?  No; I don&#8217;t even do that.  I constantly test my assumptions.</p>

<h2>Myths Are Born Out Of Lack Of Testing</h2>

<p>Every programming language has its own share of myths.  Objective-C is no exception to that.  I have run across many of them in my career and it is amazing how people will defend them to the very end.  Even in the face of absolute proof they will still close their eyes and ears while pretending that it just isn&#8217;t so.  Ever hear anyone tell you that a method should have only a single return at the end of the method?  That one has been around for ages.</p>

<p>There are many myths surrounding our favorite languages and each one of them deserves to be tested and challenged.  That testing cannot be conducted by someone else.  When you run across one of these myths and it sounds wrong to you <em>test it</em>.  Maybe its not a myth, maybe it is real.  But the only way you are going to know is by testing it yourself.</p>

<p>If a trusted resource ever tells you that something needs to be done a certain way, look for a reason behind it.  If the reason boils down to &#8220;because&#8221; or &#8220;its always been that way&#8221; that should be a red flag.  If it sounds fishy then test it.  Find out for yourself.  If you find out its a myth then share that knowledge.  Myths grow in the dark.  Shed light upon them.</p>

<h2>We Are Lazy</h2>

<p>Developers are by nature a lazy bunch.  We love solving problems but we generally hate doing something twice.  Therefore it is easy for us to just accept the word of a trusted source when they say that something just is and let it go at that.  However, your users, clients, customers, suffer from that form of laziness.</p>

<p>If we don&#8217;t understand why we are doing something it is our responsibility to research it and grok it.  If we don&#8217;t are we really any better than monkeys?</p>

<h2>Read The Docs But Test</h2>

<p>The DEBB on any class is a valuable resource.  It lets us know what the intention of the class was and the intention of the developer who wrote it.  It teaches us one way to use the classes that are available to solve a problem.  But don&#8217;t take it as the final authority on the subject.  That is a quick way to failure and generation of myths.</p>

<p>We should be able to explain every single line of code that we write.  We should be able to look at each line and <strong>know</strong> why its there.  If we don&#8217;t, remove it and see what happens.</p>

<p>When an error in DEBB is found we should point it out, politely, to those responsible for it.  Let them correct it so that the information can be up to date.  It is quite possible that the response will be an explanation of why it is the way it is and we can then go back and review it again.  The end result is that DEBB will get corrected or we will learn why something has an unusual structure.</p>

<h2>Conclusion</h2>

<p>I am sure many will object to my tone in this article.  Some may find it offensive.  It should be.  It was intended to shock.  But the message is the same.</p>

<p>If you treat DEBB as the final authority then you are elevating it to the same position as the Bible or other holy text.</p>

<p>That is a mistake because I helped write it and I am a moron.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2009/03/26/dont-blindly-trust-debb/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t Screw Your Customers Over</title>
		<link>http://www.cimgf.com/2009/02/26/dont-screw-your-customers-over/</link>
		<comments>http://www.cimgf.com/2009/02/26/dont-screw-your-customers-over/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 18:23:26 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=469</guid>
		<description><![CDATA[As part of working with the print world I occasionally have to actually print something out. Publishers like to have paper copies of contracts, tax documents, etc. Its a pain in the rear and outdated but a necessary evil at this point. One such occasion happened today and I needed to mail out a new [...]]]></description>
			<content:encoded><![CDATA[<p>As part of working with the print world I occasionally have to actually print something out. Publishers like to have paper copies of contracts, tax documents, etc.  Its a pain in the rear and outdated but a necessary evil at this point.</p>

<p>One such occasion happened today and I needed to mail out a new signed contract to THe Pragmatic Programmers.  As luck would have it, I lost my aging copy of Mail Factory, an app that prints nice mailing labels, since the last time I needed to print a label.  No big deal, I went to their website and tried to download a new copy.  Since the last time I used it, about a year ago, they have cancelled that product and rebranded it Labels &amp; Addresses.  Still no big deal, I downloaded the new application and recreated my label.</p>

<p>When I went to print the label I saw in the preview window that they printed &#8220;trial version&#8221; on the label.  Ok, now this is starting to get annoying.  If you are going to let me demo the software, let me demo it!  Don&#8217;t put trial version on the <strong>very first label I try to print!</strong></p>

<p>I took a deep breath, remembered that I have been using their software for many years now and decided to just buy a license.  They even took my old license in and gave me a discount.  Blood pressure dropped, things were fine.  Then I ran into their payment processor &#8212; Digital River.</p>

<p>I am stunned, <strong>stunned</strong>, that anyone is still using these thieves!  Immediately they try to charge me a &#8220;license backup&#8221; fee which is an Opt-Out.  Annoyed, I opt out of that.  On the payment page I have a choice for PayPal.  Surprise, there is a $3.50 &#8220;manual processing fee&#8221; for PayPal.  This is NOT 1998!  Still, I wanted to print a pretty label so I back out, add a credit card and hit process.  I am then presented with this:</p>

<div class="thumbnail"><a href="http://skitch.com/mzarra/bgr1p/swreg-error"><img src="http://img.skitch.com/20090226-x22pajgtf7txfnc37f95yqrqny.preview.jpg" alt="SWREG - Error" /></a><br /><span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080">Uploaded with <a href="http://plasq.com/">plasq</a>&#8216;s <a href="http://skitch.com">Skitch</a>!</span></div>

<p>Did my order go through or not?  Who knows?  I check my credit card provider, no charge.  But are they slow or did it fail?  </p>

<p>I contact the software vendor but they are only open until noon EST.  Guess I will find out tomorrow or the next day since their site claims they <i>strive</i> to respond within 1-2 days.  A happy customer this does not make.</p>

<h2 id="advice">Advice</h2>

<p>Do not do this to your customers.  Stop using these payment processing services that charge you insane amounts of money and screw your customers over.  Spend a day (yes it only takes ONE day) and write your own that links to Google or PayPal.  Or just use E-Junkie like I do.  This is a customer facing system.  When you bend your customers over with additional fees, cryptic error messages and other junk, they are not going to come back to you and say &#8220;please sir I would like some more&#8221;.  </p>

<p>Also, respond to customer email within 24 hours.  Don&#8217;t let it sit.  Don&#8217;t give your customers a 7 hour window per day that you handle email.  This is just bad.</p>

<h2 id="my_solution">My Solution</h2>

<p>I deleted their software, will be asking for a refund (IF they ever charge me) and I wrote the label by hand.  I will not be going back to them any time in the future for any of their software unless they stop using Digital River.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2009/02/26/dont-screw-your-customers-over/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MacDev 2009 Christmas Offer</title>
		<link>http://www.cimgf.com/2008/12/01/macdev-2009-christmas-offer/</link>
		<comments>http://www.cimgf.com/2008/12/01/macdev-2009-christmas-offer/#comments</comments>
		<pubDate>Mon, 01 Dec 2008 14:54:22 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=397</guid>
		<description><![CDATA[As most of you know, Scotty is hosting a developer&#8217;s conference next year in England. To make this event even more enticing, he has just announced a Christmas offer. Sign up for MacDev2009 before the 24th of December and get FREE copies of both Code Collector Pro and Changes App together worth over Â£40. There [...]]]></description>
			<content:encoded><![CDATA[<p>As most of you know, Scotty is hosting a developer&#8217;s conference next year in England.  To make this event even more enticing, he has just announced a <a href="http://www.mac-developer-network.com/conference/conference/offer.html">Christmas offer</a>.</p>

<blockquote>Sign up for MacDev2009 before the 24th of December and get FREE copies of both Code Collector Pro and Changes App together worth over Â£40.</blockquote>

<p>There are going to be some great speakers at this event and I am looking forward to it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/12/01/macdev-2009-christmas-offer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announcement: Marcus will be a Panelist at O&#8217;Reilly&#8217;s iPhoneLive conference</title>
		<link>http://www.cimgf.com/2008/10/04/announcement-marcus-will-be-a-panelist-at-oreillys-iphonelive-conference/</link>
		<comments>http://www.cimgf.com/2008/10/04/announcement-marcus-will-be-a-panelist-at-oreillys-iphonelive-conference/#comments</comments>
		<pubDate>Sat, 04 Oct 2008 16:34:50 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=313</guid>
		<description><![CDATA[Now that the NDA has been lifted we can all finally come out of the closet :) If you have not heard, O&#8217;Reilly is hosting a conference on November 18, 2008 to discuss all things iPhone. I have been invited to attend the conference as a Panelist. Please come and join the conference, if nothing [...]]]></description>
			<content:encoded><![CDATA[<p>Now that the NDA has been lifted we can all finally come out of the closet :)</p>

<p>If you have not heard, O&#8217;Reilly is hosting a conference on November 18, 2008 to discuss all things iPhone.  I have been invited to attend the conference as a Panelist.</p>

<p>Please come and join the conference, if nothing else, to heckle me :)</p>

<p><a href='http://en.oreilly.com/iphonelive2008/public/content/home'>iPhone Live</a></p>

<p>The list of speakers (as opposed to panelists), is quite impressive and definitely worth the trip.</p>

<p><a href='http://en.oreilly.com/iphonelive2008/public/schedule/speakers'>Speakers</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/10/04/announcement-marcus-will-be-a-panelist-at-oreillys-iphonelive-conference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A git quickie</title>
		<link>http://www.cimgf.com/2008/07/09/a-git-quickie/</link>
		<comments>http://www.cimgf.com/2008/07/09/a-git-quickie/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 16:22:29 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=140</guid>
		<description><![CDATA[After reading Fraser Speirs&#8217; excellent write-up on his conversion over to git, I followed a few of the links to find a bash script to display your current git branch in the command prompt. Following yet another link from that post showed how to convert the bash script to zsh. Here is my contribution to [...]]]></description>
			<content:encoded><![CDATA[<p>After reading Fraser Speirs&#8217; <a href='http://speirs.org/2008/07/09/on-switching-to-git/'>excellent write-up</a> on his conversion over to git, I followed a few of the links to find a <a href='http://www.simplisticcomplexity.com/2008/03/13/show-your-git-branch-name-in-your-prompt/'>bash script</a> to display your current git branch in the command prompt.  Following yet another link from that post showed how to convert the <a href='http://pastie.textmate.org/180088'>bash script to zsh</a>.</p>

<p>Here is my contribution to move that from the prompt to the right side of the screen.</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;">function parse_git_branch <span style="color: #009900;">&#123;</span>
  git branch <span style="color: #339933;">--</span>no<span style="color: #339933;">-</span>color <span style="color: #cc66cc;">2</span><span style="color: #339933;">&gt;</span> <span style="color: #339933;">/</span>dev<span style="color: #339933;">/</span>null <span style="color: #339933;">|</span> sed <span style="color: #339933;">-</span>e <span style="color: #ff0000;">'/^[^*]/d'</span> <span style="color: #339933;">-</span>e <span style="color: #ff0000;">'s/* \(.*\)/(\1)/'</span>
<span style="color: #009900;">&#125;</span>
function precmd<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> RPS1<span style="color: #339933;">=</span><span style="color: #ff0000;">&quot;%~$(parse_git_branch)&quot;</span> <span style="color: #009900;">&#125;</span>
export PS1<span style="color: #339933;">=</span><span style="color: #ff0000;">'&gt; '</span></pre></td></tr></table></div>


<p>Note that the last line just gives me a very short left hand prompt which I prefer.</p>

<div class="thumbnail"><a href="http://skitch.com/mzarra/xqd3/gitbranchdisplay"><img src="http://img.skitch.com/20080709-ngkx7df3p6npn79dmykg8qiyqs.preview.jpg" alt="GitBranchDisplay" /></a><br /><span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080">Uploaded with <a href="http://plasq.com/">plasq</a>&#8216;s <a href="http://skitch.com">Skitch</a>!</span></div>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/07/09/a-git-quickie/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A Case Against Dot Syntax</title>
		<link>http://www.cimgf.com/2008/07/08/a-case-against-dot-syntax/</link>
		<comments>http://www.cimgf.com/2008/07/08/a-case-against-dot-syntax/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 22:41:14 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=137</guid>
		<description><![CDATA[I was not born an Objective-C developer. I know that in some circles that is considered a mortal sin. Before learning Objective-C and Cocoa I had developed in a great number of languages dating back to the early 1980&#8242;s. I tell you this so that what you are about to read next is taken in [...]]]></description>
			<content:encoded><![CDATA[<p>I was not born an Objective-C developer.  I know that in some circles that is considered a mortal sin.  Before learning Objective-C and Cocoa I had developed in a great number of languages dating back to the early 1980&#8242;s.  I tell you this so that what you are about to read next is taken in the light that it was intended.</p>

<p>Take a look at the following lines of code:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>doSomethingSpecial
<span style="color: #002200;">&#123;</span>
	myVar.itsAttribute <span style="color: #002200;">=</span> <span style="color: #2400d9;">10</span>;
	myOtherVar.itsAttribute <span style="color: #002200;">=</span> <span style="color: #2400d9;">20</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Now tell me, what is myVar and myOtherVar.  Is it an object or a struct?  Can&#8217;t tell from that piece of code can you.  That is half of my argument against dot syntax in Objective-C.  It makes the meaning of your code unclear.  Objective-C is known for its self documenting nature.  Dot Syntax removes that.</p>

<p><span id="more-137"></span></p>

<p>Next, lets take a look at another piece of example code:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>myCompliatedMethod
<span style="color: #002200;">&#123;</span>
	MyObject <span style="color: #002200;">*</span>object <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>MyObject alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	object.attribute1 <span style="color: #002200;">=</span> <span style="color: #2400d9;">10</span>;
	object.attribute2 <span style="color: #002200;">=</span> <span style="color: #2400d9;">20</span>;
	OtherObject <span style="color: #002200;">*</span>nextObject <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OtherObject alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>nextObject doSomethingAmazingWith<span style="color: #002200;">:</span>object<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>nextObject.result &gt; <span style="color: #2400d9;">10</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
		<span style="color: #002200;">&#91;</span>object doSomethingElse<span style="color: #002200;">&#93;</span>;
		<span style="color: #a61390;">return</span> <span style="color: #a61390;">NO</span>;
	<span style="color: #002200;">&#125;</span>
	<span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Yes, this is clearly contrived code.  However, hopefully, its meaning is clear.  dot syntax breaks up the flow of the code.  Code should be elegant.  It should be graceful and beautiful to look at.  This is ugly, nasty code that you want to fold as fast as possible so that you can stop looking at it.  The message passing lines are completely at odds with the dot syntax lines.  The difference is striking and distracting.</p>

<p>When we write code, we care about its formatting.  We care that the code is properly indented and that the indentation is consistent.  We should care equally as much about its consistency of style and design.  Switching from message passing over to dot syntax and back is not consistent.</p>

<p>Now lets compare this against keeping the entire method within message passing:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>myCompliatedMethod
<span style="color: #002200;">&#123;</span>
	MyObject <span style="color: #002200;">*</span>object <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>MyObject alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>object setAttribute1<span style="color: #002200;">:</span><span style="color: #2400d9;">10</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>object setAttribute2<span style="color: #002200;">:</span><span style="color: #2400d9;">20</span><span style="color: #002200;">&#93;</span>;
	OtherObject <span style="color: #002200;">*</span>nextObject <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OtherObject alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>nextObject doSomethingAmazingWith<span style="color: #002200;">:</span>object<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>nextObject result<span style="color: #002200;">&#93;</span> &gt; <span style="color: #2400d9;">10</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
		<span style="color: #002200;">&#91;</span>object doSomethingElse<span style="color: #002200;">&#93;</span>;
		<span style="color: #a61390;">return</span> <span style="color: #a61390;">NO</span>;
	<span style="color: #002200;">&#125;</span>
	<span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>There is now a consistency of form and style.  The code flows more smoothly and is not as jarring.</p>

<h2>Dispelling some myths</h2>

<p>I want to dispel a couple of myths about dot syntax in Objective-C while I am on the subject.</p>

<ol>
<li>Dot syntax is not faster than message passing.  It is syntactic sugar that is translated to normal message passing.</li>

<li>Using dot syntax to set an attribute to nil is <strong>not</strong> a more efficient way to release an object.  It is less lines of code but just as heavy as [object setAttribute:nil].</li>

<li>Using dot syntax will not directly access the attribute on an object.  While this is true in some languages, the actual call path for an Objective-C dot syntax accessor is:<sup>1</sup>

<ul>
    <li>Resolve the accessor selector from the call</li>
    <li>The accessor method, if that does not exist</li>
    <li>The attribute itself, if that does not exist</li>
    <li>The unknownValueForKey: method is called last.</li>
</ul></li>

</ol>

<h2>Why did Apple add it?</h2>

<p>I have my own theories on why this nastiness was added to the language.  It could be due to all of the windows hacks coming over to OS X and a desire to make them feel a little more comfortable.</p>

<p>It could be that a battle rages between the Carbon developer and the Cocoa developers and this was a concession to the Carbon developers since Carbon is going away.</p>

<p>It could be that while adding properties (a most useful feature of Objective-C 2.0), the developers decided &#8220;why not&#8221; and threw them in there.</p>

<p>We may never know the real reason behind adding these to the language.  However it is clear that they are here to stay and I mourn their coming.  They are a confusing addition to the language and cause developers new to our platform to bring bad habits with them.  </p>

<p>Unfortunately they have made their way into Apple&#8217;s sample code as well as the language.  This is truly unfortunate.  As I have mentioned in the past, the sample code that Apple provides is not the best case solution; however many developers will think so.  By adding dot syntax into these examples, it exacerbates the problem.  New/young developers coming to the platform will see this dot syntax as the &#8220;right way&#8221; to do things and they will become a maintenance nightmare.</p>

<h2>Maintainability</h2>

<p>The last thoughts on this subject are with regard to maintainability.  We often forget about this aspect when we are working by ourselves.  However, maintainability is not just a factor when we hand off code to another developer, it is also a factor when we have to come back to our own code 6 months from now!  I don&#8217;t know about you but when I look at code I wrote a year ago all I can think is: &#8220;That moron!  What the HELL was he thinking!&#8221;</p>

<p>Since dot syntax is not as clear with regard to intent as message passing is, then we should avoid it for maintainability as well.  Who wants to have to constant flip back to the header file while reviewing a piece of code to remember if we are talking to an object or a struct.  Keep the intention clear, keep the code clear, and maintainability will follow.</p>

<h2>Conclusion</h2>

<p>In the end, it is a matter of preference.  I hope that these topics have helped to show the negative effects of using dot syntax in Objective-C.  It is purely syntactic sugar and adds nothing to the language.  However, there are so many cons that I cannot suggest that anyone use it in any situation.</p>

<hr/>

<p><small></p>

<ol>
<li>
<p>Thanks go to Chris Hanson for setting me straight on this precise order.</p>
</li>
</ol>

<p></small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/07/08/a-case-against-dot-syntax/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Where has cimgf gone?</title>
		<link>http://www.cimgf.com/2008/07/04/where-has-cimgf-gone/</link>
		<comments>http://www.cimgf.com/2008/07/04/where-has-cimgf-gone/#comments</comments>
		<pubDate>Fri, 04 Jul 2008 18:17:10 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=136</guid>
		<description><![CDATA[As you can probably imagine, we have been heads down coding for the past month. Can I tell you what I am working on? Nope and if you are in the community you can guess why. However, here is a hint. What does a deadline look like? And my desk to go along with that [...]]]></description>
			<content:encoded><![CDATA[<p>As you can probably imagine, we have been heads down coding for the past month.  Can I tell you what I am working on?  Nope and if you are in the community you can guess why.</p>

<p>However, here is a hint.</p>

<p><a href="http://outerlevel.com/blog/2008/07/04/what-does-a-deadline-look-like/">What does a deadline look like?</a></p>

<p>And my desk to go along with that link:</p>

<div class="thumbnail"><a href="http://skitch.com/mzarra/xrdr/deadline-looming"><img src="http://img.skitch.com/20080704-1jxxjxpcq8h515icc3x9hd8xt5.preview.jpg" alt="Deadline_Looming" /></a><br /><span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080">Uploaded with <a href="http://plasq.com/">plasq</a>&#8216;s <a href="http://skitch.com">Skitch</a>!</span></div>
]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/07/04/where-has-cimgf-gone/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
