<?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; Nerdery</title>
	<atom:link href="http://www.benzado.com/blog/what/nerdery/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>Draw your own Disclosure Indicator</title>
		<link>http://www.benzado.com/blog/post/325/draw-your-own-disclosure-indicator</link>
		<comments>http://www.benzado.com/blog/post/325/draw-your-own-disclosure-indicator#comments</comments>
		<pubDate>Mon, 04 Jan 2010 03:21:17 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=325</guid>
		<description><![CDATA[In which I share code for a function to draw an iPhone disclosure indicator.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m writing Cocoa Touch code to draw a button which, when pressed, pushes a new view controller onto the stack. If I was working with a UITableView, I&#8217;d simply set the cell&#8217;s accessory to be a <a href="http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/MobileHIG/ContentViews/ContentViews.html#//apple_ref/doc/uid/TP40006556-CH12-SW13">disclosure indicator</a> (the little gray arrowhead) and call it a day.</p>
<p>But I&#8217;m not working with table cells, so even though the standard disclosure indicator is <em>perfect</em> for this situation, if I want one I&#8217;ll have to draw it myself.</p>
<p>In this situation I will usually take a screenshot of the real iPhone control, add the image file to my project, and then feel kind of guilty about it. I began to do this, but I realized that the disclosure indicator is really only two gray lines. Two lines! How hard can it be to just draw it in code?</p>
<p>It turns out that it&#8217;s not too hard, if you&#8217;re willing to spend some time experimenting with different numbers and seeing what looks right. Fortunately for you, I&#8217;ve saved you the trouble by posting the answer here:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Draws a disclosure indicator such that the tip of the arrow is at (x,y)</span>
<span style="color: #a61390;">void</span> BRDrawDisclosureIndicator<span style="color: #002200;">&#40;</span>CGContextRef ctxt, CGFloat x, CGFloat y<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">static</span> <span style="color: #a61390;">const</span> CGFloat R <span style="color: #002200;">=</span> <span style="color: #2400d9;">4.5</span>; <span style="color: #11740a; font-style: italic;">// &quot;radius&quot; of the arrow head</span>
    <span style="color: #a61390;">static</span> <span style="color: #a61390;">const</span> CGFloat W <span style="color: #002200;">=</span> <span style="color: #2400d9;">3</span>; <span style="color: #11740a; font-style: italic;">// line width</span>
    CGContextSaveGState<span style="color: #002200;">&#40;</span>ctxt<span style="color: #002200;">&#41;</span>;
    CGContextMoveToPoint<span style="color: #002200;">&#40;</span>ctxt, x<span style="color: #002200;">-</span>R, y<span style="color: #002200;">-</span>R<span style="color: #002200;">&#41;</span>;
    CGContextAddLineToPoint<span style="color: #002200;">&#40;</span>ctxt, x, y<span style="color: #002200;">&#41;</span>;
    CGContextAddLineToPoint<span style="color: #002200;">&#40;</span>ctxt, x<span style="color: #002200;">-</span>R, y<span style="color: #002200;">+</span>R<span style="color: #002200;">&#41;</span>;
    CGContextSetLineCap<span style="color: #002200;">&#40;</span>ctxt, kCGLineCapSquare<span style="color: #002200;">&#41;</span>;
    CGContextSetLineJoin<span style="color: #002200;">&#40;</span>ctxt, kCGLineJoinMiter<span style="color: #002200;">&#41;</span>;
    CGContextSetLineWidth<span style="color: #002200;">&#40;</span>ctxt, W<span style="color: #002200;">&#41;</span>;
    CGContextStrokePath<span style="color: #002200;">&#40;</span>ctxt<span style="color: #002200;">&#41;</span>;
    CGContextRestoreGState<span style="color: #002200;">&#40;</span>ctxt<span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>Before calling the function, you should set the stroke color to 50% gray if you&#8217;re drawing on a white background or white if the control is highlighted and you&#8217;re drawing on a blue background. Or, <a href="http://stackoverflow.com/questions/1852672/best-way-to-change-the-color-view-of-disclosure-indicator-accessory-view-in-a-tab">you can use whatever color you like</a>.</p>
<p>To be honest, I only eyeballed the result, so it <em>might</em> not be a pixel-perfect reproduction of the real thing. However, I think my eyeballs are at least as good as most users&#8217; eyeballs, so I will confidently declare this code Good Enough.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/325/draw-your-own-disclosure-indicator/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nicer ways to view UNIX man pages</title>
		<link>http://www.benzado.com/blog/post/319/nicer-ways-to-view-unix-man-pages</link>
		<comments>http://www.benzado.com/blog/post/319/nicer-ways-to-view-unix-man-pages#comments</comments>
		<pubDate>Mon, 30 Nov 2009 02:38:57 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=319</guid>
		<description><![CDATA[There is a wealth of information available in the UNIX manual pages, but it feels a little silly to be reading text out of a terminal window, especially since I paid so much money for all this fancy font rendering technology. Here are some alternatives: To view a man page in Xcode&#8217;s documentation window, simply [...]]]></description>
			<content:encoded><![CDATA[<p>There is a wealth of information available in the <a href="http://en.wikipedia.org/wiki/Man_page">UNIX manual pages</a>, but it feels a little silly to be reading text out of a terminal window, especially since I paid so much money for <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/TextArchitecture/Concepts/ArchitectureOverview.html">all this fancy font rendering technology</a>.</p>
<p>Here are some alternatives:</p>
<p>To view a man page in Xcode&#8217;s documentation window, simply select &#8220;Open man Page&#8230;&#8221; from the Help menu. For some reason, I hadn&#8217;t noticed that menu item until I read this <a href="http://toxicsoftware.com/manoxcode/">hint on accessing it via AppleScript</a>. Nicely formatted and references to other man pages are hyperlinked.</p>
<p><a href="http://bruji.com/bwana/index.html">Bwana</a> allows you to read man pages in any web browser, by registering itself as a protocol handler for <code>man:</code> URLs. Once installed, you can type <code>man:perl</code> in your browser&#8217;s address bar or <code>open man:perl</code> at a command prompt to read a manual page in your browser. Like Xcode, cross-references become hyperlinks, but it formats text using Courier. Source code is available, so I guess if I care enough I can do something about it.</p>
<p>Finally, a surprisingly short incantation will <a href="http://www.macosxhints.com/article.php?story=20051225101106519">open any man page as a beautifully formatted document in Preview</a>:</p>
<pre>man -t perl | open -f -a /Applications/Preview.app</pre>
<p>The <code>-t</code> option tells <code>man</code> to output PostScript, and the <code>-f</code> option tells <code>open</code> to put its input into a temporary file and pass that along to the specified application.</p>
<p>After reading that hint I set about writing a shell function so I could type <code>manp perl</code> to open Perl&#8217;s manual page in Preview. However, Preview&#8217;s PostScript to PDF conversion is kind of slow, so I wound up writing something slightly more sophisticated:</p>
<pre>function manp {
    local M=`man -w $*`               # Get path of page source.
    if [ -z $M ]; then return; fi     # Quit if it doesn't exist.
    local N=`basename $M .gz`         # Extract the name of the file and
    local P=$TMPDIR/man.$N.pdf        # use it to create a PDF file name.
    if [ ! -e $P ]; then              # If the PDF file doesn't exist,
        echo Creating PDF for $N...
        man -t $1 | pstopdf -i -o $P  # generate it.
    fi
    open $P                           # Open the PDF version.
}</pre>
<p>Then I went back and read the <a href="http://www.macosxhints.com/article.php?story=20051225101106519#comments">comments</a>, which contain a dozen or so different versions of the same idea. But mine&#8217;s the best! Copy and paste it into the your <code>.profile</code> if you agree.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/319/nicer-ways-to-view-unix-man-pages/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t printf when you can tcpdump</title>
		<link>http://www.benzado.com/blog/post/317/dont-printf-when-you-can-tcpdump</link>
		<comments>http://www.benzado.com/blog/post/317/dont-printf-when-you-can-tcpdump#comments</comments>
		<pubDate>Tue, 10 Nov 2009 23:04:20 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[tcpdump]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=317</guid>
		<description><![CDATA[Instead of using print statements to debug network communication, use tcpdump and get a complete and accurate picture of what's on the wire.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on an app that talks to a web service, and in the course of debugging it&#8217;s good to know what exactly is being sent to and from the web server. I had been doing so with the tried and true method of <a href="http://stackoverflow.com/questions/189562/what-is-the-proper-name-for-doing-debugging-by-adding-print-statements">printf() debugging</a> (this is Cocoa, so NSLog() debugging, actually), but it was getting to be a pain:</p>
<ol>
<li>If I print all network traffic all the time, it overwhelms my console, making it useless for any other kind of output. So instead, I&#8217;m constantly inserting or removing NSLog() statements as I work. Not to mention having to reproduce a request because the right logging statements weren&#8217;t in place the first time around.</li>
<li>NSURLConnection returns downloaded information as an NSData object, so simply passing it to NSLog() dumps a lot of useless hexadecimal code to the screen. That means I must first create an NSString from the data, print it, then release it. (I can&#8217;t use %s, the data isn&#8217;t null terminated.)</li>
<li>NSURLConnection does a lot of behind the scenes work, like storing cookies and setting Content-Length headers. That&#8217;s nice, but that makes it hard to know exactly what&#8217;s being sent on the wire.</li>
</ol>
<p>And that&#8217;s when it occurred to me: why not just watch what&#8217;s on the wire? tcpdump is a command line utility which monitors network traffic and prints out packets that you specify.</p>
<p>Here&#8217;s the incantation to monitor HTTP traffic to and from a specified host:</p>
<blockquote><p><code>sudo tcpdump -l -q -A "host <b>(Specified Host)</b> and tcp port 80 and (((ip[2:2] - ((ip[0]&#038;0xf)<<2)) - ((tcp[12]&#038;0xf0)>>2)) != 0)"</code></p></blockquote>
<p>To explain briefly, <code>sudo</code> runs the command as root, <code>-l</code> enables line buffering, <code>-q</code> hides some of the less interesting protocol information, and <code>-A</code> prints the content of each packet in ASCII. The filtering expression that follows selects packets to or from (Specified Host), to or from port 80, and ignoring SYN, FIN, ACK-only, and other non-data packets. I&#8217;ll confess, I don&#8217;t understand that last part completely, I copied it from the <a href="http://linux.die.net/man/8/tcpdump">tcpdump man page</a>.</p>
<p>To make the output a little easier to read, I pipe the output to a Perl script I quickly hacked together which watches for the packet header lines and outputs the <a href="http://isthe.com/chongo/tech/comp/ansi_escapes.html">ANSI escape codes</a> to render them in bold. But I&#8217;ll leave that as an exercise to you, dear reader.</p>
<p>There&#8217;s no need to download anything, tcpdump is already installed on your Mac. (I don&#8217;t know if it&#8217;s part of the standard install or the Developer Tools, but what do you care?)</p>
<p>Now, what would be <em>really</em> sweet is a graphical app to do this. I found <a href="http://www.tastycocoabytes.com/cpa/">Cocoa Packet Analyzer</a>, but it&#8217;s a little low-level for me. I don&#8217;t care about packet specifics; I&#8217;d prefer something that reconstructed the tcp streams in an easy to navigate way.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/317/dont-printf-when-you-can-tcpdump/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Spam Filter for Facebook Events</title>
		<link>http://www.benzado.com/blog/post/290/fb-events-filter</link>
		<comments>http://www.benzado.com/blog/post/290/fb-events-filter#comments</comments>
		<pubDate>Fri, 16 Oct 2009 19:46:56 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[google calendar]]></category>
		<category><![CDATA[ical]]></category>
		<category><![CDATA[icalproxy]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=290</guid>
		<description><![CDATA[I love that Facebook exports events as a calendar that I can subscribe to in Apple iCal or Google Calendar. It saves much copying and pasting. Unfortunately, somebody is almost always creating an event that spans several days. Then my calendar looks like this: This is annoying, because that purple monster isn&#8217;t even a real [...]]]></description>
			<content:encoded><![CDATA[<p>I love that Facebook exports events as a calendar that I can subscribe to in Apple iCal or Google Calendar. It saves much copying and pasting. Unfortunately, somebody is almost always creating an event that spans several days. Then my calendar looks like this:</p>
<p style="text-align: center;"><img class="size-medium wp-image-289 aligncenter" title="Giant event messing up my calendar" src="http://www.benzado.com/blog/wp-content/uploads/2009/10/Screen-shot-2009-10-16-at-12.31.25-PM-300x166.png" alt="Giant event messing up my calendar" width="300" height="166" /></p>
<p>This is annoying, because that purple monster isn&#8217;t even a real event; it&#8217;s just a notice that <a href="http://www.amazon.com/gp/product/B002FQ8NEM?ie=UTF8tag=benjpeteragh-20linkCode=as2camp=1789creative=390957creativeASIN=B002FQ8NEM">somebody&#8217;s film is available for download from Amazon</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=benjpeteragh-20l=as2o=1a=B002FQ8NEM" border="0" alt="" width="1" height="1" />. As much as I encourage everybody to watch that film, I don&#8217;t want it eating up my calendar. I am routinely invited to events like this, and they are always announcements, or &#8220;I&#8217;m looking for a roommate,&#8221; or &#8220;I was too lazy to create four separate events for the show I&#8217;m doing four times this month.&#8221; In other words, calendar spam.</p>
<p>This would be tolerable, if there were some way to hide individual events, but there isn&#8217;t. Facebook includes every event you&#8217;ve been invited to, even if you RSVP: Not Attending. You can uninvite yourself using the &#8220;Remove from My Events&#8221; link, but it&#8217;s tedious and doesn&#8217;t protect you from being re-invited in the future. It&#8217;s also of no use if you&#8217;re away from the computer and viewing your calendar on your iPhone.</p>
<h3>How to Clean Your Calendar</h3>
<p>I solved the problem with a program that acts as a proxy between your calendar app and Facebook, removing events that are longer than 12 hours. It&#8217;s on the web, so you can use it, too.</p>
<p>First, find your Facebook Calendar URL by going to <a href="http://www.facebook.com/events.php">Facebook Events</a> and clicking &#8220;Export Events&#8221; in the top left corner. A box will appear with an address that looks something like this:</p>
<pre>http://www.facebook.com/ical/u.php?uid=123456&amp;key=789abcdef</pre>
<p>To use the filter, change the first part of the address (everything before the question mark) so that it looks like this:</p>
<pre>http://www.benzado.com/bin/icalproxy.php?uid=123456&amp;key=789abcdef</pre>
<p>Then you can use the new address to subscribe to your filtered calendar in apps like <a href="http://docs.info.apple.com/article.html?path=iCal/4.0/en/9869.html">Apple iCal</a> or <a href="http://www.google.com/support/calendar/bin/answer.py?hl=enanswer=37100">Google Calendar</a>.</p>
<p>Note that using my filter means your events pass through my web server, and even though I&#8217;m not really interested in looking at them, I could. So if you&#8217;re super concerned about your privacy, keep that in mind.</p>
<p>If you&#8217;d like to see how the script works or make a copy to run on your own server, you can <a href="http://www.benzado.com/bin/icalproxy.php?getsrc">view the source code</a>. If you extend it in any interesting ways, please let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/290/fb-events-filter/feed</wfw:commentRss>
		<slash:comments>2</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>Bracket-notation syntax</title>
		<link>http://www.benzado.com/blog/post/270/bracket-notation-syntax</link>
		<comments>http://www.benzado.com/blog/post/270/bracket-notation-syntax#comments</comments>
		<pubDate>Sat, 08 Aug 2009 21:35:19 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Comedy]]></category>
		<category><![CDATA[Nerdery]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=270</guid>
		<description><![CDATA[I don&#8217;t agree with The Big Nerd Ranch&#8217;s philosophy. When I teach, I make sure to mention the bracket-notation added to C by Objective-C. Then, I make sure to tell the students never to use it ever, ever, ever again. Buy why? To keep our code consistent and maintain readability. The Intent of Code When we [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t agree with <a href="http://weblog.bignerdranch.com/?p=83">The Big Nerd Ranch&#8217;s philosophy</a>. When I teach, I make sure to mention the bracket-notation added to C by Objective-C. Then, I make sure to tell the students never to use it ever, ever, ever again. Buy why? To keep our code consistent and maintain readability.</p>
<h3>The Intent of Code</h3>
<p>When we look at well written C code, we can tell exactly what is going on by glancing at it. That&#8217;s the power that C gives us. If I want to take a drink of water while doing a cartwheel, I call the function:</p>
<blockquote><p><code>drink(water, TRUE);</code></p></blockquote>
<p>We know <em>exactly</em> what that means. There is no room for interpretation. It is pure, simple, and good, just as Jesus intended.</p>
<h3>Then comes Objective-C&#8230;</h3>
<p>Objective-C comes along, sprinkling diabetes-inducing syntactic sugar all over our code. We wind up having to read code like this:</p>
<blockquote><p><code>x = [foo value];</code></p></blockquote>
<p>What is that? Can anybody interpret that? Of course not! That&#8217;s because the compiler could translate it into a call to any one of the functions <code>objc_msgSend</code>, <code>objc_msgSend_fpret</code>, or <code>objc_msgSend_stret</code>. But we have no way of telling which one! It&#8217;s impossible! For all we know, the compiler just picks one at random!</p>
<p>It&#8217;s incredibly confusing, which is why I recommend that students exclusively call those C functions directly, so there is no doubt about which one is being called. That way the code is readable.</p>
<h3>But I&#8217;m used to Smalltalk. Bracket notation looks like I&#8217;m at home!</h3>
<p>You are not at home. You&#8217;re in the forest, and wolves are trying to kill you.</p>
<h3>Apple uses it in their sample code, though!</h3>
<p>That&#8217;s right, they do. But should you really be trying to emulate Apple? Have you heard about the App Store review process? They are totally incompetent and can&#8217;t do anything!</p>
<p>In the end, there is a wrong way and a right way to write Objective-C code. I will not say that using brackets is wrong, even though I tell my students never ever to use it. Is that confusing? Not as confusing as brackets are.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/270/bracket-notation-syntax/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>App Store Reviewer Incentives</title>
		<link>http://www.benzado.com/blog/post/268/app-store-reviewer-incentives</link>
		<comments>http://www.benzado.com/blog/post/268/app-store-reviewer-incentives#comments</comments>
		<pubDate>Sat, 08 Aug 2009 17:28:27 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=268</guid>
		<description><![CDATA[I think Daniel Jalkut has it backwards: Many of the mercenary testers I encountered were motivated to scrape the system for bugs, as ridiculous as they may be. They logged them into the bug system and then defended them at all costs, as if their lives depended on it. And it turned out, they did. [...]]]></description>
			<content:encoded><![CDATA[<p>I think <a href="http://www.red-sweater.com/blog/872/app-store-mercenaries">Daniel Jalkut has it backwards</a>:</p>
<blockquote><p>Many of the mercenary testers I encountered were motivated to scrape the system for bugs, as ridiculous as they may be. They logged them into the bug system and then defended them at all costs, as if their lives depended on it. And it turned out, they did. At least, their paychecks did.</p>
<p>I would not be surprised to learn that App Store reviewers are working under a similar structure. A system that rewards “unique, valid rejections” would certainly explain the behavior we have seen coming to light in the past year.</p></blockquote>
<p>QA teams, like the ones Daniel writes about, reward &#8220;unique, valid bug reports&#8221; because all the testers are testing the same piece of software. If a group of testers repeatedly file duplicate bug reports, clearly you have an inefficient team, and can afford to let some of them go. The team has an incentive to reward unique reports.</p>
<p>The App Store review team, on the other hand, has one reviewer per app, and each app is different. Even if the team was perversely trying to justify its existence by beefing up its rejection numbers, there would be no need to come up with &#8220;unique, valid rejections.&#8221; In that case it would be more efficient for them to reject apps with increasingly vague reasons, or no reason at all.</p>
<p>It is more likely that reviewers are severely punished (i.e., fired) for approving an app that later causes a problem. That&#8217;s the kind of situation that leads to overzealous reviewers without assuming that management is dumb.</p>
<p>And there are problems: all the writing on the Ninjawords rejection pits Apple against enlightened liberal people. Not pictured are the parents who have purchased an iPod touch for their young child and want to let them download games from the App Store, but maybe don&#8217;t want to let them downloading Motorboat, which is not actually about boats, but involves rubbing your nose on the touchscreen.</p>
<p>When Apple added ratings to the App Store, it did not do so in a vacuum. It has quite a few customers with children, who I suspect express themselves by making phone calls instead of posting on blogs. So while we&#8217;ve read a lot about the helpless developers who are being persecuted by puritannical Apple, we haven&#8217;t read the testimony of parents who are trying to give their child a little bit of freedom without having to worry that they will get the idea that sticking your nose in a woman&#8217;s cleavage is an acceptable thing to talk about during Thanksgiving dinner.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/268/app-store-reviewer-incentives/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I cannot fix your Windows computer</title>
		<link>http://www.benzado.com/blog/post/240/microsoft-windows</link>
		<comments>http://www.benzado.com/blog/post/240/microsoft-windows#comments</comments>
		<pubDate>Tue, 16 Jun 2009 19:19:57 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=240</guid>
		<description><![CDATA[A friend asked me to help fix her computer. It&#8217;s a Dell laptop running Windows XP Home and it became infected with a virus. She was able to partially remove the virus, and I helped her remove the rest of it, but now the infamous Blue Screen of Death appears about a minute after booting [...]]]></description>
			<content:encoded><![CDATA[<p>A friend asked me to help fix her computer. It&#8217;s a Dell laptop running Windows XP Home and it became infected with a virus. She was able to partially remove the virus, and I helped her remove the rest of it, but now the infamous Blue Screen of Death appears about a minute after booting into anything other than Safe Mode.</p>
<p>It wasn&#8217;t obvious what was causing the crashes, but I found out I could use a Microsoft Debugging utility to read the memory dump files that Windows creates on each crash. I offered to take the computer home with me, so I could plug it into a network and install the utility and finish the job.</p>
<p>Booting into &#8220;Safe Mode with Networking&#8221; worked, so I was able to download the utility, but I was not able to install it. I was told, &#8220;The System Administrator has set policies to prevent this installation.&#8221; That was confusing, because I logged in using the <em>fucking system administrator account</em>. Now I am pretty sure that the error message is inaccurate, because some lazy asshole at Microsoft decided to use that very specific text as a generic &#8220;operation failed&#8221; message.</p>
<p>It turns out that the installer program requires the Installer Service to be running, but the Service cannot be started in Safe Mode. So, if I want to use the debugging tools, I am caught in a catch-22: the computer will crash if I don&#8217;t use Safe Mode, but I can&#8217;t diagnose the crashes if I do use Safe Mode.</p>
<p>After chasing my own tail for longer than I&#8217;d like to admit, I realized I could try finding some other tool to extract the utility from the installer package. I found such a tool, and in the process I learned that MSI archives are apparently unable to store file extensions, so when you unpack them, you have to manually insert the dot in hundreds of file names. I do this for a subset of the files that seem necessary to run the diagnostic program, and finally, I get it to run.</p>
<p>At least, I think I do. It outputs a lot of error messages, but the instructions I am following from some sketchy website say it is normal to see a lot of messages, so I have no clue if it&#8217;s working or if I need to add more dots to more filenames. I blindly forge ahead, and finally get it to generate a report from one of the memory dump files.</p>
<p>The goal, in case you&#8217;ve forgotten, is to find out what is responsible for crashing the kernel. The report indicates the memory location where the crash occurs: Good. It also contains a list of loaded drivers and what memory locations they occupy: Good. So I scan the list to find the culprit. While every other line has a driver name, this one has the name &#8220;00001b6f&#8221; or something like that. No name, just a hexadecimal number without context. WTF?</p>
<p>So, I give up.</p>
<p>To be clear, I&#8217;m not just giving up on this job, but <strong>I&#8217;m giving up on ever attempting to &#8220;fix&#8221; a computer running Microsoft Windows ever again.</strong> It&#8217;s been so long since I used one regularly that I&#8217;m no longer familiar with all the voodoo incantations required to make them work. The only thing my technical knowledge buys me is a misleading sense of being &#8220;one step closer&#8221; when in fact I am running in circles. It is painful and frustrating and humiliating. I honestly feel like I&#8217;m the butt of a joke right now. Like I&#8217;ve spent four hours trying to catch a pig on a dare.</p>
<p>By taking this computer home, I thought I was doing a favor for a friend, but now I realize that she has done a favor for me. I&#8217;ve learned a lesson. I&#8217;m sorry, I can&#8217;t fix your computer, I don&#8217;t know how.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/240/microsoft-windows/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>mkbuild, an iPhone project build script</title>
		<link>http://www.benzado.com/blog/post/202/mkbuild</link>
		<comments>http://www.benzado.com/blog/post/202/mkbuild#comments</comments>
		<pubDate>Sat, 28 Feb 2009 02:39:23 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=202</guid>
		<description><![CDATA[When I wrote &#8220;Good Practices: iPhone Development&#8220;, I promised to share the script I wrote to create numbered builds of iPhone applications. I am certain that I am not the only programmer who feels uncomfortable sharing source code until it is ready (i.e., Perfect), but we must not forget that Real Artists Ship. This is a [...]]]></description>
			<content:encoded><![CDATA[<p>When I wrote &#8220;<a href="http://www.benzado.com/blog/iphonedev-good-practices">Good Practices: iPhone Development</a>&#8220;, I promised to share the script I wrote to create numbered builds of iPhone applications. I am certain that I am not the only programmer who feels uncomfortable sharing source code until it is ready (i.e., Perfect), but we must not forget that <a href="http://www.folklore.org/StoryView.py?story=Real_Artists_Ship.txt">Real Artists Ship</a>. This is a long winded way of saying that <strong>I finally cleaned up my build script and made it available for downl</strong><strong>oad.</strong></p>
<p>The impatient can get it here: <a href="http://www.benzado.com/code/mkbuild.zip">mkbuild.zip</a></p>
<p>The basic idea is that you create a build-config.sh file with some instructions on how to build your particular project, place it into a checked-out working copy of your project, and run mkbuild.sh from within the same directory. When you ask it to create a new build (mkbuild.sh new), it will:</p>
<ol>
<li>Tag your repository with a build number (e.g., build-0023).</li>
<li>Export that tag to a RAM disk.</li>
<li>Compile and package your app as instructed by the configuration file.</li>
<li>Destroy the RAM disk.</li>
</ol>
<p>I like using RAM disks for this sort of thing, since there is no doubt the build is clean.</p>
<p>The build number is always a four digit, monotonically increasing integer. When you make a new build, the script scans your existing tags and <strong>automatically determines the next available build number</strong>. I briefly experimented with <a href="http://www.red-sweater.com/blog/23/automatic-build-sub-versioning-in-xcode">using the repository revision number</a>, but decided it would be better to decouple the build numbering from the revision control system used.</p>
<p>That turned out to be a good move, because although I developed the script to work against a Subversion repository, I made a git version for a different project I worked on. I have since merged the two, so the mkbuild.sh script <strong>will talk to either Subversion or git</strong>, depending on how you configure it.</p>
<p>Here is a summary of the operations it supports:</p>
<ul>
<li><strong>mkbuild.sh new</strong> creates a new build</li>
<li><strong>mkbuild.sh rebuild </strong><em><strong>n</strong></em> recreates build <em>n</em>, in case you deleted it</li>
<li><strong>mkbuild.sh log </strong><em><strong>n</strong></em> prints changes between build <em>n</em> and build <em>n</em> &#8211; 1</li>
<li><strong>mkbuild.sh log </strong><em><strong>n</strong></em><strong> </strong><em><strong>m</strong></em> prints changes between build <em>n</em> and build <em>m</em></li>
<li><strong>mkbuild.sh list</strong> lists all builds in the repository</li>
<li><strong>mkbuild.sh archive </strong><em><strong>n</strong></em> creates a zip file of the source of build <em>n</em></li>
</ul>
<p>Everywhere it asks for a build number, you can specify 3 and it will automatically interpret that as 0003.</p>
<p>Although I wrote the script to simplify iPhone project builds, it could be easily adapted to handle any Xcode project.</p>
<p><strong>Please try it out and let me know what you think.</strong> <a href="http://www.benzado.com/code/mkbuild.zip">This link</a> will always redirect you to the latest version and I&#8217;ll make previous versions available <a href="http://www.benzado.com/code/">here</a>. Since the script will tag your repository, be responsible and make a backup before you start experimenting. The zip file contains a sample configuration file and there is documentation is in the script source itself.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/202/mkbuild/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
