<?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>Red Sweater Blog &#187; Carbon</title>
	<atom:link href="http://www.red-sweater.com/blog/category/articles/programming/carbon/feed" rel="self" type="application/rss+xml" />
	<link>http://www.red-sweater.com/blog</link>
	<description>Mac &#38; Technology Writings by Daniel Jalkut</description>
	<lastBuildDate>Tue, 17 Jan 2012 22:03:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>Crappy Crash Logs</title>
		<link>http://www.red-sweater.com/blog/439/crappy-crash-logs</link>
		<comments>http://www.red-sweater.com/blog/439/crappy-crash-logs#comments</comments>
		<pubDate>Thu, 06 Dec 2007 19:47:07 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/439/crappy-crash-logs</guid>
		<description><![CDATA[Developers who write code inevitably write code that crashes. Luckily for our users, 99% of those crashes happen on our own development machines, and we get the opportunity to fix them before shipping them off to our unsuspecting computers. But every once in a while even the most polished and refined software exhibits that nastiest [...]]]></description>
			<content:encoded><![CDATA[<p>Developers who write code inevitably write code that crashes. Luckily for our users, 99% of those crashes happen on our own development machines, and we get the opportunity to fix them before shipping them off to our unsuspecting computers.</p>
<p>
But every once in a while even the most polished and refined software exhibits that nastiest of malfunctions: the crashing bug. In the middle of a possibly important user task, the application comes screeching to a halt and disappears, leaving the user with nothing more than a cryptic message from the operating system, along with an offer to send the crash log off to Apple.
</p>
<p>
<img src="http://www.red-sweater.com/blog/images/CrashDialog-20071206-131213.jpg" />
</p>
<p>
Needless to say, crashes suck. A lot. For users, especially. If there&#8217;s one behavior of your application that you should focus on eliminating, it&#8217;s the behavior of crashing. Above all other &#8220;nuisances,&#8221; this is the one that is absolutely unacceptable.
</p>
<p>
Which is why crash logs are so important. Occasionally, when a user is sophisticated enough to understand the value of the crash log and, instead of choosing to send it to Apple, copies and pastes it into an email to you, you should be overjoyed! Finally! A  crash has been captured in the wild and delivered to you for easy inspection. This artifact not only proves that a crashing bug exists, but usually includes highly detailed information about where and how the crash has happened.
</p>
<p>
Which is why it boggles the mind to think that some developers see these crash logs as relatively useless. In my own experience of reporting bugs to other developers, I have found frequently that my crash log is considered more as a statistic than as a specimen. While I expect a response like &#8220;great, I see what the bug is, and I&#8217;ll get this fixed,&#8221; I often get responses more like &#8220;sigh, I&#8217;ve seen this a few times but have no idea what&#8217;s going on!&#8221;
</p>
<p>
Sometimes I find that the developer in question simply needs to be educated about the tools at his or her disposal. I imagine the hours wasted speculating about what the crash log means, and can&#8217;t help but think if they knew how to analyze it, they  could have the bug solved (in many cases) in moments. Oh &#8211; and I&#8217;m sounding high and mighty right now, so before I get too carried away, let me just say that <em>I too need to be educated on a great many things</em>, but making sense of crash logs is not particularly high on that list. I leave it to other bloggers to fill in the gaps of my education.</p>
<h3>Crash Logs: The Crappy Way</h3>
</p>
<p>
So what is this big thing that developers are missing? Well, a crash log essentially shows the &#8220;path&#8221; that the little hamsters in your computer were running on when they fell off the cliff. It paints a picture of where the program got misguided and went off doing something it never should have done. Problem is, the picture is a little blurry. Below is an actual crash log submitted by an actual MarsEdit user (abbreviated and condensed to fit the blog):
</p>
<p><pre style="font-size:1em;">
Thread 0 Crashed:
Foundation 0x93cc2a2e _NSAPAddPage + 94
Foundation 0x93cc3b27 __NSAutoreleaseObject + 263
Foundation 0x93cc3962 -[NSObject(NSObject) autorelease] + 18
Foundation 0x93cceaca +[NSString stringWithFormat:] + 106
marsedit   0x000637fb 0x1000 + 403451
marsedit   0x00053883 0x1000 + 338051
marsedit   0x000539ea 0x1000 + 338410
marsedit   0x00053d7b 0x1000 + 339323
marsedit   0x00053e45 0x1000 + 339525
marsedit   0x0005238b 0x1000 + 332683
</pre>
</p>
<p>
For any non-programmers who are still reading (bravi!), you may have a little trouble understanding what the heck this means. This is an ordered description of the path the computer followed while trying to do <em>something</em>. Problem is it ended up crashing. The path is shown in reverse-order, so the crash is at the top of the list, inside Foundation (an Apple system library). Trying to make human sense of this goes something like this:
</p>
<ol>
<li>Something in MarsEdit at address 0x0005238b&#8230;</li>
<li>&#8230; called something in MarsEdit at address 0x00053e45 </li>
<li>&#8230; called something in MarsEdit at address 0x00053d7b </li>
<li>&#8230; called something in MarsEdit at address 0x000539ea </li>
<li>&#8230; called something in MarsEdit at address 0&#215;00053883 </li>
<li>&#8230; called something in MarsEdit at address 0x000637fb </li>
<li>&#8230; which called a standard string library method &#8220;stringWithFormat&#8221;</li>
<li>which eventually crashed in the system.</li>
</ol>
<p>
You can sort of see how some developers are forced to throw up their arms in despair, right? But what if you could turn this muddled picture into something a bit sharper? The fact is, you can. The reason the picture is so blurry is because MarsEdit shipped without debugging symbols. The reasons for this are mostly to keep the shipping application as small as possible, but there are also some good reasons to hide the symbols if they reveal too much about your business strategy.</p>
<h3>Crash Logs: The Happy Way</h3>
</p>
<p>
Many developers seem to think that gathering useful crash logs requires shipping a symbol-laden application, but aren&#8217;t willing to do so. The fact is, you can have the best of both worlds by shipping a symbol-stripped version of your application, but <em>keeping a symbol-laden version</em> on-hand for the developer&#8217;s convenience.
</p>
<p>
What am I getting at? Apple offers a tool called &#8220;atos&#8221;, which makes it relatively easy to map an address from a symbol-stripped application to a name in a symbol-laden version of that same application.  As long as the two applications were built with the same sources and using the same build options, the addresses are bound to match up. It&#8217;s just the symbols that are &#8220;stripped&#8221; from the shipping application.
</p>
<p>
Let&#8217;s take a look at what happens when I apply my atos powers to the crash log I pasted above. From the Terminal, I invoke atos with the literal memory addresses of all the mysterious points in the &#8220;path&#8221; from the crash log. You can list the addresses in whatever order you want, but I&#8217;m listing them so that the result will be in order from top to bottom, the same way I reasoned out the crash in plain &#8220;crappy&#8221; English above:
</p>
<p><pre style="font-size:1em;">
iBook> cd MarsEdit.app/Contents/MacOS
iBook> atos -arch i386 -o MarsEdit \
	0x0005238b 0x00053e45 0x00053d7b 0x000539ea 0x00053883 0x000637fb
</pre>
</p>
<p>
Note also that I specified the architecture explicitly. This is because I am debugging this on a PowerPC Mac, but the crash log I received showed that the customer is running on an Intel machine. This yields a magical response with, behold, real meaningful symbols!</p>
<pre style="font-size:1em;">
-[RSXMLRPCCall invoke:] (in MarsEdit) (RSXMLRPCCall.m:397)
-[RSXMLRPCRequest requestText] (in MarsEdit) (RSXMLRPCRequest.m:239)
-[RSXMLRPCRequest serializeParams:] (in MarsEdit) (RSXMLRPCRequest.m:216)
-[RSXMLRPCRequest serializeDictionary:toString:] (in MarsEdit) (RSXMLRPCRequest.m:153)
-[RSXMLRPCRequest serializeData:toString:] (in MarsEdit) (RSXMLRPCRequest.m:123)
-[NSData(extras) base64StringWithLineLength:] (in MarsEdit) (NSData+extras.m:215)
</pre>
</p>
<p>
Now I can apply my human sense again, but with the  benefit of symbolic names instead of raw memory addresses:
</p>
<ol>
<li>MarsEdit invoked an RPC network request</li>
<li>&#8230; which while building the actual request cargo text</li>
<li>&#8230; was trying to serialize the parameters</li>
<li>&#8230; when it tried to serialize a dictionary object</li>
<li>&#8230; whose data</li>
<li>&#8230; upon being converted to a Base64 representation</li>
<li>&#8230; caused a &#8220;stringWithFormat:&#8221; call that went blammo!</li>
</ol>
<p>
Not only does the plot to this story make a lot more sense now, but I&#8217;ve even got handy pointers to the line numbers in the source code. Let&#8217;s see, NSData+extras.m, around line 215:
</p>
<p><pre style="font-size:1em;">
NSString *charString = [NSString stringWithFormat:@"%c", base64EncodingTable [outbuf [i]]];
</pre>
</p>
<p>
Survey says? That&#8217;s the line I&#8217;m going to zero in on now as I try to figure out <em>why</em> this crash is occurring. Sure, I&#8217;ll have to now speculate as to why, and under what circumstances the observed crash might occur. So the magic of &#8220;atos&#8221; doesn&#8217;t take all the work out of debugging a crash log, but it brings most crashes out of the &#8220;frustratingly impossible&#8221; into the realm of &#8220;all in a day&#8217;s work.&#8221; I can use my knowledge of the situation to ask intelligent questions of the user, and hopefully get to the bottom of it, so that no other user ever has to see the nasty crash again.
</p>
<p>
I can do more than just tell the user &#8220;thanks for the report, I have no clue what&#8217;s happening here. Sorry.&#8221;</p>
<h3>Doing It For Yourself</h3>
</p>
<p>
I hope I&#8217;ve intrigued you by the power of what I was able to achieve with &#8220;atos&#8221;, but of course to do the same with your own project, you&#8217;ll need to make sure you can come up with a &#8220;symbol-laden version&#8221; of your release app, so you can apply the same magic. The best way I know to do this is to simply add another build configuration in xcode, that is just like your &#8220;Release&#8221; configuration, but doesn&#8217;t strip out debugging symbols. You can read more about this approach and others in <a href="http://developer.apple.com/tools/xcode/symbolizingcrashdumps.html">Apple&#8217;s fine documentation</a>.
</p>
<p>
If you find yourself dealing with crash logs on a regular basis, it might be a good idea to make building a &#8220;symbol-laden&#8221; version of your app part of the standard build and distribute process. For myself, I&#8217;ve found it happens rarely enough that I&#8217;m happy with a process whereby I re-checkout a tagged version of the sources from Subversion, and then rebuild a copy using the &#8220;Release With Symbols&#8221; build configuration.
</p>
<p>
Nota Bene: If you&#8217;re on Leopard and trying to replicate a symbol-laden version of an app you shipped with Tiger, you&#8217;ll probably have to tweak Xcode to use the old linker, in order to get a build whose memory addresses match up with your old Tiger-built application. Might be easier to just go back to Tiger and rebuild it there.
</p>
<p>
I know this was probably common knowledge for some of you, but I also know from experience of chatting with my colleagues that this is completely new, forehead-slapping &#8220;why didn&#8217;t I know about that?!&#8221; type material for many others. I hope it saves you hours of work. Possibly even enough hours to continue reading long articles such as this one!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/439/crappy-crash-logs/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Iron Coder 7</title>
		<link>http://www.red-sweater.com/blog/431/iron-coder-7</link>
		<comments>http://www.red-sweater.com/blog/431/iron-coder-7#comments</comments>
		<pubDate>Fri, 02 Nov 2007 19:03:26 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Indie]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/431/iron-coder-7</guid>
		<description><![CDATA[Iron Coder 7 is coming up, and Jonathan Wight just announced that the top prize will be an iPod Touch! In other news the contest will run over the course of a week this time around, instead of the usual 48 hours. I am going to need something to develop my iPhone/iPod applications on pretty [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://ironcoder.org/blog/2007/11/02/ironcoder-7-bigger-better-and-uncut/">Iron Coder 7</a> is coming up, and Jonathan Wight just announced that the top prize will be an iPod Touch! In other news the contest will run  over the course of a week this time around, instead of the usual 48 hours.</p>
<p>
I <em>am</em> going to need something to develop my iPhone/iPod applications on pretty soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/431/iron-coder-7/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2007 MacTech 25</title>
		<link>http://www.red-sweater.com/blog/348/2007-mactech-25</link>
		<comments>http://www.red-sweater.com/blog/348/2007-mactech-25#comments</comments>
		<pubDate>Wed, 06 Jun 2007 19:34:25 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/348/2007-mactech-25</guid>
		<description><![CDATA[The results are in for the 2007 MacTech 25, a community-selected list of the 25 &#8220;most influential&#8221; members of the Mac community. (Apple employees are not eligible, or else the list would probably look a lot different!) I couldn&#8217;t be more thrilled, because not only does the list include everybody I suggested as good candidates, [...]]]></description>
			<content:encoded><![CDATA[<p>The results are in for the <a href="http://www.mactech.com/articles/mactech/Vol.23/23.06/2007MacTech25/">2007 MacTech 25</a>, a community-selected list of the 25 &#8220;most influential&#8221; members of the Mac community. (Apple employees are not eligible, or else the list would probably look a lot different!)</p>
<p>
I couldn&#8217;t be more thrilled, because not only does the list include <em>everybody</em> I <a href="http://www.red-sweater.com/blog/311/who-influences-you">suggested</a> as good candidates, it also includes me!
</p>
<p>
I&#8217;m particularly happy to share the honor with so many people I have so much respect for. I would try to itemize them but there are just so many that I am still in awe of actually being listed among them. Many thanks to those who voted for me. It feels great to be recognized, and I&#8217;m glad if it means I&#8217;ve had a positive influence on you.
</p>
<p>
I would also like to point out that <em><a href="http://inessential.com/">everybody</a> who has <a href="http://gusmueller.com/">programmed</a> for MarsEdit</em> is on the MacTech 25 list this year :) This project has the golden touch!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/348/2007-mactech-25/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Iron Coder V Winner: Ben Gottlieb</title>
		<link>http://www.red-sweater.com/blog/315/iron-coder-v-winner-ben-gottlieb</link>
		<comments>http://www.red-sweater.com/blog/315/iron-coder-v-winner-ben-gottlieb#comments</comments>
		<pubDate>Tue, 03 Apr 2007 14:26:40 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/315/iron-coder-v-winner-ben-gottlieb</guid>
		<description><![CDATA[Another Iron Coder weekend is wrapped up officially, as this round&#8217;s judge Jon Wight announced on the Iron Coder Blog. Ben Gottlieb won with his WikiPath screensaver. Congratulations, Ben! My entry received an honorable mention as the &#8220;Best Non-Screensaver.&#8221; I thought everybody would do a screensaver, and I should try to be a little different. [...]]]></description>
			<content:encoded><![CDATA[<p>Another Iron Coder weekend is wrapped up officially, as this round&#8217;s judge <a href="http://www.toxicsoftware.com/">Jon Wight</a> announced on the <a href="http://ironcoder.org/blog/2007/04/03/ironcoder-v-winner-wikipath/">Iron Coder Blog</a>. Ben Gottlieb won with his <a href="http://ironcoder.org/entries/ironcoder_5/Wikipath.dmg">WikiPath</a> screensaver. Congratulations, Ben!</p>
<p>
My entry received an honorable mention as the &#8220;Best Non-Screensaver.&#8221; I thought everybody would do a screensaver, and I should try to be a little different. <a href="http://ironcoder.org/entries/ironcoder_5/Viva.zip">Viva</a> is an application that lets you tile multiple screensavers on your desktop. Fun times. But run the app before you run the .saver &#8211; there&#8217;s a bug.
</p>
<p>
Big thanks to Jon for sacrificing many hours and making the difficult decisions as judge.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/315/iron-coder-v-winner-ben-gottlieb/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Iron Coder V</title>
		<link>http://www.red-sweater.com/blog/312/iron-coder-v</link>
		<comments>http://www.red-sweater.com/blog/312/iron-coder-v#comments</comments>
		<pubDate>Tue, 27 Mar 2007 21:43:07 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/312/iron-coder-v</guid>
		<description><![CDATA[If you&#8217;ve been sitting on the fence about whether to participate in Iron Coder, maybe this will push you over the edge. Just announced: the winner of Iron Coder V will receive free admission to C4[1]! Start your engines lady and gentleman coders, get ye to the Iron Coder starting line this Friday evening!.]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve been sitting on the fence about whether to participate in <a href="http://ironcoder.org/blog/2007/02/26/ironcoder-v-march-30-april-1">Iron Coder</a>, maybe this will push you over the edge. Just announced: the winner of Iron Coder V will receive <a href="http://rentzsch.com/c4/ironCoderToTheMetal">free admission</a> to C4[1]!</p>
<p>
Start your engines lady and gentleman coders, get ye to the Iron Coder starting line <em>this Friday evening!</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/312/iron-coder-v/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Who Influences You?</title>
		<link>http://www.red-sweater.com/blog/311/who-influences-you</link>
		<comments>http://www.red-sweater.com/blog/311/who-influences-you#comments</comments>
		<pubDate>Mon, 26 Mar 2007 21:15:00 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/311/who-influences-you</guid>
		<description><![CDATA[MacTech is running their annual voting process for the People&#8217;s Choice MacTech 25. This is basically an opportunity to recognize some of the important members of our technical community. While most of the world is more interested in the highest ranking members of the Macintosh community (people like Steve Jobs), we developers and technical types [...]]]></description>
			<content:encoded><![CDATA[<p>MacTech is running their annual voting process for the <a href="http://www.mactech.com/mostinfluential/">People&#8217;s Choice MacTech 25</a>. This is basically an opportunity to recognize some of the important members of our technical community. While most of the world is more interested in the <em>highest ranking</em> members of the Macintosh community (people like Steve Jobs), we developers and technical types who live on the front-lines probably appreciate the actions of more day-to-day leaders. People whose projects or community presence helps us to do our jobs or appreciate the platform we work on.</p>
<p>
Sooo&#8230; I&#8217;m encouraging anybody who hasn&#8217;t voted yet to do so, and to vote for people who <em>influence you directly</em>. I voted for three people from among the following names which I present merely as memory toggles for you. The problem here of course is I&#8217;m sure I&#8217;ll forget somebody. But at the very least I feel comfortable proposing any of these names as worthy recipients for an honor such as this. These names all strike me as being particularly appropriate <em>this year</em>. All of these people go out of their way to develop a personal relationship with the community <em>on top of</em> a professional relationship. Any three of them are deserving of your vote:
</p>
<p>
<a href="http://daringfireball.net/">John Gruber</a>. I probably don&#8217;t have to convince most of you that John is an influential part of our lives. Whether you read his content or not, his opinions push developers, users, and the press to reconsider their views on all things Mac. This past year was an especially influential year for Gruber, having dropped some serious food for thought in his <a href="http://www.red-sweater.com/blog/215/build-your-own-damn-hig">HIG Is Dead</a> speech at the <a href="http://c4.rentzsch.com/">C4 Conference</a>.
</p>
<p>
<a href="http://www.bignerdranch.com/instructors/hillegass.shtml">Aaron Hillegass</a>. Every year, Aaron&#8217;s <a href="http://www.bignerdranch.com/">Big Nerd Ranch</a> &#8220;vacation&#8221; boot-camp for aspiring Cocoa developers churns out a new batch of programmers freshly-versed in the &#8220;right atittudes&#8221; to get started programming on the Mac. My belief is that more developers on the Mac will ultimately make all developers on the Mac more successful and happy. We&#8217;ve got a great community, and as new members are successfully indoctrinated into the group, our shared resources become larger and larger. I expect that as the years go by, more and more of the Mac developers you meet socially will have in their pedigree some kind of training from Aaron and the rest of the staff at Big Nerd Ranch.
</p>
<p>
<a href="http://www.rogueamoeba.com/utm/">Paul Kafasis</a>. As CEO of <a href="http://www.rogueamoeba.com/">Rogue Amoeba</a>, Paul has had his hands full. But he still found time over the past year to write several thought-provoking commentaries on the Rogue Amoeba blog, prompting debate about terms like &#8220;Delicious Generation.&#8221; He also serves up repeated doses of &#8220;good indie software sense&#8221; in blog series such as <a href="http://www.rogueamoeba.com/utm/posts/Article/MWSF-Costs-2007-01-16-09-00.html">Should I Exhibit At MacWorld</a>. On a personal note, Paul&#8217;s advice to me has been invaluable as I&#8217;ve gotten to know him and tried to learn from his experiences in successfuly building Rogue Amoeba into a robust young business.
</p>
<p>
<a href="http://leoville.com/">Leo Laporte</a>.I grew up listening to Leo on SF Bay Area radio. At the time I was more into Amigas and Sun Workstations than Macs, but I still found Leo&#8217;s show fascinating. The fact that all these years later I&#8217;m still listening to him, and he&#8217;s still pushing the Mac, is pretty awesome. Leo&#8217;s <a href="http://www.twit.tv/TWiT">This Week In Tech</a> podcast is the most popular tech show online, and his empire continues to grow as he adds other podcasts, videocasts, and satellite radio to the collection. Most of Laporte&#8217;s shows are not Mac-focused, but he always has Mac in his mental repertoire, which no doubt leads many of his listeners to consider giving the Mac a shot. More Mac users equals more Mac customers. And that&#8217;s good for the developer world.
</p>
<p>
<a href="http://merlinmann.com/">Merlin Mann</a>. Merlin Mann tirelessly (OK, I&#8217;m sure he gets tired!) promotes the Mac as tool numero uno in the battle against productivity failures. Through his world-famous <a href="http://43folders.com/">43 Folders</a> blog, he uses his playful writing style to remind the world that there are tricks and techniques to an organized life, and that the best ones require a Mac. Merlin&#8217;s influence on productivity software can be witnessed by the growing trend for &#8220;Getting Things Done&#8221; applications. As advisor to <a href="http://www.omnigroup.com/">The Omni Group</a> during the development of their &#8220;OmniFocus&#8221; GTD application, his opinions will no-doubt help establish some of the standards for all such software in the future. Merlin Mann is also an integral part of the Leo Laporte podcast <a href="http://www.twit.tv/mbw/">MacBreak Weekly</a>, the one show in Laporte&#8217;s empire which is dedicated to Mac and Mac alone.
</p>
<p>
<a href="http://rentzsch.com/">Jonathan &#8220;Wolf&#8221; Rentzsch</a>. Wolf has been personally influential to me for a few years now, as his work within the developer community on projects like <a href="http://rentzsch.com/mach_inject/">mach_inject</a> have made him well-known as a highly skilled Mac OS X developer and consultant. But this past year, Wolf turned the corner and became incredibly influential by launching a new Mac developer conference called <a href="http://c4.rentzsch.com/">C4</a>. Even in its maiden year, the conference left attendees unanimously satisfied and eager to return for more fun and englightenment in the coming years. Wolf has been working hard on planning the 2nd C4, and I&#8217;m sure his influence will continue to grow as the conference becomes even more renowned.
</p>
<p>
<a href="http://www.inessential.com/">Brent Simmons</a>. What can I say, the man had a huge impact on me this year :) As the person who was instrumental in putting me on NewsGator&#8217;s radar as a potential buyer for MarsEdit, I am very grateful to him. He also deserves your vote because of the ways in which he helps to define the Macintosh user experience through his development of NetNewsWire, and through his participation in the developer/user communities.
</p>
<p>
<a href="http://theocacao.com/">Scott Stevenson</a>. Scott Stevenson has long been a valuable resource in the Cocoa community in particular, serving up delicious tutorials on his <a href="http://www.cocoadevcentral.com/">Cocoa Dev Central</a> site. He upped the ante recently by adding an editorialized take on the world of Cocoa blogging, in his <a href="http://cocoablogs.com/">Cocoa Blogs</a> digest. Scott&#8217;s writing style combined with his passion for the Mac and an ability to spot quality are turning his content into the first-stop for quality Mac development information.
</p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/311/who-influences-you/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Xcode Pasteboard Accumulator</title>
		<link>http://www.red-sweater.com/blog/269/xcode-pasteboard-accumulator</link>
		<comments>http://www.red-sweater.com/blog/269/xcode-pasteboard-accumulator#comments</comments>
		<pubDate>Thu, 01 Feb 2007 23:17:04 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Usability]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/269/xcode-pasteboard-accumulator</guid>
		<description><![CDATA[Way back in the MPW days, I used to rely heavily on an extension for the IDE that put powerful pasteboard manipulation tools in the window header. Essentially these tools let you treat your pasteboard like a stack, so you could easily accumulate multiple copies and then paste them all out at once. For some [...]]]></description>
			<content:encoded><![CDATA[<p>Way back in the <a href="http://developer.apple.com/tools/mpw-tools/">MPW</a> days, I used to rely heavily on an extension for the IDE that put powerful pasteboard manipulation tools in the window header. Essentially these tools let you treat your pasteboard like a stack, so you could easily accumulate multiple copies and then paste them all out at once.</p>
<p>
For some dumb reason, I&#8217;ve been living without such conveniences for several years now. I know there are many 3rd party products that add an epic amount of functionality to the standard copy and paste of the system, but I&#8217;m not really interested in running a separate application for this purpose.
</p>
<p>
It occurred to me that this would be a perfect use of Xcode&#8217;s <a href="http://developer.apple.com/documentation/DeveloperTools/Conceptual/XcodeUserGuide/Contents/Resources/en.lproj/07_03_custom_scripts/chapter_48_section_4.html">Menu Scripts</a>. Xcode not only supports the addition of custom scripts to the menu bar, but supports a unique format by which the scripts can advertise keyboard shortcuts, and integrate seamlessly with Xcode&#8217;s text editor. For instance, you can use a script to process the selected text in Xcode and spit back out something else in its place.
</p>
<p>
<a href="http://www.red-sweater.com/blog/downloads/AppendToPasteBoard.zip">Append To Pasteboard</a> is a simple python script that takes advantage of the &#8220;pbcopy&#8221; and &#8220;pbpaste&#8221; commands to tack whatever you&#8217;ve selected in Xcode on to the end of the existing pasteboard. You stick this within your (horribly located) user scripts folder, where you must name the folders and files with numeric prefixes to inform Xcode where they belong. For example, the script lives in my home directory:
</p>
<p><pre>
/Users/daniel/Library/Application Support/
	Apple/Developer Tools/Scripts/
	10-User Scripts/1-DCJ/
</pre>
</p>
<p>
Unfortunately Xcode doesn&#8217;t handle the situation where some scripts come from your home directory, and some come from the /Library installation directory. So I put everything in my home directory. The &#8220;10-User Scripts&#8221; is how I tell it to name the menu bar item &#8220;User Scripts.&#8221; The &#8220;1-DCJ&#8221; folder is the folder with all my custom scripts in it, and since it is &#8220;1,&#8221; it comes before all of Apple&#8217;s standard scripts that I copied in (10-Open, 20-Search, etc). The process of providing scripts to Xcode is ugly but when you finally get it all put together, this is what you end up with:
</p>
<p>
<img src="http://www.red-sweater.com/blog/images/AppendToPasteboard.png"/>
</p>
<p>
Now it&#8217;s a snap to cruise through a .m and accumulate method declarations, for pasting into a corresponding .h. Note that the script always appends a newline to the existing pasteboard, which could be annoying depending on what you want to use it for. Since I envision myself almost always double-clicking a function or method declaration and appending it to a list, I find this behavior to be most convenient.
</p>
</p>
<p>Thanks to <a href="http://www.toxicsoftware.com/">Jon Wight</a> for helping with Python.</p>
<p>
<strong>Update:</strong> Any productivity gained by using this macro was certainly lost as I tried desperately to debug Xcode&#8217;s latest propensity to &#8220;beachball&#8221; on launch. Finally, I attached with gdb and found a telling backtrace. Hmm? Yep, when I &#8220;zipped&#8221; the script for upload to the blog, I left a zipped copy in the scripts folder. Next time I launched Xcode, it choked big time on trying to treat that zip file as a script.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/269/xcode-pasteboard-accumulator/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Xcode Index</title>
		<link>http://www.red-sweater.com/blog/264/xcode-index</link>
		<comments>http://www.red-sweater.com/blog/264/xcode-index#comments</comments>
		<pubDate>Thu, 25 Jan 2007 20:59:12 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/264/xcode-index</guid>
		<description><![CDATA[If you use Xcode often, surely you appreciate the &#8220;Code Sense Index.&#8221; This is the magic cache of symbolic info that allows tricks like command-double-clicking a variable name to jump to its declaration, or Opt-Period to complete a function name. Indexing makes life for programmers about one bajillion times easier. Unless. Ughh!!!!! Angst, angst, angst! [...]]]></description>
			<content:encoded><![CDATA[<p>If you use Xcode often, surely you appreciate the &#8220;Code Sense Index.&#8221; This is the magic cache of symbolic info that allows tricks like command-double-clicking a variable name to jump to its declaration, or Opt-Period to complete a function name. Indexing makes life for programmers about one bajillion times easier.</p>
<p>
Unless. Ughh!!!!! Angst, angst, angst! It&#8217;s got crap in the index. You jump to a definition, make a load of changes, build, run, and &#8230; nothing&#8217;s changed. What on earth? You thought for sure you fixed it. Finally you stumble upon the nuanced fact that the source file you&#8217;re editing isn&#8217;t located in your project directory. In fact, looking at the full path you see fragments like &#8220;.bak&#8221; or &#8220;old&#8221; or &#8220;copy&#8221; in the hierarchy. This is some bogus copy of your source base that you moved aside, but somehow Xcode caught up with it.
</p>
<p>
I&#8217;m not exactly sure how this happens, but I suppose the recommended procedure for fixing it is to click the &#8220;Rebuild Code Sense Index&#8221; button from the Project Inspector window. Heck, for all I know this might work. But it gives no feedback &#8211; no sense of whether the reindexing has started, or when it will be done. And especially no feedback about what it chose to index. Well, truth be told you can see some vague feedback about the indexing progress if you open the &#8220;Activity Monitor&#8221; window. But it&#8217;s still not completely reassuring.
</p>
<p>
I stumbled on the &#8220;xcodeindex&#8221; command-line tool, which is a real gift. With this you can not only explicitly remove the index, but you can recreate it with a variety of debugging log levels set, to see exactly what&#8217;s going on.
</p>
<p>
But Apple really made my day by including a &#8220;dump&#8221; option. For instance:
</p>
<p><pre>
% xcodeindex -project FlexTime.xcodeproj dump > MyIndex
</pre>
</p>
<p>
Yields a tab-delimited file containing all the indexed terms that Xcode knows about for my project. Nifty!</p>
<h3>Anatomy Of An Index Dump</h3>
<p>The index file contains thousands of rows divided into 5 tab-delimited columns detailing the symbol name, description, type, language, and file. Let&#8217;s take a look at a sample line from my FlexTime index, column by column:
</p>
<p><pre>
adaptPlaybackToDisappearingItem:
</pre>
</p>
<p>
This is the symbolic name, what I would have to double-click on to get Xcode to wake up and notice it was an indexed term.
</p>
<p><pre>
-[RoutineDocument(Running) adaptPlaybackToDisappearingItem:]
</pre>
</p>
<p>
This is the description, which seems to be what Xcode displays for instance in the popup menu when there are more than possible choices. Clearly this description will vary based on the language the symbol happens to belong to.
</p>
<p><pre>
Instance Method
</pre>
</p>
<p>
The type is probably the most interesting column, after name. In this case I&#8217;m told it&#8217;s an instance method. Other rows in the output include types like &#8220;Instance Variable,&#8221;  &#8220;Function,&#8221; and &#8220;Type.&#8221;
</p>
<p><pre>
Objective-C
</pre>
</p>
<p>
Language. Well, that&#8217;s pretty obvious.
</p>
<p><pre>/Users/daniel/Sources/FlexTime/RoutineDocument+Running.m</pre>
</p>
<p>
Source file. Everything has a source file, including items from the System APIs, which point into the root volume or the appropriate SDK.
</p>
<p><h3>Great Expectations</h3>
<p>What&#8217;s really exciting about this index dump file is that I can read it. You can read it. We can write scripts to do nifty analysis tricks with it. Xcode&#8217;s standard project indexes are kept in some (presumably) proprietary binary format that we dno&#8217;t have easy access to, but the dump file opens things up to the masses.
</p>
<p>
For instance, sometimes I&#8217;d really like to know the answer to questions like &#8220;which of my custom classes is depended upon by the fewest of its peer classes?&#8221; I&#8217;m not sure how I would figure that out (no doubt some of you will comment with another clever solution), but I&#8217;m pretty sure I can whip up a Python script to do the trick with this dump file.
</p>
</p>
<p><strong>Update:</strong> Well, call off the party balloons. The index dump file is cool, but not quite as cool as I was imagining. I just realized that because the &#8220;Instance Variable&#8221; types don&#8217;t indicate the <em>type of the variable</em>, they&#8217;re not very useful for tracking down dependencies.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/264/xcode-index/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Restart Xcode</title>
		<link>http://www.red-sweater.com/blog/262/restart-xcode</link>
		<comments>http://www.red-sweater.com/blog/262/restart-xcode#comments</comments>
		<pubDate>Wed, 17 Jan 2007 16:36:04 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/262/restart-xcode</guid>
		<description><![CDATA[As much as I basically like Xcode, let&#8217;s just say it&#8217;s not without its infuriating quirks. Among these quirks are a number of subtle bugs that seriously degrade its usability, but that only seem to appear after using it for several hours or days. Your text editors stop showing your changes, the spinning pizza of [...]]]></description>
			<content:encoded><![CDATA[<p>As much as I basically like <a href="http://www.apple.com/macosx/features/xcode/">Xcode</a>, let&#8217;s just say it&#8217;s not without its infuriating quirks. Among these quirks are a number of subtle bugs that seriously degrade its usability, but that only seem to appear after using it for several hours or days. Your text editors stop showing your changes, the spinning pizza of death is appearing more often, the index doesn&#8217;t quite seem to be working. Xcode has <em>poor uptime</em>, when compared with Mac OS X itself.</p>
<p>
The workaround is, of course to simply restart Xcode when it  gets flakey. But often this is an ordeal because you then have to go through your recent projects and manually reopen the one (or ones) that you were working on. I found myself frequently cmd-clicking the project window&#8217;s title to get a Finder reference to the project, so I could quickly reopen it after quitting.
</p>
<p>
<a href="http://www.red-sweater.com/AppleScript/RestartXcode.zip">Restart Xcode</a> does all of this for you. Save the script to your ~/Scripts/Applications/Xcode folder, and keep it at easy reach from <a href="http://www.red-sweater.com/fastscripts/">FastScripts</a> or the Apple Script Menu. When you run it, it asks Xcode to quit, but not before accumulating a list of all the project documents you&#8217;ve got open. It waits for the quit to finish, then promptly reopens Xcode and all the documents.
</p>
<p>
Until Apple improves the uptime of Xcode, this script is going to save me a lot of frustration.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/262/restart-xcode/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Keychain Developer Tip</title>
		<link>http://www.red-sweater.com/blog/253/keychain-developer-tip</link>
		<comments>http://www.red-sweater.com/blog/253/keychain-developer-tip#comments</comments>
		<pubDate>Mon, 08 Jan 2007 19:15:26 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/253/keychain-developer-tip</guid>
		<description><![CDATA[First of all, if you&#8217;re dealing with any sensitive information on behalf of the user, you&#8217;re ethically responsible for storing that information securely. Mac OS X&#8217;s deeply integrated Keychain Services leaves you with no excuse for saving passwords, credit card numbers, or other sensitive information in plain-text format on the user&#8217;s disk. Access to items [...]]]></description>
			<content:encoded><![CDATA[<p>First of all, if you&#8217;re dealing with any sensitive information on behalf of the user,  you&#8217;re ethically responsible for storing that information securely. Mac OS X&#8217;s deeply integrated <a href="http://developer.apple.com/documentation/MacOSX/Conceptual/OSX_Technology_Overview/AppTechnology/chapter_5_section_12.html">Keychain Services</a> leaves you with no excuse for saving passwords, credit card numbers, or other sensitive information in plain-text format on the user&#8217;s disk. Access to items in the keychain is controlled by users, and when any new application asks for access, the user generally has to approve it:</p>
<p>
<img src="http://www.red-sweater.com/blog/images/KeyChainAccessDialog.png"/>
</p>
<p>
I recently added Keychain Support to an application where the sensitive password information needs to be fetched at launch-time, every time it launches. That&#8217;s fine, but one of the important security features of Keychain Services is its ability to detect changed copies of a previously permitted application. This is to ward off abuses in case a hacker has replaced some trusted application with one that is programmed to siphon off your keychain passwords or something:
</p>
<p>
<img src="http://www.red-sweater.com/blog/images/KeychainConfirmChange.png"/>
</p>
<p>
Usually this dialog appears only once in a while, after updating an application to a newer version, or installing an Apple software update. But when you consider the product development cycle: develop -> build -> test, you can imagine how frequently an application under development will trigger this warning.
</p>
<p>
Until provoked by this nuisance, I didn&#8217;t know about a feature in Keychain Access that allows users to open up access to a particular key. In general this would be a pretty insecure choice, but it makes a lot of sense for development purposes:
</p>
<p>
<img src="http://www.red-sweater.com/blog/images/KeychainFreeForAll.png"/>
</p>
<p>
You&#8217;ll find the option in the &#8220;Access Control&#8221; tab after double-clicking any keychain item. So for the purposes of development, test against a key that doesn&#8217;t actually have any sensitive information in it, and set the access to unrestricted. Now you can rebuild and test as often as you like without being pestered by Keychain Services.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/253/keychain-developer-tip/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

