<?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>Discern, Design, Generate</title>
	<atom:link href="http://blog.ddg.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.ddg.com</link>
	<description>Code and Design Thoughts from Donoho Design Group, L.L.C.</description>
	<lastBuildDate>Sun, 09 Oct 2011 18:04:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>A Pattern to Declare an Objective-C Mix-in</title>
		<link>http://blog.ddg.com/?p=81</link>
		<comments>http://blog.ddg.com/?p=81#comments</comments>
		<pubDate>Sun, 09 Oct 2011 18:02:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[DDG]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://blog.ddg.com/?p=81</guid>
		<description><![CDATA[The missing piece for creating a full fledged mix-in, or multiple inheritance, language out of Objective-C was the addition of associated references. My earlier post on creating a category that uses associated references is an example of the basic framework to do so. All it was missing was a formal way for the compiler to [...]]]></description>
			<content:encoded><![CDATA[<p>The missing piece for creating a full fledged mix-in, or multiple inheritance, language out of Objective-C was the addition of associated references. My earlier post on creating a category that uses associated references is an example of the basic framework to do so. All it was missing was a formal way for the compiler to enforce the types of the mix-in. A protocol provides this mechanism. This post will show how to create and use this convention.</p>
<h2>Use Cases</h2>
<p>There are, at least, two use cases for a mix-in. First, it is an organizational mechanism for building libraries that can be added to any proprietary class. This has been a common use for categories since they were invented and implemented in Obective-C. Unfortunately, it was always restricted to only adding methods and not ivars to a class. Obviously, using associated references addresses this limitation. Second, it can be used to add functionality to existing classes in a precompiled framework, as in my <code>DDGActivity</code> example adding an indicator to a <code>UIView</code>.</p>
<h2>Modifications to <code>DDGActivityViewController</code></h2>
<p>The changes are quite simple. You convert your category into an <code>@protocol</code>. I will show two examples. First, I&#8217;ll add a mix-in to support TestFlight&#8217;s SDK. TestFlight is an excellent service to support a wide area Ad Hoc app testing program. You can learn about their SDK at <a href="http://TestFlightApp.com">http://TestFlightApp.com</a>. There are other companies/open source software projects that provide similar services, such as QuicyKit, <a href="http://QuincyKit.net">http://QuincyKit.net</a>, and HockeyKit, <a href="http://HockeyKit.net">http://HockeyKit.net</a>.</p>
<p>The example&#8217;s goal is to use TestFlight during Ad Hoc testing and to compile the code out of the app for deployment. There is some question whether Apple allows apps into the App Store with the crash reporting functionality provided by TestFlight. Hence, I wanted a mechanism that made it trivial to remove TestFlight without placing conditional compilation statements throughout my application. I also added an ivar, <code>lastCheckpoint</code>, to contain the last string saved by the <code>-passCheckpoint:</code> method.  This ivar is a proper <code>@property</code>. Hence, you can observe the ivar and do things like collect a history of the checkpoints. I&#8217;ve implemented simple logging in the view controller this way.</p>
<p>All of the type information is contained in two files. The first file contains a traditional declaration of a protocol. In this case, it is <code>DDGTestFlight.h</code>. It is name spaced because I wrote it. It more appropriately belongs in the <code>TestFlight.h</code> file in the TestFlight SDK. The second file is a simple modification of the category file in the previous version of this project. It is a very simple change. You import the header and then apply the protocol to the category. As in:</p>
<pre><code>@interface DDGActivityViewController (DDGTestFlight) &lt;DDGTestFlight&gt;
</code></pre>
<p>As with any protocol, this allows you to precisely control both the type and which methods are required to be implemented. While the category and the protocol do not need to have the exact same name, that seems like it is a good convention to adopt.</p>
<h2>Modifications to <code>DDGView</code></h2>
<p>The category on <code>UIView</code> is similarly simple augmented. A protocol file, <code>DDGView.h</code>, is written and it is included and applied to the category. As in:</p>
<pre><code>@interface UIView (DDGView) &lt;DDGView&gt;
</code></pre>
<p>I implement the same naming convention as in DDGTestFlight.</p>
<h2>Code Encapsulation Improvements Appear in <code>ModalViewController</code></h2>
<p>A very nice side effect of using protocols instead of categories is the information encapsulation now possible. In <code>ModalViewController</code>, we are able to just test for the protocol and not the class of the mixed-in instance. Your code is now more loosely coupled as a result. Traditionally, this means it is more robust against changes in other parts of your program. This is a good thing.</p>
<h2>Summary</h2>
<p>Moving to a protocol driven technique of adding both associative references and methods improves the encapsulation of your classes while also partitioning type information in a useful fashion. As it is a pretty simple addition to what you need to do to add associative references anyway, I recommend that you do it. As before, you can get the source code up at GitHub, <a href="http://bit.ly/DDGActivityGH">http://bit.ly/DDGActivityGH</a>.</p>
<h2>Postscript to our Friends at TestFlight</h2>
<p>As you can see from the above, it is pretty straightforward to add an effective form of conditional compilation to your system. I would raise two issues. First, the team token for <code>DDGActivity</code> in my account is hard compiled into the code. I&#8217;m OK with this if you are. Second, more importantly, I want to encourage you to embrace this method of adding a TestFlight mix-in. In your case, I recommend that you create and maintain the TestFlight protocol. Furthermore, as Apple is standardizing on the class name AppDelegate in their Xcode 4 templates, it is almost trivial to change my category implementation to apply to <code>AppDelegate</code> instead of <code>DDGActivityViewController</code>. Unlike the rest of your library, I want to encourage you to keep the source code for this category visible to your licensees.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ddg.com/?feed=rss2&#038;p=81</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Steve Jobs RIP</title>
		<link>http://blog.ddg.com/?p=77</link>
		<comments>http://blog.ddg.com/?p=77#comments</comments>
		<pubDate>Thu, 06 Oct 2011 20:46:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[DDG]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.ddg.com/?p=77</guid>
		<description><![CDATA[Steve Jobs changed my life. Outside of my immediate family, I think I can only say that about him. I wanted to contribute to his vision. I left graduate school to write Mac software &#8212; D2 Software&#8217;s MacSpin &#8212; to contribute to Jobs&#8217; vision. I followed the siren call of multiprocessor performance and lead a [...]]]></description>
			<content:encoded><![CDATA[<p>Steve Jobs changed my life.</p>
<p>Outside of my immediate family, I think I can only say that about him.</p>
<p>I wanted to contribute to his vision.</p>
<p>I left graduate school to write Mac software &#8212; D<sup>2</sup> Software&#8217;s MacSpin &#8212; to contribute to Jobs&#8217; vision.</p>
<p>I followed the siren call of multiprocessor performance and lead a team to create the TokaMac family of Mac accelerators. People could do more on their Macs with my products.</p>
<p>In the height of irony, I joined IBM to lead IBM&#8217;s Mac OS licensing technical team. We were successful. Jobs disapproved.</p>
<p>I spent 11 years in IBM Software Group tracking everything Apple did. Apple once suggested that IBM embrace a Cocoa UI in Java. I countered with a vision of a browser based UI. We now call it AJAX. It was the original programming model for the iPhone.</p>
<p>In 2009, I asked to be laid off from IBM. The goodbye severance launched a new embrace of Jobs&#8217; vision; I returned to programming with the iPhone.</p>
<p>I am beyond being a fanboy. People who call me that don&#8217;t understand the vision.</p>
<p>I am a contributor.</p>
<p>Thank you Steve for making a place to play and contribute.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ddg.com/?feed=rss2&#038;p=77</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DDGActivity: An Example of Using Associated References</title>
		<link>http://blog.ddg.com/?p=59</link>
		<comments>http://blog.ddg.com/?p=59#comments</comments>
		<pubDate>Mon, 26 Sep 2011 14:05:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[DDG]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.ddg.com/?p=59</guid>
		<description><![CDATA[Object oriented languages have always allowed a programmer to add both methods and ivars to any class. Apple recommends you should not over-ride some Cocoa/Cocoa Touch classes. Hence, you cannot use inheritance to add ivars and methods to those classes. Of course, Objective-C has always offered the category mechanism as a way to add arbitrary [...]]]></description>
			<content:encoded><![CDATA[<p>Object oriented languages have always allowed a programmer to add both methods and ivars to any class. Apple recommends you should not over-ride some Cocoa/Cocoa Touch classes. Hence, you cannot use inheritance to add ivars and methods to those classes. Of course, Objective-C has always offered the category mechanism as a way to add arbitrary methods to any class. But historically, categories cannot add ivars. Apple has addressed this in the modern Objective-C runtime with a mechanism called associated references. I have tested this code on iOS v4+.</p>
<p>The example app shows you how use an associated reference to add a <code>UIActivityIndicatorView</code> to every <code>UIView</code>, just as if it was any other ivar.</p>
<h3><code>UIView (DDG)</code> category</h3>
<p>This category adds an <code>@property</code> and a method, <code>-centerIndicator</code> to a <code>UIView</code>. Here is the header:</p>
<pre><code>#import &lt;UIKit/UIKit.h&gt;

extern NSString *const kActivityIndicatorKey;

@interface UIView (DDG)

@property (nonatomic, retain) UIActivityIndicatorView *activityIndicator;

- (void) centerIndicator;

@end
</code></pre>
<p>As we are using an <code>@property</code>, I also add a constant string key to support key-value coding. (I do this to allow the Xcode&#8217;s function completion to suggest the right key. This, of course, ensures that you don&#8217;t inadvertently add a typo to your key.)</p>
<h3>How Do You Use It?</h3>
<p>Here I create an <code>activityIndicator</code> and add it to a <code>UIViewController</code>&#8216;s <code>UIView</code>.</p>
<pre><code>self.view.activityIndicator = [[[UIActivityIndicatorView alloc]
                                initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray]
                               autorelease];
[self.view addSubview: self.view.activityIndicator];
[self.view centerIndicator];

[self.view.activityIndicator startAnimating];
</code></pre>
<p>Here I release the activity indicator:</p>
<pre><code>[self.view.activityIndicator removeFromSuperview];
self.view.activityIndicator = nil;
</code></pre>
<p>That is straightforward and is used no differently from any other ivar that contains a <code>UIActivityIndicatorView</code>.</p>
<h3>A Pleasant Surprise.</h3>
<p>One downside of the category mechanism is that it cannot over-ride any arbitrary method. This is a problem. To preclude a memory leak, all instances need to be released. But you cannot override <code>-dealloc</code> with a category. How do we solve this problem? We don&#8217;t have to; the Objective-C runtime handles this for us. This is another example of Objective-C evolving into a modern object oriented language that manages its own memory.</p>
<p>The example application allows you to create a modal view. When you dismiss the modal view, the <code>activityIndicator</code> is automatically released by the runtime and not by a <code>-dealloc</code> method. Please run the example app under Instruments&#8217; memory leak tool. You will see this to be true.</p>
<h3>How Does It Work?</h3>
<p>The <code>activityIndicator</code> is an <code>@dynamic @property</code>. Hence, we need to implement both the setter and getter. All of this code is in <code>UIView+DDG.h/.m</code> files.</p>
<p>Here is the getter:</p>
<pre><code>- (UIActivityIndicatorView *) activityIndicator {

    return objc_getAssociatedObject(self, kActivityIndicatorARKey);

} // -activityIndicator
</code></pre>
<p>Here is the setter:</p>
<pre><code>- (void) setActivityIndicator: (UIActivityIndicatorView *) activityIndicator {

    objc_setAssociatedObject(self,
                             kActivityIndicatorARKey, activityIndicator,
                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);

} // -setActivityIndicator:
</code></pre>
<p>As you can see, the runtime provides a simple C-function to implement both accessors. The runtime identifies the associated reference by this C-string key:</p>
<pre><code>static const char *kActivityIndicatorARKey =  "ddgActivityIndicatorARKey";
</code></pre>
<p>This string could be anything. I chose to namespace it with a DDG prefix and role suffix, <code>"ARKey"</code>. Both of these together insure that this symbol will not collide with an Apple name. (As I prefer readability in my code, I chose NOT to namespace the ivar <code>activityIndicator</code> itself. This namespace collision  is a risk I&#8217;m willing to take.) As these accessors apply to the instance, <code>self</code> is the appropriate object to pass to the function. Finally, the memory management policy is defined by a family of self descriptive constants:     <code>OBJC_ASSOCIATION_ASSIGN</code>, <code>OBJC_ASSOCIATION_RETAIN_NONATOMIC</code>, <code>OBJC_ASSOCIATION_COPY_NONATOMIC</code>, <code>OBJC_ASSOCIATION_RETAIN</code>, <code>OBJC_ASSOCIATION_COPY</code>. In the example, I&#8217;ve chosen <code>OBJC_ASSOCIATION_RETAIN_NONATOMIC</code> to match the <code>@property (nonatomic, retain)</code> declaration.</p>
<h3><code>DDGActivity</code> Example Application.</h3>
<p>The example application is based upon Apple&#8217;s single view application template. For clarity and simplicity, most of the template code has been removed. The root view controller, <code>DDGActivityViewController</code>, has just 3 button action methods: <code>-turnOnAction:</code>, <code>-turnOffAction:</code> and <code>-modalViewAction:</code>. The first two toggle the state of the activity indicator and the third, somewhat obviously, shows the modal view.</p>
<p>The modal view exists to show you automatic memory reaping of associated references by the runtime. It does this by not actively releasing the <code>activityIndicator</code> when the modal view is dismissed. All of the memory is automatically reclaimed. No leaks are created. Please verify this by running the app under Instruments&#8217; memory leak tool. The <code>ModalViewController</code> just has two methods: <code>-viewDidLoad</code> and <code>-dismissAction:</code>. They are simple. <code>-viewDidLoad</code>&#8216;s body was copied from <code>-turnOnAction:</code>. <code>-dismissAction:</code> just dismisses itself.</p>
<h3>Licensing</h3>
<p>Even though there is little likelihood that you will copy and past this code directly into your app, it is covered by an attribution required BSD license. If you use this technique, please consider giving me credit in your licenses or credits view. I write these posts to help grow my development consulting business and would appreciate your help.</p>
<h3>Where to get it?</h3>
<p>This code lives up on GitHub at: <a href="http://bit.ly/DDGActivityGH">http://bit.ly/DDGActivityGH</a>. The announcement post to my blog is at: <a href="http://bit.ly/DDGActivity">http://bit.ly/DDGActivity</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ddg.com/?feed=rss2&#038;p=59</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DDGPreferences: A Class for all Settings</title>
		<link>http://blog.ddg.com/?p=53</link>
		<comments>http://blog.ddg.com/?p=53#comments</comments>
		<pubDate>Sat, 27 Aug 2011 15:24:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[DDG]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.ddg.com/?p=53</guid>
		<description><![CDATA[Almost every iOS application has individual user preferences. Some apps also use Apple&#8217;s Settings app, some don&#8217;t. If you develop many different applications, as I do in my development consulting practice, it is tedious to code up a custom preferences class for each app. My class, DDGPreferences, is an attempt to minimize the tedium by [...]]]></description>
			<content:encoded><![CDATA[<p>Almost every iOS application has individual user preferences. Some apps also use Apple&#8217;s Settings app, some don&#8217;t. If you develop many different applications, as I do in my development consulting practice, it is tedious to code up a custom preferences class for each app. My class, <code>DDGPreferences</code>, is an attempt to minimize the tedium by providing a very simple API to the <code>NSUserDefaults</code> class for both settings and custom preferences. In addition to <code>DDGPreferences</code>, I have included a set of standard logging macros, <code>DDGMacros</code>, and an example single view iOS app tying all of the pieces together.</p>
<h2 id="the-api">The API</h2>
<p>I like simple APIs. They are easy to use and easy to share. I wanted this API to be no more than a list of properties. As in:</p>
<pre><code>@interface Preferences : DDGPreferences

@property (nonatomic, copy)   NSString *nameSetting;
@property (nonatomic, assign, getter=isEnabledSetting) BOOL enabledSetting;
@property (nonatomic, assign) CGFloat sliderSetting;

@property (nonatomic, copy)   NSString *namePref;
@property (nonatomic, assign, getter=isEnabledPref) BOOL enabledPref;
@property (nonatomic, assign) CGFloat sliderPref;
@property (nonatomic, retain) NSData *rectPrefData;

@end
</code></pre>
<p>Furthermore, the only difference between whether a property was visible in Apple&#8217;s settings app should be if a key matching its exact name was present in the <code>Root.plist</code> in the <code>Settings.bundle</code>. In other words, each setting has an identifier/key which is identical to a property name. This post is not a tutorial on how to build an app that uses Apple&#8217;s Settings application. That said the example app has only made minor changes to the fields created when you add a <code>Settings.bundle</code> to your app. (In particular, I changed the Key/Identifier from using under bars, _, as word separators to using standard Cocoa camel case.) In other words, I believe a beginner should be able to follow the logic of using this class without too much difficulty.</p>
<h3 id="how-do-you-use-ddgpreferences">How do you use DDGPreferences?</h3>
<p>Using <code>DDGPreferences</code> is simple. Make your Preferences class a subclass of <code>DDGPreferences</code> and then instantiate it. Really, that is all you have to do. Your preferences are limited to those supported by Apple&#8217;s .plist files. This is not as restrictive as it might seem. Later, I&#8217;ll show you how to convert an arbitrary NSCoding compliant class to a preference.</p>
<p>If you have default preference values which are different from the state of a freshly initialized object, then you must implement the <code>DDGPreferences</code> protocol&#8217;s single method, <code>-setDefaultPreferences</code>. The example application has this method.</p>
<p>What about synchronizing changes between Apple&#8217;s Settings app and yours while the app is in the background? When your app returns to the foreground, I recommend you read/write the Settings managed values in response to the <code>UIApplicationDidBecomeActiveNotification</code>, <code>UIApplicationWillResignActiveNotification</code> notification pair. The example app shows one way to do this. All other coordination with the Settings app is handled by <code>DDGPreferences</code>.</p>
<h3 id="the-ddgpreferences-app">The DDGPreferences app:</h3>
<p>I&#8217;ve included an app showing how to use <code>DDGPreferences</code>. It is a single view iPhone app with an array of identical controls for both Apple&#8217;s Settings app and the <code>DDGPreferences</code> app. You can change the preferences for the settings in both apps and they transfer bi-directionally. A simple <code>CGRect</code> is also initialized and stored. It is then displayed in a UILabel. How to store a complex structure, such as a <code>CGRect</code>, is described below. Traditionally, your preferences are stored with your application singleton. In this example, for pedagogical simplicity, I store them in the root view controller.</p>
<h3 id="saving-complex-classes">Saving complex classes:</h3>
<p>This is an advanced technique and, if you can, I recommend that you avoid using it. Any <code>NSCoding</code> compliant class can be stored, with care, in <code>DDGPreferences</code>. As <code>DDGPreferences</code> uses the properties to determine what needs to be persisted, you cannot just define a <code>@property</code> for your class that is not one of those supported by Apple&#8217;s .plist format; you need to define an <code>NSData</code> typed instance variable to hold an archived instance of your class/structure. In the example, <code>rectPrefData</code> is that property. To access this data as your preferred type, you need to define &#8220;old school&#8221; Objective-C v1 style accessors. In the example, these are <code>-rectPref</code>/<code>-setRectPref:</code>. Somewhat obviously, these accessors will use rectPrefData to store the value. A example implementation of these methods is:</p>
<pre><code>- (CGRect) rectPref {

    return [[NSKeyedUnarchiver unarchiveObjectWithData:
             self.rectPrefData] CGRectValue];

} // -rectPref

- (void) setRectPref: (CGRect) rect {

    self.rectPrefData = [NSKeyedArchiver archivedDataWithRootObject:
                         [NSValue valueWithCGRect: rect]];
} // -setRectPref:
</code></pre>
<p>They work by taking your <code>NSCoding</code> compliant class and archiving it using the <code>NSKeyedArchiver</code>/<code>NSKeyedUnarchiver</code> classes. The above methods, for pedagogical purposes, are not key-value coding compliant.</p>
<h3 id="licensing">Licensing:</h3>
<p><code>DDGPreferences</code> is covered under a public attribution required version of the new BSD license. Why do I require that you acknowledge me publicly in your app? Similarly to many other developers, I make my code available under an open source license as an advertisement for my development consulting services. Hence, I need to be able to easily point to applications that use my code. While it is not necessary, I would appreciate it if you also sent me an email saying in which apps you use <code>DDGPreferences</code>.</p>
<p>From my experience making other code available under an open source license, some folks will write asking to be relieved of my public recognition requirement. Unless the requestor is willing to compensate me to change the licensing terms, I will always decline to change my agreement. I have put some time and care into crafting this class, app and this blog post. That time deserves compensation. I have chosen to be compensated by using this class as a marketing mechanism. I apologize if this does not align with your open source values. I have a family to feed and a mortgage to service. I sell coding services and code to provide for all of us. I hope you understand.</p>
<h3 id="where-to-get-the-code">Where to get the code:</h3>
<p>This code is available from GitHub at this URL: &lt;<a href="https://github.com/adonoho/DDGPreferences">https://github.com/adonoho/DDGPreferences</a>&gt;. I will be tracking comments at both GitHub and this post on my personal blog, &lt;<a href="http://blog.ddg.com/?p=53">http://blog.DDG.com/?p=53</a>&gt;. I, of course, encourage you to send in bug fixes and make suggestions to improve <code>DDGPreferences</code> for all of us.</p>
<p>I hope you find <code>DDGPreferences</code> useful.</p>
<p>In a future post for advanced programmers, I will describe how <code>DDGPreferences</code> functions.</p>
<h3 id="acknowledgements">Acknowledgements:</h3>
<p>I would like to thank Scott Gustafson and Mason Weems for their suggestions and support. Also, Austin&#8217;s local Mac OS X/iOS developer group, Cocoa Coders, organized by Jim Hillhouse and Rajat Datta, has been extremely helpful in my return to software engineering.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ddg.com/?feed=rss2&#038;p=53</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Core Data Lessons Learned.</title>
		<link>http://blog.ddg.com/?p=51</link>
		<comments>http://blog.ddg.com/?p=51#comments</comments>
		<pubDate>Thu, 02 Sep 2010 13:47:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.ddg.com/?p=51</guid>
		<description><![CDATA[The lessons I&#8217;ve learned about using CD are pretty simple. 1) Retain the minimum CD items as necessary to run your app. The CD row cache and fetch requests appear to be quite performant. Rebuilding fetches allows the system to dump memory as needed. 2) -save: is your friend. -save: early and often. Sometimes this [...]]]></description>
			<content:encoded><![CDATA[<p>The lessons I&#8217;ve learned about using CD are pretty simple.</p>
<p>1) Retain the minimum CD items as necessary to run your app. The CD row cache and fetch requests appear to be quite performant. Rebuilding fetches allows the system to dump memory as needed.</p>
<p>2) <tt>-save:</tt> is your friend. <tt>-save:</tt> early and often. Sometimes this will hit your UI&#8217;s responsiveness. It&#8217;s OK. In particular, you should -save: before starting background operations. Frequent <tt>-save:</tt>&#8216;s mean that each one is a fast operation.</p>
<p>3) The fetched results controller is &#8220;new&#8221; code. It has surprising performance &#8220;gotchas&#8221; and section update bugs. In particular, you should dump it at the first sign of memory pressure. You can recreate it simply. Block oriented fetches are quick.</p>
<p>4) It really helps to go though your program early in a memory warning and dump CD items. Your root view controllers appear to get first crack at dumping memory. If at all possible, do it there. It isn&#8217;t clear whether CD gets a chance to dump it&#8217;s caches before your <tt>-applicationDidReceiveMemoryWarning:</tt> gets called. When it did, I then frequently saw a UI-locking loop into the fetched results controller. Also, call <tt>-save:</tt> in each memory warning routine. If you are observing NSManagedObjectContextDidSaveNotification, it creates a potential dirty loop; KVO observers get fired as the save progresses.</p>
<p>5) The predicate documentation is wholly inadequate. Yes, it is a complete reference. Yet, it is useless as a learning document. The &#8220;CD Programming Guide&#8221; is much better. The predicate guide needs as thorough a treatment. (Apple is not alone in this lack, one well known book addresses predicates in 3/4 of one page. I feel like such a sucker buying a DB book that doesn&#8217;t cover the query language.) For example, I spent a great deal of time banging my head against the fetching limitations of the fetch request. (Of course, if you use a fetched results controller, you have no choice. There is a great need for a block/handler controller.) There are no good examples of the idioms involved with using this predicate language. In particular, when I need to start using text searching, there is little discussion of how the regex engine interacts with the object graph and the row cache.</p>
<p>6) There are surprising interactions between your foreground and background contexts. They can be handled with careful model design and instantiation order. While I don&#8217;t think Apple should necessarily document these kinds of problems, some discussion of CD model design guidelines would be helpful. CD is a different way to think about a data model. Apple needs, IMO, to help folks get their heads around the differences.</p>
<p>While you might think that all of my suffering with CD would cause me to walk away from the technology, I&#8217;m leaning the other way. As I&#8217;ve now crossed a competence threshold, I am seeing good benefits from using an object graph instead of a SQL model. For example, I have a recursive algorithm. Recursive SQL appears to be it&#8217;s own special hell. The object graph makes it easy and handles cycles well. While I doubt there is a performance issue, I can pre-fill the row caches with a single fetch request. In addition, my algorithms are well served by object graphs.</p>
<p>The above said, I wish that learning this technology was as straightforward as learning the rest of Cocoa/Cocoa Touch. Apple could do better here.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ddg.com/?feed=rss2&#038;p=51</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DNS-SD Configuration &#8220;Gotcha&#8221;</title>
		<link>http://blog.ddg.com/?p=40</link>
		<comments>http://blog.ddg.com/?p=40#comments</comments>
		<pubDate>Sun, 03 Jan 2010 19:53:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[DDG]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.ddg.com/?p=40</guid>
		<description><![CDATA[weLost™ uses DNS-SD, DNS Service Discovery, to bootstrap the location of its social network servers. While this was a good idea, it had a very subtle &#8220;gotcha&#8221; in its configuration. The basic configuration instructions are described here in: Static Server Setup. If you do not intend to support browsing for your resources, then things are [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://welosttogether.com/">weLost™</a> uses DNS-SD, DNS Service Discovery, to bootstrap the location of its social network servers. While this was a good idea, it had a very subtle &#8220;gotcha&#8221; in its configuration. The basic configuration instructions are described here in: <a href="http://www.dns-sd.org/ServerStaticSetup.html">Static Server Setup</a>. If you do not intend to support browsing for your resources, then things are even simpler but there is still that pesky &#8220;gotcha&#8221;. To support direct access you only need to implement the third set of DNS records. The one&#8217;s labeled: &#8220;SRV &#038; TXT records describing each service entity named above&#8221;. </p>
<p>If my experience with the iPhone is a guide, the TXT record is not optional. Every service you query MUST have a TXT record. In my case, I neglected to set the TXT record for my narrow web HTTP server. This caused every NSNetService query to timeout. Solving this problem was simple, I entered &#8220;txtvers=1&#8243; as the body (minus the quote marks) for the TXT record. This is a default version of the format of all DNS-SD TXT records. There are other values you could use, particularly for HTTP, but this one is both innocuous and sufficient.</p>
<p>Enjoy and Anon,<br />
Andrew</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ddg.com/?feed=rss2&#038;p=40</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Network Reachability</title>
		<link>http://blog.ddg.com/?p=24</link>
		<comments>http://blog.ddg.com/?p=24#comments</comments>
		<pubDate>Mon, 28 Dec 2009 20:13:37 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[DDG]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.ddg.com/?p=24</guid>
		<description><![CDATA[If you write an iPhone application that uses the network, then you must check if the network is both operating and that your server is reachable. Apple has and will continue to reject applications that do not test reachability. To this end, Apple provides iPhone developers a sample application and class, Reachability, that can easily [...]]]></description>
			<content:encoded><![CDATA[<p>If you write an iPhone application that uses the network, then you must check if the network is both operating and that your server is reachable. Apple has and will continue to reject applications that do not test reachability. To this end, Apple provides iPhone developers a sample application and class, <a href="http://developer.apple.com/iphone/library/samplecode/Reachability/">Reachability</a>, that can easily be used to perform these tests. While the 2.0 version of this code is much better than v1.5, it is still quite raw. (For example, there is a bare <tt>[super init];</tt> in a class method [line 175 in Reachability.m]. It does nothing. It also has two routines with misspellings in their names: <tt>-startNotifer/-stopNotifer</tt> should be <tt>-startNotifier/-stopNotifier</tt>) To me, these are signs of raw code. To remedy this, I have significantly reengineered this class.</p>
<p>I had three goals when starting this process. First, I wanted to understand how to use this code. It isn&#8217;t at all apparent how these routines should be used. What order should they be called in and what do the various tests and values mean? Second, my scan of the code convinced me that it was written by a low level network engineer. They had made implementation decisions that were not terribly friendly to using it in a Cocoa Touch program. I wanted a class that fit in with my coding style. Third, because the core network testing routine <tt>-networkStatusForFlags:</tt> was not, in my opinion, clear, I did not feel comfortable shipping it in my app, weLost™. I wanted to have confidence in this code.</p>
<p>This class has two important features: network status transition notifications and easy reachability testing for each server your app touches. Because radios lose connections all of the time, these dynamic notifications help your user understand why they cannot use the networking features of your app. </p>
<p>When I start my app, the first Reachability method I use creates a <tt>Reachability</tt> instance for the network itself, <tt>+(Reachability *) reachabilityForInternetConnection;</tt>. This tests the hardware and can immediately provide you with the current network status. Because this reachability test doesn&#8217;t leave the phone, there is no network latency. Because hostname reachability instances must resolve your host&#8217;s name into an IP address, they are asynchronous. The immediately returned status is that your host is not reachable. (Bear in mind that the subsystem underlying Reachability, <tt>SCNetworkReachability</tt>, does not actually try to send a packet to your host. It only really knows the state of the radios and whether IP addresses have been allocated for the phone and that your host&#8217;s name has resolved into an IP address.)</p>
<p>These Reachability instances do not start notifying you of network transitions upon instantiation. You must turn this on. Before turning on the notifications, I like to register for them. The notification name in the default notification center is: <tt>kReachabilityChangedNotification</tt>. When your registered method is called, the notification&#8217;s <tt>object</tt> will be the Reachability instance with the changed status. For example, you might register this method:</p>
<p><tt>-(void) networkReachabilityEvent: (NSNotification *) notification;</tt></p>
<p>with the notification center. When it is called for a status change, the Reachability instance is recovered with this line of code:
<p><tt>Reachability *r  = [notification object];</tt></p>
<p> A Reachability instance&#8217;s notifications are initiated, unsurprisingly, with the <tt>-startNotifier</tt> method.</p>
<p>Now that you can track gross network transitions, you need to create Reachability instances for each host. In weLost&#8217;s case, I track 4 different servers. I use:
<p><tt>+(Reachability *) reachabilityWithHostName: (NSString*) hostName;</tt></p>
<p> to create these instances. These host names must be resolved into addresses before the instance is reachable. (A notification, if you&#8217;ve turned them on for this instance, is issued when the resolution is finished.) </p>
<p>This class can be used both synchronously and asynchronously. Typically, you will make synchronous queries of the Reachability instance passed to you after a network status transition. You may also want to do a synchronous test before opening a new view which connects to your host. (One advantage of creating all of your Reachability instances at startup, i.e. before you need them, is that their name resolution does not delay your later network accesses.) My version of Reachability has more methods for synchronously testing network status than Apple&#8217;s. Their version also has mixed some tests, such as whether user intervention is required, into the network status method which I think should not be there. I have cracked them out into separate methods. Here are the kinds of network tests you can perform:</p>
<ul>
<li>Test whether this Reachability instance is of interest.</li>
<li>If so, then test what kind of network transition it is:
<ul>
<li>Is the host reachable? <tt>-(BOOL) isReachable;</tt></li>
<ul>
<li>Is the connection up? <tt>-(BOOL) isConnectionRequired;</tt></li>
<ul>
<li>Will it come up automatically? <tt>-(BOOL) isConnectionOnDemand;</tt></li>
<li>Will the user have to enter a password? <tt>-(BOOL) isInterventionRequired;</tt></li>
</ul>
<li>Is the connection slow? <tt>-(BOOL) isReachableViaWWAN;</tt></li>
<li>Is the connection fast? <tt>-(BOOL) isReachableViaWiFi;</tt></li>
</ul>
</ul>
</li>
</ul>
<p>How do you determine if a Reachability instance is of interest? You check its key &#8212; a hostname or a dotted quad IP address or one of two constants: <tt>kInternetConnection</tt> or <tt>kLocalWiFiConnection</tt>. This is a big change from Apple&#8217;s code. I keep a key, an NSString, along with the <tt>SCNetworkReachabilityRef</tt>. Apple just keeps a boolean and the <tt>SCNetworkReachabilityRef</tt>. In other words, I make it easy to use Reachability instances in complex Cocoa data structures. I&#8217;m sure Apple&#8217;s engineer would argue that pointer comparisons are sufficient to determine one&#8217;s interest in a notification. That doesn&#8217;t mean it is a particularly useful mechanism in a Cocoa program. Also, Apple&#8217;s boolean is used just to differentiate one instance type, <tt>kLocalWiFiConnection</tt>, from all of the other types. While this is useful to the internal functioning of Apple&#8217;s code, it isn&#8217;t particularly useful to a client of the class. I provide a convenience method, <tt>-isEqual:</tt>, to compare Reachability instances. To a Cocoa Touch programmer, a key is just more flexible.</p>
<p>Your decision tree to interpret network status transitions is, of course, idiosyncratic to your application. However, there are issues to consider based upon your connection. After you have determined whether your host is reachable, is the network active and connected? For example, if you are connected via the EDGE/3G wireless wide area network (WWAN), your network is always reachable but it may not be active. You start the radios by trying to connect to your host. I have seen this process take tens of seconds. Does your user need to know this? If you are connected via WiFi and if a user must enter a password, you may choose not to connect to the network. If you&#8217;ve transitioned from WiFi to WWAN, does the user need to know that things are much slower or they may have lower resolution media? And the converse? Do you enable more features when the network transitions to WiFi from WWAN? And what, exactly, do you do when there is a repeated network flap between WiFi and WWAN? What do you do when your app is brought out of sleep in a new venue? What do you tell your user? You will get a notification for each of these situations.</p>
<p>There are two Reachability instances I have neglected &#8212; <tt>-reachabilityWithAddress:</tt> and <tt>-reachabilityForLocalWiFi</tt>. <tt>-reachabilityWithAddress:</tt> takes an internet IP/socket address and can be queried immediately for its status. Its key is a dotted quad IP address, such as <tt>@"127.0.0.1"</tt>. The <tt>-reachabilityForLocalWiFi</tt> instance is a bit more subtle. It tests for a WiFi connection using an automatic private IP address, <tt>169.254.0.0</tt>. If this network is reachable, then your network is active but not routable. Some services, such as Bonjour, will still function fine in this case but not much else. I have not found any use for this instance type. Yet I have preserved Apple&#8217;s test criteria for this instance in my code. Perhaps it is of use to you.</p>
<p>Before using my extensions you should probably ask: how compatible is this stack with Apple&#8217;s? My answer is: very. My code is a superset of Apple&#8217;s API. Other than Apple&#8217;s misspelled method names, my code will be a drop in replacement for Apple&#8217;s class. It has, as far as I&#8217;ve been able to test, identical behavior. My network status test is different. It is supported by empirical observations of the status flags. Because it does not conflate a test for whether a user&#8217;s intervention is required with the basic reachability, my network status test is simpler. Nonetheless, if you do not wish to use my extensions, I provide a <tt>#define DDG_EXTENSIONS</tt> to enable easy comparisons between the two network status policies in your application. Both classes employ <tt>NSAssert</tt> and <tt> NSCAssert.</tt> This is aligned with the Cocoa policy to throw exceptions during development to catch programmer errors. These exceptions can be turned off by defining <tt>NS_BLOCK_ASSERTIONS</tt> during your release builds. Finally, I support a conditionally compiled logging system. To turn it on you need to <tt>#define CLASS_DEBUG</tt> in the class header and <tt>#define DEBUG</tt> for the debug builds of your app. Then both the <tt>-description</tt> method and synchronous logging are turned on. My log entries also list the method name and line number of the source code. Class logging is turned on by default.</p>
<p>This class is packaged in a <tt>.zip</tt> file here: <a href="http://blog.ddg.com/wp-content/uploads/blog.ddg.com/2010/02/Reachability-2.0.4ddg1.zip" title="Reachability 2.0.4ddg1.zip">Reachability 2.0.4ddg.zip</a>. It has two directories: Reachability itself and my version of Apple&#8217;s Reachability project. These extensions to Apple&#8217;s class are covered by the new BSD license. Hence, if you use my version, I require a public acknowledgement of my contributions in your application.</p>
<p>I hope you find this version of Reachability useful. May your code compile without errors and run like the wind.</p>
<p><strong>NOTE:</strong> Allen Brunson found a memory leak in Reachability. This has been corrected and a new version generated, 2.0.2ddg, and placed at the link above.</p>
<p><strong>NOTE:</strong> Ling Wang suggested an additional test for a WiFi+VPN condition. This has been added and a new version generated, 2.0.3ddg, and placed at the link above.</p>
<p><strong>NOTE:</strong> After complaints about my added NSAssert in the -networkStatusForFlags: method, I have now surrounded the assert with a conditional compile macro. This change has been added and a new version generated, 2.0.4ddg, and placed at the link above.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ddg.com/?feed=rss2&#038;p=24</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQLite Persistent Objects</title>
		<link>http://blog.ddg.com/?p=21</link>
		<comments>http://blog.ddg.com/?p=21#comments</comments>
		<pubDate>Fri, 23 Oct 2009 15:22:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[DDG]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.ddg.com/?p=21</guid>
		<description><![CDATA[I use Jeff LaMarche&#8217;s and his contributor&#8217;s SQLite Persistent Objects library in my upcoming iPhone application. This library was created before version 3 of the iPhone OS was released. Because iPhone OS v3 contained Core Data, Jeff and his contributors ceased further development. Yet, I was dependent on it and, hence, I continued private development. [...]]]></description>
			<content:encoded><![CDATA[<p><STYLE type="text/css"><br />
<!--<br />
.code { font-family: monospace; font-style: normal }<br />
--><br />
</STYLE></p>
<p>I use Jeff LaMarche&#8217;s and his contributor&#8217;s SQLite Persistent Objects library in my upcoming iPhone application. This library was created before version 3 of the iPhone OS was released. Because iPhone OS v3 contained Core Data, Jeff and his contributors ceased further development. Yet, I was dependent on it and, hence, I continued private development.</p>
<p>My changes were primarily performance enhancements and some reorganization of the main header files to support better life cycle management of the databases. In particular, I added a static variable to hold a static <span class="code">NSDateFormatter</span>. (An <span class="code">NSDateFormatter</span> is surprisingly expensive to create on each SQLite transaction involving a time stamp.) I also defined a new mechanisms to hold the <span class="code">propertiesWithEncodedTypes</span> as a class static. These properties are static with respect to each class. Hence, caching the dictionary, which is used on almost every call to the class, is an excellent performance enhancement.</p>
<p>To use this new feature to optimize your classes, you need to override <span class="code">+propertiesWithEncodedTypes</span>. Here is the code your need to place in your class:</p>
<pre>
+ (NSDictionary *) propertiesWithEncodedTypes {

	static NSDictionary *classProperties = nil;

	if (classProperties == nil) {

		// Because it is stored in a static, we must retain it.
		classProperties = [[self propertiesWithEncodedTypes_] retain];

	}

	return classProperties;

} // propertiesWithEncodedTypes
</pre>
<p>Due to these enhancements this library is not thread safe. Because there are other static variables sprinkled throughout the code, which also preclude thread safety, this is not a change in the library&#8217;s lack of thread safety.</p>
<p>The license agreement used by this project was legally dubious. With Mr. LaMarche&#8217;s formal agreement via email, as the voice of the project, I have edited each project file to be covered by the OSI approved New BSD license. This license, while supporting the values expressed by Jeff during the creation of the project, adds liability protection to each contributor and formally defines the criteria to use the code. Let me be clear, each contributor was facing an unspecified legal liability under the old license. They are now protected. I contribute my changes to this code under the below license.</p>
<p>I hope you find my changes useful and the license agreement a legal improvement. Here is a <a href="http://blog.ddg.com/wp-content/uploads/blog.ddg.com/2009/10/091023-SQLite-Persistent-Objects.zip" title="091023 SQLite Persistent Objects.zip">link</a> to a zip of the archive, 091023 SQLite Persistent Objects.zip. And a <a href="http://www.slideshare.net/360conferences/using-sqlite">link</a> to Jeff&#8217;s extremely useful presentation at the 360 iDev Conference. </p>
<p>Enjoy and Anon,<br/><br />
Andrew</p>
<hr/>
<p>SQLite Persistent Objects for Cocoa and Cocoa Touch.</p>
<p>Copyright (c) 2008 &#8211; 2009,<br />
Jeff LaMarche, <jeff_lamarche@mac.com><br />
All rights reserved.</p>
<p>Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:</p>
<p>* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.</p>
<p>* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.</p>
<p>* Neither the name of Jeff LaMarche nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.</p>
<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &#8220;AS IS&#8221; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ddg.com/?feed=rss2&#038;p=21</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RHView and Delegate Drawing&#8230;</title>
		<link>http://blog.ddg.com/?p=16</link>
		<comments>http://blog.ddg.com/?p=16#comments</comments>
		<pubDate>Sun, 11 Oct 2009 00:09:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.ddg.com/?p=16</guid>
		<description><![CDATA[The delegate drawing pattern implemented by a RHView is not a decorator pattern. It is a simple delegate pattern. I intend you, though, to use it somewhat differently than a traditional delegate. A traditional delegate would be responsible for drawing directly in the RHView. And, of course, you can use it that way. I use [...]]]></description>
			<content:encoded><![CDATA[<p>The delegate drawing pattern implemented by a <span style="font-family: monospace; font-style: normal">RHView</span> is not a decorator pattern. It is a simple delegate pattern. I intend you, though, to use it somewhat differently than a traditional delegate. A traditional delegate would be responsible for drawing directly in the <span style="font-family: monospace; font-style: normal">RHView</span>. And, of course, you can use it that way. I use it differently though.</p>
<p>I create all of my drawing commands as methods of the <span style="font-family: monospace; font-style: normal">RHView</span>. This allows complex graphics commands to be encapsulated in the view. The delegate becomes a drawing coordinator and does not a directly draw in the view. </p>
<p>Here is a simple example &#8212; a subclass of <span style="font-family: monospace; font-style: normal">RHView</span> to draw a graph:</p>
<pre>
#import "RHView.h"<br/>
@class Curve;<br/>
@interface GraphView : RHView {<br/>
@private
    Curve *curve;
}<br/>
@property (retain, nonatomic) Curve *curve;<br/>
- (void) drawBorder: (CGRect) rect inContext: (CGContextRef) context;
- (void)  drawCurve: (CGRect) rect inContext: (CGContextRef) context;<br/>
@end
</pre>
<p>It has a single instance variable &#8212; a <span style="font-family: monospace; font-style: normal">curve</span>. And it has two drawing methods &#8212; <span style="font-family: monospace; font-style: normal">-drawBorder:inContext:</span> and <span style="font-family: monospace; font-style: normal">-drawCurve:inContext:</span>. The delegate object only needs to implement the <span style="font-family: monospace; font-style: normal">RHViewDelegate</span> protocol. </p>
<p>Here is a sample delegate implementation:</p>
<pre>
- (void) drawView: (GraphView *) view inRect: (CGRect) rect inContext: (CGContextRef) context {<br/>
    [view  drawCurve: rect inContext: context];
    [view drawBorder: rect inContext: context];<br/>
}
</pre>
<p>All drawing commands are encapsulated in the subclass of <span style="font-family: monospace; font-style: normal">RHView</span>. Your view controller is, in my opinion, the natural delegate of the <span style="font-family: monospace; font-style: normal">RHView</span>. You then just create new view controllers to coordinate the new behavior. It is totally congruent with the MVC pattern. </p>
<p>This pattern really cleaned up my code. I hope it cleans yours up too.</p>
<p>An aside: the <span style="font-family: monospace; font-style: normal">RHViewDelegate</span> is the key mechanism needed to initiate a decorator drawing pattern.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ddg.com/?feed=rss2&#038;p=16</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coordinate Systems and the iPhone&#8230;</title>
		<link>http://blog.ddg.com/?p=10</link>
		<comments>http://blog.ddg.com/?p=10#comments</comments>
		<pubDate>Sun, 06 Sep 2009 18:18:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.ddg.com/?p=10</guid>
		<description><![CDATA[Interesting iPhone apps draw custom views/widgets. Every platform though makes assumptions that will be good for some applications and bad for others. As the Mac OS X evolved into iPhone OS, one of the graphics assumptions changed &#8212; the handedness of the drawing coordinate system. In Mac OS X&#8217;s case, the right handed coordinate system [...]]]></description>
			<content:encoded><![CDATA[<p>Interesting iPhone apps draw custom views/widgets. Every platform though makes assumptions that will be good for some applications and bad for others. As the Mac OS X evolved into iPhone OS, one of the graphics assumptions changed &#8212; the handedness of the drawing coordinate system. In Mac OS X&#8217;s case, the right handed coordinate system was a natural match to traditional graphing which we all learned in high school algebra. iPhone OS uses a left handed coordinate system. The left handed system is very good for drawing text. The big difference is in the direction of the y-axis. In a right handed system, the y-axis points up; a left handed y-axis points down. If you want to draw scatter plots, then a right handed system is just easier to use.</p>
<p>The graphics system is called Quartz 2D. It supports general purpose transformations of every graphics action. This is how the handedness can switch between the Mac and the iPhone &#8212; Quartz 2D made it easy. Hence, to return to a right handed system, we need to use this transformation system to flip the coordinate system. We will also need to move the origin of the view from the top-left to the bottom-left corner. Two tasks: flip the coordinate system and translate the origin.</p>
<p>Each view in Cocoa Touch draws in exactly one method: <span style="font-family: monospace; font-style: normal">-drawRect:</span>. Our code needs to intercept this method and transform the coordinate system. Also, because there is a common design pattern in Cocoa Touch, delegation, we should support that too. Finally, because of the ways views are implemented in Cocoa Touch, as <span style="font-family: monospace; font-style: normal">CALayer</span>s, our class needs to provide some methods to make it easy for layers to be rendered in our new coordinate system.</p>
<p>Two tasks:</p>
<ul>
<li>Flip the coordinate system.</li>
<li>Translate the origin.</li>
</ul>
<p>Three requirements:</p>
<ul>
<li>Intercept -drawRect:</li>
<li>Implement a delegate pattern.</li>
<li>Provide a utility method for layer drawing.</li>
</ul>
<h4>The Right Hand View Header:</h4>
<pre>
@interface RHView : UIView {
@private
	id &lt;RHViewDelegate&gt; delegate;
}
@property (assign, nonatomic) id &lt;RHViewDelegate&gt; delegate;<br/>
// Abstract methods. This must be overridden.
- (void) drawRect: (CGRect) rect inContext: (CGContextRef) context;<br/>
// Concrete methods.
- (CGContextRef) flipContext: (CGContextRef) context;
@end
</pre>
<h4>Starting at the top:</h4>
<p>This class inherits from <span style="font-family: monospace; font-style: normal">UIView</span>, the standard parent class to all views in Cocoa Touch. It&#8217;s only instance variable is a pointer to a delegate that implements the <span style="font-family: monospace; font-style: normal">RHViewDelegate</span> protocol. As with almost all other delegate instance variables in Cocoa Touch, the delegate is assigned and not retained. It is up to the delegate to keep from being reaped.</p>
<p>This class has two public methods. The first method, <span style="font-family: monospace; font-style: normal">-drawRect:inContext:</span>, is an abstract method. It must be overridden by your subclass to draw anything. Or you must use the delegate. You cannot use both at the same time.</p>
<p>The second method, <span style="font-family: monospace; font-style: normal">-flipContext:</span>, is a utility method to transform a graphics context between coordinate systems. You should not override this method.</p>
<p>The alternate way to draw is with a delegate that implements the <span style="font-family: monospace; font-style: normal">RHViewDelegate</span> protocol. </p>
<pre>
@protocol RHViewDelegate
@required<br/>
// Draw contents into the given view, using the given bounds and context.
- (void) drawView: (RHView *) view inRect: (CGRect) rect inContext: (CGContextRef) context;<br/>
@end
</pre>
<p>Because a delegate is unrelated to the view, you need to pass the view to the delegate along with the rectangle that needs to be filled in and the flipped context: <span style="font-family: monospace; font-style: normal">-drawView:inRect:inContext:</span>.</p>
<h4>How does RHView work?:</h4>
<p>I&#8217;ll start with simpler of the 2 methods: <span style="font-family: monospace; font-style: normal">-flipContext:</span>.</p>
<pre>
- (CGContextRef) flipContext: (CGContextRef) context {

    // Get the current transformation matrix.
    CGAffineTransform ctm = CGContextGetCTM(context);

    // Toggle the origin's position between the bottom-left and top-left.
    CGAffineTransformTranslate(ctm, 0.0, self.bounds.size.height);

    // Flip the handedness of the coordinate system.
    CGAffineTransformScale(ctm, 1.0, -1.0);

    // Apply the new coordinate system to the CGContext.
    CGContextConcatCTM(context, ctm);

    return context;

} // flipContext:
</pre>
<p>This method is rather straightforward. It implements our two tasks: flipping and translation. The key thing to recognize is that the new origin is always at the &#8220;top&#8221; of the current view. In a left handed system, the top-left point is the same as the bottom-left of a right handed system. And this is true, vice versa. The second transform, the <span style="font-family: monospace; font-style: normal">CGAffineTransformScale</span>, changes the sign of the y-axis. It changes the handedness of the system. That really is all that is required.</p>
<p>The <span style="font-family: monospace; font-style: normal">RHView -drawRect:</span> method has to do both the transformation and delegate dispatch. Unlike a normal UIView, you do not override <span style="font-family: monospace; font-style: normal">-drawRect:</span>. Because it is responsible for managing the coordinate system, it has to get the first crack at drawing the view. Hence, you need to override the <span style="font-family: monospace; font-style: normal">-drawRect:inContext:</span> method. The only difference between the two methods is that you will use the provided context instead of the default context. Other than that, everything about the new method is treated identically to the classical <span style="font-family: monospace; font-style: normal">-drawRect:</span> method. (A note: <span style="font-family: monospace; font-style: normal">-drawRect:inContext:</span> is using the same naming pattern as <span style="font-family: monospace; font-style: normal">CALayer</span>&#8216;s delegate method <span style="font-family: monospace; font-style: normal">-drawLayer:inContext:</span>.)</p>
<pre>
- (void) drawRect: (CGRect) rect {

    // Convert the coordinate system to be what Quartz 2D expects.
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGAffineTransform ctm = CGContextGetCTM(context);

    // Translate the origin to the bottom left.
    CGAffineTransformTranslate(ctm, 0.0, self.bounds.size.height);

    // Flip the handedness of the coordinate system back to right handed.
    CGAffineTransformScale(ctm, 1.0, -1.0);

    // Convert the update rectangle to the new coordiante system.
    CGRect xformRect = CGRectApplyAffineTransform(rect, ctm);

    // Apply the new coordinate system to the CGContext.
    CGContextConcatCTM(context, ctm);

    if (delegate != nil) {
        // The delegate gets the first crack at rendering the view.
        [delegate drawView: self inRect: xformRect inContext: context];
    } else {
        [self drawRect: xformRect inContext: context];
    }
} // drawRect:
</pre>
<p><span style="font-family: monospace; font-style: normal">-drawRect:</span> has to do four tasks: 1) get the current graphics context; 2) translate and flip the coordinate system; 3) transform the drawing rectangle; 4) dispatch to either the delegate or subclass.</p>
<h4>Getting the Code:</h4>
<p>I&#8217;ve released this code into the public domain.<br />
It is available here: <a href="http://blog.ddg.com/wp-content/uploads/blog.ddg.com/2009/09/RHView.zip" title="RHView.zip">RHView.zip</a>.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ddg.com/?feed=rss2&#038;p=10</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

