<?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>Whatever happened to Benjamin Ragheb? &#187; xcode</title>
	<atom:link href="http://www.benzado.com/blog/tags/xcode/feed" rel="self" type="application/rss+xml" />
	<link>http://www.benzado.com/blog</link>
	<description>I apologize that this blog is using the default Wordpress template.</description>
	<lastBuildDate>Thu, 06 May 2010 16:33:52 +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>Make Xcode nag you about unfinished TODOs</title>
		<link>http://www.benzado.com/blog/post/329/make-xcode-nag-you-about-unfinished-todos</link>
		<comments>http://www.benzado.com/blog/post/329/make-xcode-nag-you-about-unfinished-todos#comments</comments>
		<pubDate>Fri, 08 Jan 2010 08:51:15 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=329</guid>
		<description><![CDATA[Add a simple Run Script Build Phase to your project and you'll never forget another TODO again.]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re like me, you often make promises to yourself in the form of TODO comments in your code. For example:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// TODO: make sure file exists before opening!</span>
fooBar <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>FooBar alloc<span style="color: #002200;">&#93;</span> initWithFile<span style="color: #002200;">:</span>path<span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>This is a reasonable thing to do, because sometimes you just want to get something working right now and aren&#8217;t in the mood to write all the required error checking code. But, you also know that you cannot trust your <a href="http://theinfosphere.org/Transcript:I,_Roommate#time-04-13">soft human brain</a> to remember to add the check later, so you write a comment to remind yourself to do it.</p>
<p>Xcode recognizes the TODO: keyword in your comments and helpfully <a href="http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/XcodeWorkspace/100-The_Text_Editor/text_editor.html#//apple_ref/doc/uid/TP40002679-SW10">adds items to the function popup menu</a> so that you can quickly navigate to them. In addition to <code>TODO:</code>, Xcode will also recognize <code>FIXME:</code> (when you know the code is broken), <code>???:</code> (when you don&#8217;t know what it does), and <code>!!!:</code> (when you wish you didn&#8217;t know).</p>
<p>That&#8217;s helpful when you&#8217;re editing a file, but what about a TODO tucked away in some dark corner of your source code that you haven&#8217;t visited in a while? You&#8217;re likely to forget about it, and how can you keep a promise you forgot that you made?</p>
<p>The answer, of course, is to have somebody nag you. Fortunately, there&#8217;s a way to have Xcode fill that role. All you have to do is add a simple Run Script Build Phase which turns them into Build Warnings.</p>
<p>Select <b>Project &gt; New Build Phase &gt; New Run Script Build Phase</b> from the menu bar. Then, copy and paste this into the script window:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">KEYWORDS</span>=<span style="color: #ff0000;">&quot;TODO:|FIXME:|\?\?\?:|\!\!\!:&quot;</span>
<span style="color: #c20cb9; font-weight: bold;">find</span> <span style="color: #800000;">${SRCROOT}</span> \<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #660033;">-name</span> <span style="color: #ff0000;">&quot;*.h&quot;</span> <span style="color: #660033;">-or</span> <span style="color: #660033;">-name</span> <span style="color: #ff0000;">&quot;*.m&quot;</span> \<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #660033;">-print0</span> <span style="color: #000000; font-weight: bold;">|</span> \
    <span style="color: #c20cb9; font-weight: bold;">xargs</span> <span style="color: #660033;">-0</span> <span style="color: #c20cb9; font-weight: bold;">egrep</span> <span style="color: #660033;">--with-filename</span> <span style="color: #660033;">--line-number</span> <span style="color: #660033;">--only-matching</span> <span style="color: #ff0000;">&quot;(<span style="color: #007800;">$KEYWORDS</span>).*<span style="color: #000099; font-weight: bold;">\$</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> \
    <span style="color: #c20cb9; font-weight: bold;">perl</span> <span style="color: #660033;">-p</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/(<span style="color: #007800;">$KEYWORDS</span>)/ warning: <span style="color: #000099; font-weight: bold;">\$</span>1/&quot;</span></pre></td></tr></table></div>

<p>What does it mean?</p>
<p>Line 1 defines the keywords we want to search for. If you want to exclude a keyword or include a different one, edit this line.</p>
<p>Line 2 uses the <a href="http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man1/find.1.html">find</a> command to generate a list of all files in your project directory (SRCROOT) having an .h or .m extension. If you want to search more files, you will need to edit this line.</p>
<p>Line 3 uses <a href="http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man1/xargs.1.html">xargs</a> to pass those file names along to <a href="http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man1/egrep.1.html">egrep</a>, which searches inside the files for lines containing one of the keywords. If any are found, it outputs the file name, line number, and the matching part of the line.</p>
<p>Line 4 uses Perl to format the lines as warnings.</p>
<p>The output of the script will look like this:</p>
<p><code>/Users/benzado/Projects/FooBart/Baz.m:42: warning: TODO: make sure file exists before opening!</code></p>
<p>Xcode will recognize lines in this format and treat them as first class build warnings. You can see them in the Build Results panel and, just like a warning from the compiler, a double click will open an editor window and take you directly to the offending line.</p>
<p><i>An Exercise For The Enterprising Reader: modify the script so that no warnings or errors are reported during Debug builds, but TODOs are flagged as errors in Release builds.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/329/make-xcode-nag-you-about-unfinished-todos/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Avoid defining your iPhone app&#8217;s default values in two places</title>
		<link>http://www.benzado.com/blog/post/275/xsl-for-default-plist</link>
		<comments>http://www.benzado.com/blog/post/275/xsl-for-default-plist#comments</comments>
		<pubDate>Tue, 06 Oct 2009 22:13:34 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[xcode]]></category>
		<category><![CDATA[xsl]]></category>
		<category><![CDATA[xsltproc]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=275</guid>
		<description><![CDATA[This is a guide to using XSLT to extract default values from your iPhone app&#8217;s Settings bundle into a separate property list file. That file can be loaded by your app at runtime, sparing you the need to maintain the same data in two places and avoiding the risk of a mismatch leading to buggy [...]]]></description>
			<content:encoded><![CDATA[<p>This is a guide to using XSLT to extract default values from your iPhone app&#8217;s Settings bundle into a separate property list file. That file can be loaded by your app at runtime, sparing you the need to maintain the same data in two places and avoiding the risk of a mismatch leading to buggy behavior.</p>
<p><span id="more-275"></span>Your iPhone app includes a Settings bundle, so that you can keep your application simple and leave the <a href="http://www.settingsareinthesettingsapp.com/">settings in the settings app</a>. Specifically, you allow the user to customize the FooColor setting, with a default value of Red.</p>
<p>Initially, the user defaults database doesn&#8217;t contain a value for FooColor. Although you defined a default value in the Settings bundle, only the Settings app pays any attention to it.</p>
<p><b>Take Note:</b> Cocoa uses the term &#8220;user defaults&#8221; to refer to application settings in general. Don&#8217;t confuse that with the notion of a default value, which is the initial value of a setting before it has been changed through user action.</p>
<p>The proper way to load default values at runtime is to use NSUserDefaults&#8217;s <code>registerDefaults:</code> method. It takes a single NSDictionary object and merges it into the user defaults registration domain. (The user defaults database is divided into domains, or layers.) Values in the registration domain are only used if they are not defined anywhere else, so you don&#8217;t need to worry about overwriting a user&#8217;s preference.</p>
<p>You create a property list file named Defaults.plist, define an entry giving &#8220;FooColor&#8221; the value &#8220;Red&#8221;, and load it:</p>
<pre>NSString *path = [[NSBundle mainBundle] pathForResource:@"Defaults" ofType:@"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];</pre>
<p>The only problem with this set up is that you must keep your Settings bundle and Defaults.plist files in sync. If you change the default FooColor from Red to Blue, you must change both. If you add a new setting, you must add it to both. If you&#8217;ve been programming for more than a month, you know that eventually you will make a mistake which will lead to a bug that will take forever to track down and take years off your life.</p>
<p><strong>Therefore, a better solution is to dynamically generate Defaults.plist from the data that is already in the Settings bundle.</strong> You can do so with <a href="http://www.benzado.com/blog/wp-content/uploads/2009/10/ExtractDefaults.xsl.txt" title="ExtractDefaults.xsl.txt">ExtractDefaults.xsl</a>, a simple stylesheet which creates an XML property list from a Settings bundle definition, and xsltproc, which is fortunately already installed on your Mac.</p>
<p>First, if you really did create a Defaults.plist, remove it from your project and delete the file. It&#8217;s graduating from a source file to a build product!</p>
<p>Then, select your target in Xcode. Go to the menu bar and select Project | New Build Phase | New Run Script Build Phase. A window appears. In the Script area, enter the following shell script:</p>
<pre>SETTINGS_PLIST=$SRCROOT/Settings/Root.plist
XSL=$SRCROOT/ExtractDefaults.xsl
DEFAULTS_PLIST=${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Defaults.plist
xsltproc -o $DEFAULTS_PLIST $XSL $SETTINGS_PLIST
plutil -convert binary1 $DEFAULTS_PLIST</pre>
<p>You may need to edit the first three lines, depending on the path to your Settings page file and where you saved ExtractDefaults.xsl. It&#8217;s also recommended that you fill in the Input Files and Output Files lists, so that Xcode can intelligently determine when the script needs to be run (when input files are newer than output files). Following the script above, Input Files should contain:</p>
<pre>$(SRCROOT)/Settings/Root.plist
$(SRCROOT)/ExtractDefaults.xsl</pre>
<p>Output Files should contain:</p>
<pre>$(BUILT_PRODUCTS_DIR)/$(WRAPPER_NAME)/Defaults.plist</pre>
<p>Note that Xcode needs round parenthesis around variable names, unlike the shell script, which uses nothing or curly braces. There&#8217;s a good reason for this, but I don&#8217;t know what it is.</p>
<p><strong>That&#8217;s it!</strong> Now, when you build your app, the script will generate a Defaults.plist file inside of your app bundle, so it can be loaded by your code. And you won&#8217;t have to worry about your app defaults mismatching your Settings bundle defaults, because it is being handled by a machine, and machines never fail!</p>
<h3>Mini-FAQ</h3>
<p><strong>Where do I get ExtractDefaults.xsl?</strong> <a href="http://www.benzado.com/blog/wp-content/uploads/2009/10/ExtractDefaults.xsl.txt" title="ExtractDefaults.xsl.txt">Click here to download the file.</a> It&#8217;s free to use for whatever you want to do with it. If you improve on it in some way, kindly let me know.</p>
<p><strong>What if I have also default values not defined in my Settings bundle?</strong> You can manually enter them into another property list file, and load both. It&#8217;s totally cool to call <code>registerDefaults:</code> several times with different dictionaries. <em>Totally cool!</em></p>
<p><strong>What if my Settings bundle contains multiple page files?</strong> In that case you could run the script over each one, generating several Defaults.plist files, and load them all at runtime. Or, if you&#8217;re really clever, figure out some way to merge them all into a single property list at build time. <em>I can&#8217;t do everything for you.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/275/xsl-for-default-plist/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Show Xcode where to find Subversion 1.5</title>
		<link>http://www.benzado.com/blog/post/40/show-xcode-where-to-find-subversion-15</link>
		<comments>http://www.benzado.com/blog/post/40/show-xcode-where-to-find-subversion-15#comments</comments>
		<pubDate>Sat, 22 Nov 2008 02:56:11 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=40</guid>
		<description><![CDATA[I installed Subversion 1.5 using MacPorts (with the Porticus front-end), which places libraries in /opt/local/lib by default.  Xcode 3.1.1 supports Subversion 1.5, but it only looks in /usr/lib, so even though I have Subversion 1.5 installed, it claims my working copies are incompatible.  How did I fix this? sudo -s cd /usr/lib tar cvf oldapr+svnlib.tar libapr* [...]]]></description>
			<content:encoded><![CDATA[<p>I installed Subversion 1.5 using <a href="http://www.macports.org/">MacPorts</a> (with the <a href="http://porticus.alittledrop.com/">Porticus</a> front-end), which places libraries in /opt/local/lib by default.  Xcode 3.1.1 supports Subversion 1.5, <a href="http://lists.apple.com/archives/Xcode-users/2008/Sep/msg00289.html">but it only looks in /usr/lib</a>, so even though I have Subversion 1.5 installed, it claims my working copies are incompatible.  How did I fix this?</p>
<ol>
<li>sudo -s</li>
<li>cd /usr/lib</li>
<li>tar cvf oldapr+svnlib.tar libapr* libsvn*</li>
<li>bzip2 oldapr+svnlib.tar</li>
<li>rm libapr* libsvn*</li>
<li>cd /opt/local/lib</li>
<li>for NAME in libapr*.dylib; do ln -s /opt/local/lib/$NAME /usr/lib/$NAME; done</li>
<li>for NAME in libsvn*.dylib; do ln -s /opt/local/lib/$NAME /usr/lib/$NAME; done</li>
<li>exit</li>
</ol>
<div>Lines 3-4 generate a backup archive.  In case something goes wrong, you can delete the libapr* and libsvn* files from /usr/lib and unpack oldapr+svnlib.tar.bz2 to go back to the way things were.</div>
<p>Line 5 removes the existing subversion libraries and lines 6-8 put symlinks in /usr/lib that point to /opt/local/lib.  Note that the set of libraries may not match exactly.  (In my case, some libraries for Python and Ruby bindings didn&#8217;t appear in /opt/local/lib.)  However, I figure it&#8217;s better to keep the set consistent than to piece together possibly incompatible parts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/40/show-xcode-where-to-find-subversion-15/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
