<?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>Tao Effect Blog &#187; Cocoa</title>
	<atom:link href="http://www.taoeffect.com/blog/category/cocoa/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.taoeffect.com/blog</link>
	<description>Notice the Tao Effects...</description>
	<lastBuildDate>Sun, 29 Aug 2010 16:04:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>The Ultimate Test Machine Saga</title>
		<link>http://www.taoeffect.com/blog/2010/06/the-ultimate-test-machine-saga/</link>
		<comments>http://www.taoeffect.com/blog/2010/06/the-ultimate-test-machine-saga/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 06:46:49 +0000</pubDate>
		<dc:creator>Greg Slepak</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[greg]]></category>
		<category><![CDATA[macbook pro]]></category>
		<category><![CDATA[pain]]></category>
		<category><![CDATA[quad-boot]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.taoeffect.com/blog/?p=2129</guid>
		<description><![CDATA[So, you want to quad-boot your Mac? What could possibly go wrong? This post explores that question. Motivation After upgrading to the latest Unibody, I decided to turn my old MacBook Pro into the ultimate testing environment. My goal was to be able to test and develop software for Tiger, Leopard, Snow Leopard, Windows XP, [...]]]></description>
			<content:encoded><![CDATA[<p><center>
<div class="img"><a href="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/QuadBootingMac.jpg" class="fancybox"><img src="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/QuadBootingMac_thumb.jpg" alt="Quad-Booting Mac" title="Quad-Booting Mac" width="500" height="375" class="alignnone size-full wp-image-2197" /></a></div>
<p></center></p>
<p>So, you want to quad-boot your Mac? What could possibly go wrong?</p>
<p>This post explores that question.</p>
<h4>Motivation</h4>
<p>After upgrading to the latest Unibody, <a href="http://twitter.com/taoeffect/status/15895736075" target="_blank">I decided</a> to turn my old MacBook Pro into the ultimate testing environment. My goal was to be able to test and develop software for Tiger, Leopard, Snow Leopard, Windows XP, and possibly other operating systems in the future (Windows 7, Ubuntu, etc., although that might require <a href="http://www.gnu.org/software/grub/">Grub</a>).</p>
<h4>Setting Up The Partitions</h4>
<p>I originally thought this entire process would be a simple matter of creating partitions and installing each OS on its respective partition (Hah!). The plan was to use iPartition to create this setup without erasing my Snow Leopard install:</p>
<p><center><a href="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/PerfectTestMachine.png" class="fancybox"><img src="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/PerfectTestMachine_thumb.png" alt="Perfect Test Machine" title="Perfect Test Machine" width="500" height="380" class="alignnone size-full wp-image-2198"  /></a></center></p>
<p>To do this, I had to first run iDefrag (also made by <a href="http://www.coriolis-systems.com/" target="_blank">Coriolis Systems</a>) to compact the Snow Leopard install. Then I could non-destructively resize its partition and add the rest.</p>
<p>iPartition wasn&#8217;t able to create an NTFS partition so I left the Windows partition unformatted, everything else was formatted as HFS+, journaled.</p>
<p>I had saved a Windows install using <a href="http://www.twocanoes.com/winclone/">Winclone</a>, so I went to try to restore that. That failed because Winclone needs the partition to be formatted first.</p>
<p>I tried using Boot Camp Assistant (BCA) to create the NTFS partition, but BCA greeted me with this error (for the Googlers): &#8220;The startup disk cannot be partitioned or restored to a single partition.&#8221;</p>
<p>To get around this error you probably <i style="color:inherit">could</i> use iPartition to create a single HFS+ partition and install Snow Leopard on it. You would need to use iPartition because iPartition lets you create partitions while leaving free space on the drive, and remember, we need that space to create additional partitions for the other operating systems. Disk Utility cannot leave &#8220;unpartitioned space&#8221; on the drive, and therefore you&#8217;d end up creating more than one partition before running BCA, which would then refuse to do its thing.</p>
<p>I went a different route though, as I discovered that by installing <a href="http://macntfs-3g.blogspot.com/">NTFS-3G</a> (the free Open Source version), I could create NTFS partitions using Disk Utility. So I partitioned the entire drive, this time using Disk Utility, and was able to successfully restore Windows to the NTFS partition using Winclone.</p>
<p>That was the easy part though.</p>
<h4>Fragile Windows</h4>
<p>Restoring Windows is one thing, getting it to boot is another. Upon rebooting to check the XP install, I was greeted with a black screen and error message along the lines of &#8220;No bootable device available.&#8221;</p>
<p>After searching Google I came across <a href="http://www.macosxhints.com/article.php?story=20090807033320433">this hint</a> on how to triple-boot your system. The comments section were particularly helpful, and led me to investigate the <b><span class="code">boot.ini</span></b> file as a possible source of the problem.</p>
<p>The <span class="code">boot.ini</span> file, for some reason, specifies what partition number it&#8217;s located on. My Windows partition was in the wrong location, and it didn&#8217;t like that. So I followed their suggestions and edited the file using emacs, and played around with the number. I tried every single number between 1 and 6, and even zero (out of desperation), none would satisfy Windows.</p>
<p>At some later point, after much formatting and reinstalling, I actually got Windows to boot, only to be greeted by a blue screen instead of a black screen, which flashed too quickly for me to read and then the computer restarted itself.</p>
<p>Although I don&#8217;t have a complete list of my Googles during this time, here&#8217;s what I was able to dig up from Firefox&#8217;s history, hopefully it will save a fellow Googler or two:</p>
<ul>
<li>chkdsk &#8220;volume appears to contain&#8221;</li>
<li>&#8220;windows could not start&#8221; hal.dll</li>
<li>windows xp recovery console</li>
<li>&#8220;no bootable device&#8221; boot.ini bootcamp</li>
<li>boot camp UNMOUNTABLE_BOOT_VOLUME</li>
<li>&#8220;there is no operating system installed in this virtual machine&#8221; <i>(That&#8217;s from Parallels)</i></li>
</ul>
<h4>The &#8220;Right&#8221; Partition</h4>
<p>Here&#8217;s what I now know. Editing <span class="code">boot.ini</span> may or may not work. In my case (with Windows XP) it definitely did not. Prior to embarking on this journey, you need to decide ahead of time what to install on the first two partitions, because the third has to be Windows. In Disk Utility, partitions start from the top:</p>
<p><center><a href="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/partitions.png" class="fancybox"><img src="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/partitions_thumb.png" alt="Disk Utility Partition Map" title="Disk Utility Partition Map" width="500" height="440" class="alignnone size-full wp-image-2193" /></a></center></p>
<p>I&#8217;m <i style="color:inherit">pretty sure</i> Windows must be installed on the third partition. It&#8217;s either that or the second one. For me right now, the third partition has done the trick.</p>
<p>Now, with a working WIndows install, I know how to verify the number in the <span class="code">boot.ini</span> file. It does in fact correspond to the partition number as specified in the output of <span class="code">diskutil list</span>, and/or <span class="code">df</span>. It&#8217;s one greater than the number you&#8217;d expect if you were just going by Disk Utility&#8217;s GUI. Here&#8217;s the output from the quad-booting laptop as it is now, showing it as partition #4:</p>
<pre class="code">Last login: Sun Jun 13 19:22:13 on console
Macintosh:~ gslepak$ diskutil list
/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *200.0 GB   disk0
   1:                        EFI                         209.7 MB   disk0s1
   2:                  Apple_HFS Snow Leopard            49.7 GB    disk0s2
   3:                  Apple_HFS Leopard                 32.6 GB    disk0s3
   4:       Microsoft Basic Data Windows                 29.2 GB    disk0s4
   5:                  Apple_HFS Tiger                   20.6 GB    disk0s5
Macintosh:~ gslepak$ df
Filesystem    512-blocks     Used Available Capacity  Mounted on
/dev/disk0s2    97069312 23384096  73173216    25%    /
devfs                218      218         0   100%    /dev
map -hosts             0        0         0   100%    /net
map auto_home          0        0         0   100%    /home
/dev/disk0s3    63741456 24106640  39634816    38%    /Volumes/Leopard
/dev/disk0s4    57012216 29356408  27655808    52%    /Volumes/Windows
/dev/disk0s5    40174016 15283088  24890928    39%    /Volumes/Tiger
</pre>
<h4>Stubborn Tiger</h4>
<p>Not to be outdone by its Redmond counterpart, Mac OS 10.4 Tiger turned out to be even more difficult to install.</p>
<p>First, the install disk that came with the computer (which had 10.4.9) refused to be recognized. It spun for a little while and was then spit out. So I inserted it into my PowerMac figuring I could just install over Target Disk Mode, but it refused to run because Apple watermarks these DVDs so that they only work on the exact same kind of computer.</p>
<p>Fortunately, I had another Tiger install disk that did work with any Mac. It was only after the installation finished (over Target Disk Mode, again), that I realized it was a PPC-only install, causing the Intel laptop to kernel panic on boot.</p>
<p>Feeling defeated, I went for a jog, during which I realized that I could insert the Intel install disk into my Unibody MacBook Pro, copy it onto an external hard disk, and boot off of that, thereby bypassing the flaky SuperDrive on the old MacBook Pro.</p>
<p>That outta do it, right?</p>
<p><center><a href="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/TigerStripes.jpg" class="fancybox"><img src="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/TigerStripes_thumb.jpg" alt="Tiger&#039;s Stripes" title="Tiger&#039;s Stripes" width="500" height="375" class="alignnone size-full wp-image-2199" /></a></center></p>
<p>And it did! Now I just had to figure out what to do about the crazy blue and black stripes on the screen that made it impossible to see the installer.</p>
<p>You see, this laptop, like most of its kind, was affected by the <a href="http://forums.macrumors.com/showthread.php?t=515067">infamous NVIDIA 8600GT</a> bug that completely wiped out its display capabilities. Apple <a href="/blog/2008/11/back-up-and-running/">kindly replaced</a> the logic board but, in doing so, apparently killed its compatibility with Tiger.</p>
<p>You would think that by this point any sane person would have called it a day, but it was far too late for me. My OCD was in overdrive, and I had become sort of obsessed with solving this problem. Failure was not an option&#8230; not yet at least.</p>
<p><a href="http://support.apple.com/kb/HT1492">Verbose mode</a> showed the following error:</p>
<pre class="code">GFX0 matching specific fails</pre>
<p>Google wasn&#8217;t very helpful here unfortunately, but I figured that there was a missing or outdated graphics driver. So I spent some time copying and replacing kernel extensions from my Leopard install (which had finished without problems) into the Tiger installation drive. This took a rather long time, as each time I changed a kernel extension I had to reboot to see if the fix took. I had to replace them one at a time so as to avoid potentially compounding the problem (as kernel extensions have dependencies).</p>
<p><i>Sidenote: If you ever find yourself switching out kernel extensions, don&#8217;t forget to delete the cache files &#8216;Extensions.mkext&#8217; and &#8216;Extensions.kextcache&#8217; each time you do. These files may or may not be present in the /System/Library folder, depending on the OS version.</i></p>
<p>Eventually I realized this was stupid, because I could simply run the OS install by running the OSInstall.mpkg from within Snow Leopard:</p>
<p><center><a href="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/OSInstall.png" class="fancybox"><img src="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/OSInstall_thumb.png" alt="OSInstall.mpkg" title="OSInstall.mpkg" width="500" height="274" class="alignnone size-full wp-image-2200" /></a></center></p>
<p>The installer ran (and hung at the end, of course) but it looked like it had installed everything that was necessary so I rebooted again from the Tiger disk.</p>
<p>I should mention that sometimes the disks that I needed to boot from did not appear in the Startup Disk preference pane, despite being bootable. I got around that by running the <span class="code">bless</span> command on the volume:</p>
<pre class="code">sudo bless --mount /Volumes/Tiger --setBoot --nextonly</pre>
<p>I booted into Tiger and again was greeted with its unreadable blue stripes, and by now the all too familiar setup theme music. Curses!</p>
<p>I decided to install the 10.4.11 Combo Update from Snow Leopard, thinking it might contain the proper drivers. The download link on Apple&#8217;s site was broken, but by this point the random problems no longer surprised me. After some searching I finally found <a href="http://supportdownload.apple.com/download.info.apple.com/Apple_Support_Area/Apple_Software_Updates/Mac_OS_X/downloads/061-4048.20071114.6Gn4g/MacOSXUpdCombo10.4.11Intel.dmg">a working link</a> to it. Too bad though, the update did not fix the problem.</p>
<p>It then dawned upon me that this was all a test. God was testing me, to see how badly I wanted to install the outdated operating system, and whether I really did possess the geek-credentials I claimed to have.</p>
<p>So I went back to the old plan of replacing kernel extensions.</p>
<p>I copied a bunch of extensions over from Leopard that I thought might fix the problem without causing too many dependency issues. While that did get rid of the error message, and Tiger no longer sported blue and black stripes, instead, I saw only the black and white text of the verbose screen while the Tiger setup music played in the background, taunting me.</p>
<p>I proceeded to replace the kernel extensions with the originals, one-by-one, hoping to find the one that was responsible for the missing error message. After what had to be at least an hour I finally noticed it: the GFX0 error message was back, and it was after I had replaced <span class="code">NVDAResman.kext</span> with its original.</p>
<p>Intrigued, I restored the entire Extensions folder back to its original state and replaced <i style="color:inherit">just</i> <span class="code">NVDAResman.kext</span>.</p>
<p><center><a href="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/TigerInstallSuccess.jpg" class="fancybox"><img src="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/TigerInstallSuccess_thumb.jpg" alt="Tiger Install Success!" title="Tiger Install Success!" width="500" height="375" class="alignnone size-full wp-image-2201" /></a></center></p>
<p><b>Success!!</b></p>
<p><i>Almost!</i> There was one loose-end left to fix. After logging into my account on Tiger, I got a couple of error messages complaining about <span class="code">NVDANV50Hal.kext</span> and <span class="code">GeForce.kext</span> not loading properly. Simply removing them from the <span class="code">/System/Library/Extensions</span> did the trick, with no noticeable ill effects (I tried replacing them with the ones from the Leopard install, but that didn&#8217;t work).</p>
<p>As a finishing touch, I used iPartition to shrink the Tiger partition. This way I won&#8217;t have to run iDefrag on it if I decide to install additional operating systems in the future (like 10.7). Here&#8217;s how it looks in Disk Utility:</p>
<p><center><a href="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/FinalPartitionMap.png" class="fancybox"><img src="http://www.taoeffect.com/blog/wp-content/uploads/2010/06/FinalPartitionMap_thumb.png" alt="Final Partition Map" title="Final Partition Map" width="500" height="440" class="alignnone size-full wp-image-2202" /></a></center></p>
<p>Hopefully this post will save someone a headache, or two. <img src='http://www.taoeffect.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.taoeffect.com/blog/2010/06/the-ultimate-test-machine-saga/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Easy Cocoa Setup Assistants with TESetupAssistant</title>
		<link>http://www.taoeffect.com/blog/2010/01/easy-cocoa-setup-assistants-with-tesetupassistant/</link>
		<comments>http://www.taoeffect.com/blog/2010/01/easy-cocoa-setup-assistants-with-tesetupassistant/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 02:25:59 +0000</pubDate>
		<dc:creator>Greg Slepak</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Free Stuff]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[free]]></category>
		<category><![CDATA[greg]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://www.taoeffect.com/blog/?p=1766</guid>
		<description><![CDATA[Setup assistants can be a great tool when you need to guide users through a series of steps. TESetupAssistant was born during my work on the 2.0 update to Espionage, when I discovered that many of its UI elements could stand to benefit from a generic setup assistant class. The gallery below shows some of [...]]]></description>
			<content:encoded><![CDATA[<p>Setup assistants can be a great tool when you need to guide users through a series of steps.</p>
<p><b>TESetupAssistant</b> was born during my work on the <a href="/blog/2009/02/espionage-20-released/">2.0 update</a> to <a href="/espionage">Espionage</a>, when I discovered that many of its UI elements could stand to benefit from a generic setup assistant class.</p>
<p>The gallery below shows some of the places in Espionage where we use TESetupAssisant, illustrating its versatility:</p>
<div class="imageGallery" style="background-color:black">
<ul style="width:500px">
<li><a rel="imageGallery" href="http://www.taoeffect.com/blog/wp-content/uploads/2010/01/keychain.png" title="Switching keychains"><img style="margin-top:20px" src="http://www.taoeffect.com/blog/wp-content/uploads/2010/01/keychain_thumb.png"/></a></li>
<li><a rel="imageGallery" title="Encrypting application data" href="http://www.taoeffect.com/blog/wp-content/uploads/2010/01/apptemplates.png"><img src="http://www.taoeffect.com/blog/wp-content/uploads/2010/01/apptemplates_thumb.png" /></a></li>
<li class="right"><a rel="imageGallery" title="Installing Espionage itself" href="http://www.taoeffect.com/blog/wp-content/uploads/2010/01/install.png"><img style="margin-top:25px" src="http://www.taoeffect.com/blog/wp-content/uploads/2010/01/install_thumb.png" /></a></li>
</ul>
<div class="clear"></div>
</div>
<p>You can create these sorts of UIs very quickly and use them wherever the user needs to complete a series of steps, or even a single step (as shown in the first image above). Here&#8217;s a basic overview of it:</p>
<p><center><img src="http://www.taoeffect.com/blog/wp-content/uploads/2010/01/TESetupAssistant.png" /></center></p>
<p>There are two main classes: <B>TESetupAssistant</b> and <B>TEBaseAssistant</b>. TESetupAssistant is associated with a nib file that determines the overall layout. It manages a one or more assistants, each of which inherit from TEBaseAssistant. Each TEBaseAssistant subclass has its own nib file, usually just containing a single NSView container object.</p>
<h3>Example of a Modal Assistant</h3>
<p>Here&#8217;s an example of a very simple assistant using the minified UI and running modally:</p>
<p><center><img src="http://www.taoeffect.com/blog/wp-content/uploads/2010/01/simple_assistant.png"/></center></p>
<p>And here is all the code needed to create it:</p>
<pre class="code">
<span class="source source_objc"><span class="meta meta_preprocessor meta_preprocessor_c meta_preprocessor_c_include">#<span class="keyword keyword_control keyword_control_import keyword_control_import_include keyword_control_import_include_c">import</span> <span class="string string_quoted string_quoted_other string_quoted_other_lt-gt string_quoted_other_lt-gt_include string_quoted_other_lt-gt_include_c"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_c">&lt;</span>Cocoa/Cocoa.h<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_c">&gt;</span></span></span>
<span class="meta meta_preprocessor meta_preprocessor_c meta_preprocessor_c_include">#<span class="keyword keyword_control keyword_control_import keyword_control_import_include keyword_control_import_include_c">import</span> <span class="string string_quoted string_quoted_double string_quoted_double_include string_quoted_double_include_c"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_c">"</span>TESetupAssistant.h<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_c">"</span></span></span>

<span class="meta meta_interface-or-protocol meta_interface-or-protocol_objc"><span class="storage storage_type storage_type_objc"><span class="punctuation punctuation_definition punctuation_definition_storage punctuation_definition_storage_type punctuation_definition_storage_type_objc">@</span>interface</span> <span class="entity entity_name entity_name_type entity_name_type_objc">MiniAssistant</span> <span class="punctuation punctuation_definition punctuation_definition_entity punctuation_definition_entity_other punctuation_definition_entity_other_inherited-class punctuation_definition_entity_other_inherited-class_objc">:</span> <span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_objc">TEBaseAssistant</span><span class="meta meta_divider meta_divider_objc"> </span><span class="meta meta_scope meta_scope_interface meta_scope_interface_objc">{
    <span class="storage storage_type storage_type_objc">IBOutlet</span> <span class="support support_class support_class_cocoa">NSTextField</span> *textField;
}
</span><span class="storage storage_type storage_type_objc"><span class="punctuation punctuation_definition punctuation_definition_storage punctuation_definition_storage_type punctuation_definition_storage_type_objc">@</span>end</span></span>

<span class="meta meta_implementation meta_implementation_objc"><span class="storage storage_type storage_type_objc"><span class="punctuation punctuation_definition punctuation_definition_storage punctuation_definition_storage_type punctuation_definition_storage_type_objc">@</span>implementation</span> <span class="entity entity_name entity_name_type entity_name_type_objc">MiniAssistant</span>
<span class="meta meta_scope meta_scope_implementation meta_scope_implementation_objc"><span class="meta meta_function meta_function_objc">- <span class="meta meta_return-type meta_return-type_objc"><span class="punctuation punctuation_definition punctuation_definition_type punctuation_definition_type_objc">(</span><span class="support support_class support_class_cocoa">NSArray</span> *<span class="punctuation punctuation_definition punctuation_definition_type punctuation_definition_type_objc">)</span><span class="entity entity_name entity_name_function entity_name_function_objc">orderedSteps</span></span>
</span>{
    <span class="keyword keyword_control keyword_control_c">return</span> <span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span><span class="support support_class support_class_cocoa">NSArray</span> <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">arrayWithObject<span class="punctuation punctuation_separator punctuation_separator_arguments punctuation_separator_arguments_objc">:</span></span><span class="string string_quoted string_quoted_double string_quoted_double_objc"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_objc">@"</span>Mini Step<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_objc">"</span></span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span>;
}
<span class="meta meta_function meta_function_objc">- <span class="meta meta_return-type meta_return-type_objc"><span class="punctuation punctuation_definition punctuation_definition_type punctuation_definition_type_objc">(</span><span class="storage storage_type storage_type_c">void</span><span class="punctuation punctuation_definition punctuation_definition_type punctuation_definition_type_objc">)</span><span class="entity entity_name entity_name_function entity_name_function_objc">start</span></span>
</span>{
    <span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span><span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span>controller <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">nextButton</span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span> <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">setTitle<span class="punctuation punctuation_separator punctuation_separator_arguments punctuation_separator_arguments_objc">:</span></span><span class="string string_quoted string_quoted_double string_quoted_double_objc"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_objc">@"</span>Finish<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_objc">"</span></span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span>;
    <span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span>textField <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">setStringValue<span class="punctuation punctuation_separator punctuation_separator_arguments punctuation_separator_arguments_objc">:</span></span>NSSTR_FMT(
        <span class="string string_quoted string_quoted_double string_quoted_double_c"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_c">"</span>Hi there! I'm a mini-assistant <span class="constant constant_other constant_other_placeholder constant_other_placeholder_c">%s</span>running modally!<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_c">"</span></span>,
        <span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span>controller <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">modal</span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span> ? <span class="string string_quoted string_quoted_double string_quoted_double_c"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_c">"</span><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_c">"</span></span> : <span class="string string_quoted string_quoted_double string_quoted_double_c"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_c">"</span>not <span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_c">"</span></span>)
    </span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span>;
}
</span><span class="storage storage_type storage_type_objc"><span class="punctuation punctuation_definition punctuation_definition_storage punctuation_definition_storage_type punctuation_definition_storage_type_objc">@</span>end</span></span>

<span class="comment comment_line comment_line_double-slash comment_line_double-slash_c++"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_c">//</span> To run it modally is just 4 lines of code (somewhere):
</span>
TESetupAssistant *sa = <span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span><span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span><span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span>TESetupAssistant <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">alloc</span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span> <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">initMini</span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span> <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">autorelease</span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span>;
<span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span>sa <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">setModal<span class="punctuation punctuation_separator punctuation_separator_arguments punctuation_separator_arguments_objc">:</span></span><span class="constant constant_language constant_language_objc">YES</span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span>;
<span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span>sa <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">addAssistant<span class="punctuation punctuation_separator punctuation_separator_arguments punctuation_separator_arguments_objc">:</span></span><span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span>MiniAssistant <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">assistant</span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span>;
<span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span>sa <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">run</span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span>;</span>
</pre>
<p>Notice that we don&#8217;t even need to load the nib file. That&#8217;s because our nib file is named after our assitant (MiniAssistant.nib). You can of course override the <span class="code">-assistantNib</span> method to specify a different one, but that illustrates one key aspect of TESetupAssistant, and that is that there are sensible defaults for almost everything, allowing you to quickly throw together these kinds of interfaces.</p>
<h3>Get It On Bitbucket</h3>
<p>I&#8217;m releasing TESetupAssistant as open source under a liberal license (just an attribution is asked for), and I&#8217;ve included a little demo app to help you hit the ground running. You can <a href="http://bitbucket.org/taoeffect/tesetupassistant/downloads/">download</a> it <a href="http://bitbucket.org/taoeffect/tesetupassistant/overview/">on bitbucket</a>.</p>
<p>If you use it in your application I&#8217;d love to know! Shoot us an email or post a comment below and I&#8217;ll place a link here to your app.</p>
<p>Enjoy! <img src='http://www.taoeffect.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><i style="color:inherit">You can follow me on twitter <a href="http://twitter.com/taoeffect">here</a>.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://www.taoeffect.com/blog/2010/01/easy-cocoa-setup-assistants-with-tesetupassistant/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
