<?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; Cocoa</title>
	<atom:link href="http://www.red-sweater.com/blog/category/articles/programming/cocoa/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>The Power Of Plist</title>
		<link>http://www.red-sweater.com/blog/2083/the-power-of-plist</link>
		<comments>http://www.red-sweater.com/blog/2083/the-power-of-plist#comments</comments>
		<pubDate>Wed, 03 Aug 2011 19:12:50 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Darwin]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/?p=2083</guid>
		<description><![CDATA[Most Mac and iOS developers know that when you build an application, you advertise a number of details about the application in the &#8220;Info.plist&#8221; file, located inside the application bundle. You can examine any application on your Mac and see what kind of information the developer has conveyed about it: Navigate to a .app file [...]]]></description>
			<content:encoded><![CDATA[<p>Most Mac and iOS developers know that when you build an application, you advertise a number of details about the application in the &#8220;Info.plist&#8221; file, located inside the application bundle. You can examine any application on your Mac and see what kind of information the developer has conveyed about it:</p>
<ol>
<li>Navigate to a .app file in the Finder, e.g. /Applications/Mail.app</li>
<li>Control-click the app icon and select &#8220;Show Package Contents&#8221;</li>
<li>Navigate to Contents/Info.plist</li>
<li>Open with a plist editor or your favorite text editor.</li>
</ol>
<p>These files advertise a number of interesting attributes including the application&#8217;s official version and copyright strings. They also include important clues to the system about what kinds of files the application knows how to read and write, and what its minimum system requirements are.</p>
<h3>Minimum System Requirements</h3>
<p>Declaring the right Info.plist values not only allows a developer to control which operating systems a product should run on, but which of the application&#8217;s architectures should be considered for a particular operating system. For example, <a href="http://www.red-sweater.com/blackink/">Black Ink</a> uses a number of keyed values describing its requirements:</p>
<pre>	&lt;key&gt;LSArchitecturePriority&lt;/key&gt;
	&lt;array&gt;
		&lt;string&gt;x86_64&lt;/string&gt;
		&lt;string&gt;i386&lt;/string&gt;
		&lt;string&gt;ppc&lt;/string&gt;
	&lt;/array&gt;
	&lt;key&gt;LSMinimumSystemVersion&lt;/key&gt;
	&lt;string&gt;10.4.0&lt;/string&gt;
	&lt;key&gt;LSMinimumSystemVersionByArchitecture&lt;/key&gt;
	&lt;dict&gt;
		&lt;key&gt;i386&lt;/key&gt;
		&lt;string&gt;10.4.0&lt;/string&gt;
		&lt;key&gt;x86_64&lt;/key&gt;
		&lt;string&gt;10.6.0&lt;/string&gt;
		&lt;key&gt;ppc&lt;/key&gt;
		&lt;string&gt;10.4.0&lt;/string&gt;
	&lt;/dict&gt;
</pre>
<p>Notice the fidelity of some of these options. Black Ink is an application that is compiled with binary code for three separate architectures embedded into it: 64-bit Intel, 32-bit Intel, and 32-bit PowerPC. In order to give the user the best possible experience after they double-click the application icon, the system consults the Info.plist values to determine which binary is most appropriate to load on the current system.</p>
<p>The options for Black Ink start by indicating that all things being equal, it prefers to run as 64-bit Intel, but will settle for 32-bit Intel or PowerPC in a pinch. Next, it conveys that it should not be run on any operating system earlier than Mac OS X 10.4. Finally, it adds an additional restriction by architecture, stating that in the case of 64-bit Intel, the system should consider Mac OS X 10.6 the minimum required OS.</p>
<p>Why so picky? For example, Mac OS X 10.5 will run on computers that are new enough to support 64-bit Intel code, but the 10.5 operating environment itself doesn&#8217;t contain enough compatible libraries to make it very useful to a full-featured Cocoa application. So we need to convince the 10.5 system <em>to ignore our 64-bit Intel code.</em> And this is how it&#8217;s done.</p>
<h3>Embedding Info.plist</h3>
<p>This is all well and good for applications, but what about other code that may be run on a variety of hardware and operating systems? In particular, command-line tools do not come in the same bundled-folder format that applications do. Fortunately, Apple thought of this when they implemented support in their developer tools for embedding the contents of an Info.plist directly into the binary itself. You just have to pass the Info.plist path to Apple&#8217;s linker tool when it&#8217;s constructing your binary file. (Thanks to <a href="http://www.noodlesoft.com/">Paul Kim</a> for reminding me of this functionality). What this means in practice is adding arguments like this to your Xcode target&#8217;s &#8220;Other Linker Flags&#8221; build setting:</p>
<pre>-sectcreate __TEXT __info_plist $(INFOPLIST_FILE)
</pre>
<p>This instructs the linker to crete a new text segment named &#8220;__info_plist&#8221; in the resulting binary, and to fill it with the contents of the referenced Info.plist file. To make sure the INFOPLIST_FILE expands correctly, just make sure you set it in the separate build setting for identifying the Info.plist (the one you&#8217;d normally use in an app, and that is just ignored by default for a command-line tool target).</p>
<p>I brushed up on all this information because I wanted to help ensure that some recent work I did to create a <a href="https://github.com/danielpunkass/peg-multimarkdown">standalone MultiMarkdown tool</a> would be backward compatible with older systems. This required <a href="https://github.com/danielpunkass/peg-multimarkdown/commit/ca523bac1fb03b9cfdcf540805e677086c063704">adding an embedded plist</a> much as I&#8217;m describing here.</p>
<p>(<strong>Note:</strong> I have gotten some feedback to the effect that the __info_plist segment&#8217;s minimum system version requirements may not actually be consulted properly on Mac OS X 10.5. This would be a bummer, and in fact sort of reject the whole point of embedding the Info.plist in this case. I&#8217;m going to see if I can confirm whether it doesn&#8217;t in fact work.)</p>
<p>You could technically embed all kinds of stuff in the binary, with different section names. But the contract in this case is that when Mac OS X is determining information about an executable, it will consult <strong>the bundle&#8217;s Info.plist file</strong>, if it happens to be an executable in a bundle, or <em>the binary&#8217;s __info_plist segment</em>, if it happens to have one.</p>
<p>Another common reason for needing to embed Info.plist information into a standalone binary is if you are using Apple&#8217;s code signing mechanism to sign an individual binary tool. Code signing uses information from the Info.plist of a product, and in the case of standalone binaries, the only product-cohesive place to put this is in the binary itself.</p>
<h3>Examining Binary Info.plists</h3>
<p>After you&#8217;ve performed the magic above, you&#8217;ll probably be keen to inspect your command-line tool&#8217;s Info.plist to see if it worked. To do this, you can use the otool command from the Finder. If you run otool with the &#8220;-l&#8221; option to show all load commands, it will include the load command that identifies the __info_plist segment. Use grep to narrow it down to the part you&#8217;re interested in:</p>
<pre>otool -l ./yourTool | grep info_plist -B1 -A10
</pre>
<p>Any results at will confirm that there is Info.plist information in the binary, but how does it look? The &#8220;-s&#8221; option to otool lets you examine the contents of a specific segment in a binary, but it dumps it out as hex code. Fortunately, another system-bundled tool called &#8220;xxd&#8221; is capable of easily converting between hex-dump and text formats. As it turns out, some of Apple&#8217;s bundled developer tools (at least on my Mac) contain these embedded __info_plist sections, so if you don&#8217;t have a command line tool of your own to try this on, you can peek at what the &#8220;atos&#8221; tool has to say for itself:</p>
<pre>otool -s __TEXT __info_plist /usr/bin/atos | xxd -r
</pre>
<h3>In Summary</h3>
<p>Info.plist values are important for conveying information about your product, from the crudest, most obvious stuff like version number, to the most nuanced details such as which architectures are supported. Knowing how to specify an application or tool&#8217;s requirements as precisely as possible will ensure that the product performs optimally on whatever supported system your user happens to be using. I&#8217;ve barely scratched the surface here with a few common deployment keys that control execution behavior on Mac OS X. Be sure to skim Apple&#8217;s <a href="http://developer.apple.com/library/mac/#documentation/General/Reference/InfoPlistKeyReference/Introduction/Introduction.html">Information Property List Key Reference</a> to see if there are other useful bits of information you can share for your application <em>or for your command-line tool.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/2083/the-power-of-plist/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Windowless Skyscraper</title>
		<link>http://www.red-sweater.com/blog/2065/windowless-skyscraper</link>
		<comments>http://www.red-sweater.com/blog/2065/windowless-skyscraper#comments</comments>
		<pubDate>Wed, 03 Aug 2011 15:11:09 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Motivation]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/?p=2065</guid>
		<description><![CDATA[One of the thrills of software development is how much power is placed into the hands, literally, of a single engineer. Software takes work, and lots of it. But thanks to frameworks of reusable code, individuals are consistently able to &#8220;outbuild&#8221; the work of our predecessors, while exerting the same or less effort. Consider the work [...]]]></description>
			<content:encoded><![CDATA[<p>One of the thrills of software development is how much power is placed into the hands, literally, of a single engineer. Software takes work, and lots of it. But thanks to frameworks of reusable code, individuals are consistently able to &#8220;outbuild&#8221; the work of our predecessors, while exerting the same or less effort.</p>
<p>Consider the work that went into the first word processors and web browsers, whose work can now be mimicked by a Mac developer who knows how to embed <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSTextView_Class/Reference/Reference.html">NSTextView</a> or or <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/WebKit/Classes/WebView_Class/Reference/Reference.html">WebView</a>. Imagine the time that early game developers invested in rudimentary sprite drawing, animation, and collision, which is now achieved easily in iOS games with open source packages such as <a href="http://www.cocos2d-iphone.org/about">cocos2d</a>.</p>
<p>Still, building truly great software continues to elude most developers. It&#8217;s easy to assume that a large amount of time invested in a project, combined with an impressive outcome, is the key to a successful product. But it&#8217;s not so simple.</p>
<p>The <a href="http://en.wikipedia.org/wiki/Ninety-ninety_rule">ninety-ninety rule</a> is often cited when describing the challenge of finessing a product after most of the hard work has seemingly been done:</p>
<blockquote>
<p>&#8220;The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time.&#8221; &#8212; Tom Cargill</p>
</blockquote>
<p>I agree with this perspective, and I cite it often when discussing software with others. The rule as stated is in terms of &#8220;code&#8221; but is also applicable to all the visual design, user experience, marketing, and positioning of a product. I think the rule is also recursive: whatever is missing can always be split up such that an &#8220;easy&#8221; 90% of the job can be done, leaving an elusive 10% of finesse work.</p>
<p>Many developers mistakenly assume that after they&#8217;ve put a ton of work into a project, and it achieves some impressive feat, that their work is done. When you focus on the enormity of work completed thus far, it&#8217;s tempting to pat yourself on the back and call it a day.</p>
<p>But customers don&#8217;t care about the hard work that went into the 90%. They only notice the flaws or omissions in the 10%. Imagine if Michelangelo&#8217;s statue of David was perfect in every detail, except that where David&#8217;s face should be, a clump of ragged, unfinished marble lay crudely in its place. Instead of marveling at the exquisite details of David&#8217;s feet, torso, and arms, viewers would reject it as unfinished and clumsy.</p>
<p>An important takeaway for software developers is that the missing 10%, or the missing one-tenth of 10%, may be something that will take a great deal of work to get right, but it may be something you simply overlooked the importance of.</p>
<p>You might build an impressive skyscraper projecting 40 stories into the sky. The architecture, interior design, plumbing, and electrical work may all be superior to that of your peers. But if some blindness in your product vision prevents you from adding windows, the product will never sell. It doesn&#8217;t matter how much time or effort went into this masterpiece: nobody will live in a windowless skyscraper.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/2065/windowless-skyscraper/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Core Data Model Merging</title>
		<link>http://www.red-sweater.com/blog/1862/core-data-model-merging</link>
		<comments>http://www.red-sweater.com/blog/1862/core-data-model-merging#comments</comments>
		<pubDate>Wed, 04 May 2011 16:27:44 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/?p=1862</guid>
		<description><![CDATA[I haven&#8217;t used Apple&#8217;s Core Data framework all that much, but I&#8217;m trying to dabble more in it with newer projects where I don&#8217;t rely as much on legacy data storage, or am willing to take the hit of migrating from those legacy persistence models. As a developer, the obvious upside to using Core Data [...]]]></description>
			<content:encoded><![CDATA[<p>I haven&#8217;t used Apple&#8217;s <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html">Core Data</a> framework all that much, but I&#8217;m trying to dabble more in it with newer projects where I don&#8217;t rely as much on legacy data storage, or am willing to take the hit of migrating from those legacy persistence models.</p>
<p>As a developer, the obvious upside to using Core Data is Apple&#8217;s powerful framework manages most of the nitty-gritty details of managing the &#8230; well, the data your app uses both in memory and on disk. But giving up precise control over the storage and mangement of this data also becomes maddening when you run into problems: you&#8217;re not directly responsible for the management, so you&#8217;re less likely to know exactly what is going wrong.</p>
<p>I ran into a problem recently having to do with <em>versioning</em> of core data model schemas, and how good a job the frameworks do or do not do of automatically updating existing data that a customer may have on disk. In recent years Apple has made it increasingly easy to make <em>minor changes</em> to your model schema and having the frameworks handle the migration easily. Apple calls this trivial technique <a href="http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/CoreDataVersioning/Articles/vmLightweight.html">lightweight migration</a>, and when it works well, it works very well. To modify your existing data model, you just add a new &#8220;version&#8221; of your xcdatamodel file, and add a few options flags when creating your persistent store:</p>
<pre>
NSDictionary *options =
   [NSDictionary dictionaryWithObjectsAndKeys:
   [NSNumber numberWithBool:YES],
     NSMigratePersistentStoresAutomaticallyOption,
   [NSNumber numberWithBool:YES],
     NSInferMappingModelAutomaticallyOption, nil];

[myPSC addPersistentStoreWithType:NSSQLiteStoreType
   configuration:nil URL:storeUrl
   options:options error:&amp;error];
</pre>
<p>This actually works quite well for simple addition or removal of entity attributes, but you might be forgiven for assuming its <em>completely freaking broken</em> if you run into a problem I did, having to do with a stale &#8220;.mom&#8221; file being left in the built application&#8217;s bundle in the iOS simulator and on iOS devices.</p>
<p>Essentially, if you&#8217;ve been building your project up to now with a single, unversioned xcdatamodel file, and you convert it to a versioned xcdatamodel file, it will start producing a new &#8220;.momd&#8221; file in your application bundle, and stop producing the older &#8220;.mom&#8221;. But because of a bug in the way Xcode installs the application binary in the simulator and devices, it will leave existing files from previous builds where they were in the bundle.</p>
<p>If, like many folks, you use the convenient [NSManagedObjectModel mergedModelFromBundles:nil] method to initialize your managed object model, this will, to use a technical term, bite you in the ass. The problem is Core Data looks at the .mom and the .momd files as equally viable, and attempts to merge them into some cohesive whole. When it discovers they both redundantly describe the same entities, it blows a gasket with a runtime error like &#8220;Can&#8217;t merge models with two different entities named &#8216;MyEntity&#8217;&#8221;</p>
<p>I did some googling around and discovered that the simplest solution is to simply delete the iOS app from the device or simulator, ensuring that the next time you install, you get a pristine, clean copy of the app without the troubling &#8220;.mom&#8221; file. But there&#8217;s a huge problem with that: in deleting the app you also delete its associated data files, and thus are left in a position where you aren&#8217;t actually testing the ability of Core Data to effectively migrate from your previously versioned data.</p>
<p>On the simulator, it&#8217;s no problem to dive in and trash the problematic, stale file. You can find the application binary somewhere in:</p>
<p>[Home] -&gt; Library -&gt; Application Support -&gt; iTunes Simulator</p>
<p>Once you&#8217;ve deleted the &#8220;.mom&#8221; file you can test with your new model and everything hopefully works great.</p>
<p>On the device, it&#8217;s not as easy (I think) to get in there and do pinpoint editing of the application contents, but I still wanted to test my changes against the real data on my device. I was also starting to get paranoid about the possibility of an App Store update at some point also causing a stale &#8220;.mom&#8221; file to be left in an app bundle, and wreaking havoc. So the 100% safe solution to make sure the one-true &#8220;.momd&#8221; file is consulted when building the Core Data object model, is to point directly at it:</p>
<pre>
NSString *momdPath = [[NSBundle mainBundle]
	pathForResource:@"MyModel" ofType:@"momd"];

NSURL *momdURL = [NSURL fileURLWithPath:momdPath];

managedObjectModel = [[NSManagedObjectModel alloc]
	initWithContentsOfURL:momdURL];
</pre>
<p>Hopefully seeding this solution into my blog will make it available for folks searching on similar failures in their Core Data projects.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/1862/core-data-model-merging/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t Coddle Your Code</title>
		<link>http://www.red-sweater.com/blog/1423/dont-coddle-your-code</link>
		<comments>http://www.red-sweater.com/blog/1423/dont-coddle-your-code#comments</comments>
		<pubDate>Fri, 24 Sep 2010 03:09:19 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/?p=1423</guid>
		<description><![CDATA[Jeff LaMarche presents a rundown on whether Objective-C dealloc implementations should bother nil&#8217;ing out an instance variable after releasing it. LaMarche offers a fairly balanced presentation of the two sides, but in my opinion he gives too much credibility to the argument that nil&#8217;ing is a good idea. He essentially embraces the argument that nil&#8217;ing [...]]]></description>
			<content:encoded><![CDATA[<p>Jeff LaMarche <a href="http://iphonedevelopment.blogspot.com/2010/09/dealloc.html">presents a rundown</a> on whether Objective-C dealloc implementations should bother nil&#8217;ing out an instance variable after releasing it.</p>
<p>LaMarche offers a fairly balanced presentation of the two sides, but in my opinion he gives too much credibility to the argument that nil&#8217;ing is a good idea. He essentially embraces the argument that nil&#8217;ing the variables in production code is wise, because it might mask crashing bugs that would obviously vex the user:</p>
<blockquote><p>Generally speaking, this is only going to happen if you&#8217;ve got a bug elsewhere in your code, but let&#8217;s face it, you may very well. Anyone who codes on the assumption that all of their code is perfect is begging for a smackdown.</p></blockquote>
<p>And speaking specifically about the approach I prefer, leaving the instance variable alone and not bothering to nil it out:</p>
<blockquote><p>On the other hand, that approach is really, really bad in a shipping application because you really don&#8217;t want to crash on your users if you can avoid it.</p></blockquote>
<p>I disagree with the assertion that avoiding crashes at all costs in shipping code is the right priority. The biggest disservice you can do to your users is to allow them to run code that has unpredictable behavior. The whole point of programming is to make computers accomplish tasks in predictable ways. Sure, we all make mistakes as programmers, but giving in to the chaos and putting up safety nets &#8220;just in case&#8221; is not the right approach, especially considering it has unwanted consequences.</p>
<p>Consider that by masking the crash from occurring in the wild, you may be putting off detection of and resolution of the underlying bug indefinitely. But if your application has a crash reporter, or if you take advantage of Apple&#8217;s iOS crash reports, you will learn quickly that there are issues needing to be resolved.</p>
<p>It is reasonable to take steps that mask mysterious crashes, but this should only be done after you know there are actually crashes to prevent. Masking the symptoms in a blanket manner is akin to cutting half the phone lines in the neighborhood and celebrating the reduced number of 911 calls.</p>
<p>It&#8217;s also worth noting that LaMarche&#8217;s defense of nil&#8217;ing out instance variables hinges on the presumption that messaging nil is safe. True, messaging nil will not cause a crash. But is that safe? Not if it changes the behavior of your code in unpredictable ways. Consider this incredibly contrived Cocoa-based nuclear arms controller:</p>
<p><pre>
if ([mDiplomat didReturnGestureOfPeace] == NO)
{
 	[[NuclearWarehouse nuclearMissile] launch];
}
</pre>
</p>
<p>By LaMarche&#8217;s reasoning, it&#8217;s a good idea to nil out the mDiplomat variable on release, so that it won&#8217;t crash when you message it. But in this case, messaging nil for a BOOL result causes a logical flaw in the program, with obviously dire consequences. If the instance variable were not set to nil, it would probably crash before the launch message could ever be sent.</p>
<p>We should aim to comprehend what our software actually does. Deliberately decreasing the symptoms of problematic code won&#8217;t lead us any closer to that understanding. Ship the best code you have to your customers, and if it crashes, try to fix the root cause of the crash as quickly as possible. Don&#8217;t get in the habit of writing &#8220;hope this fixes it&#8221; code, and by all means don&#8217;t adopt that philosophy as a boilerplate coding habit.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/1423/dont-coddle-your-code/feed</wfw:commentRss>
		<slash:comments>44</slash:comments>
		</item>
		<item>
		<title>Zoom Anywhere</title>
		<link>http://www.red-sweater.com/blog/1419/zoom-anywhere</link>
		<comments>http://www.red-sweater.com/blog/1419/zoom-anywhere#comments</comments>
		<pubDate>Tue, 14 Sep 2010 21:02:32 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/?p=1419</guid>
		<description><![CDATA[I&#8217;ve been in and out of Apple&#8217;s iPhone simulator for the past two years, and for the entire time, I&#8217;ve been frustrated by what I assumed was an inherent limitation: pinching and zooming and only works in the middle of the screen: Today I was so supremely frustrated by this that I played around with [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been in and out of Apple&#8217;s iPhone simulator for the past two years, and for the entire time, I&#8217;ve been frustrated by what I assumed was an inherent limitation: pinching and zooming and only works in the middle of the screen:</p>
<p>Today I was so supremely frustrated by this that I played around with all manner of double-clicking, alternate modifier keys, etc., until I stumbled on the simple solution. Googling for answers after-the-fact revealed that I&#8217;m by no means the first person to discover this, but it&#8217;s quite possible <em>I&#8217;m the first person who has told you!</em></p>
<p>To zoom in on an arbitrary point with the iPhone simulator:</p>
<ol>
<li>Hold down the option key to obtain the familiar &#8220;simulation fingertips&#8221;.</li>
<li>Move the mouse until the fingertips are the desired &#8220;starting width&#8221; for your gesture.</li>
<li>Keeping the option key pressed, hold down the shift key to enter &#8220;panning&#8221; mode.</li>
<li>Move the mouse until the fingertips are at the desired starting position.</li>
<li>Remove the shift key while continuing to hold the option key.</li>
<li>Click and drag to zoom in or out at the selection location.</li>
</ol>
<p><img title="ZoomAnywhere-3.png" src="http://www.red-sweater.com/blog/wp-content/downloads/2010/09/ZoomAnywhere-3.png" border="0" alt="ZoomAnywhere-3.png" width="314" height="548" /></p>
<p>It&#8217;s a little cumbersome, but it&#8217;s about 1000% more useful than not being able to do it at all.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/1419/zoom-anywhere/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hold On A Minute</title>
		<link>http://www.red-sweater.com/blog/1397/hold-on-a-minute</link>
		<comments>http://www.red-sweater.com/blog/1397/hold-on-a-minute#comments</comments>
		<pubDate>Thu, 09 Sep 2010 18:00:18 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Macintosh]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/?p=1397</guid>
		<description><![CDATA[One of the big new features in MarsEdit 3 is a revamped media manager that allows you to easily browse local libraries from iPhoto, Aperture, etc. This functionality is based largely on the great work of the iMedia project, which was spearheaded by Karelia to replicate Apple&#8217;s own ubiquitous media browsing interface, some variant of [...]]]></description>
			<content:encoded><![CDATA[<p>One of the big new features in <a href="http://www.red-sweater.com/marsedit/">MarsEdit 3</a> is a revamped media manager that allows you to easily browse local libraries from iPhoto, Aperture, etc.</p>
<p><img src="http://www.red-sweater.com/blog/wp-content/downloads/2010/09/Media-Manager.png" alt="Media Manager.png" border="0" width="450" height="371" /></p>
<p>This functionality is based largely on the great work of the <a href="http://code.google.com/p/imedia/">iMedia</a> project, which was spearheaded by <a href="http://www.karelia.com/">Karelia</a> to replicate Apple&#8217;s own ubiquitous media browsing interface, some variant of which is available in Pages, iWeb, Mail, etc.</p>
<p>iMedia has been around for a while, but in the past year or more it has been undergoing a significant overhaul as its primary developers gear up to release the official 2.0 milestone. I have been involved in the 2.0 project for a long time now as an &#8220;early adopter,&#8221; using MarsEdit as a testing ground during the beta phase, and taking (mostly!) only the refined and polished aspects of the product for the final MarsEdit 3.0 release.</p>
<p>We are still ironing out some of the kinks, especially in parts of the project that were not tested in MarsEdit. One of the cool new features is support for the Flickr photo-sharing service. Like MarsEdit&#8217;s own Flickr-browser, it shows thumbnails of images on Flickr, and lets you treat them more-or-less like ordinary image files that you&#8217;d find on your computer.</p>
<p><img src="http://www.red-sweater.com/blog/wp-content/downloads/2010/09/iMedia2.png" alt="iMedia Flickr Support" border="0" width="450" height="344" /></p>
<p>Things get a little bit complicated when a user selects and drags one of these Flickr image thumbnails to another app, such as the Finder, or Photoshop. Since the image lives in the internet, and not on the local hard disk, it is not something that can be popped over to the application in an instant. Instead, a progress dialog comes up while the image is downloaded to the disk, and then the local copy is passed to the receiving application.</p>
<p><img src="http://www.red-sweater.com/blog/wp-content/downloads/2010/09/iMediaFlickr.png" alt="iMedia Flickr Download Panel" border="0" width="400" height="188" /></p>
<p>I try to contribute back when possible in the form of bug fixes and architectural feedback. Some of the work I did for iMedia 2.0 involved updating its drag-and-drop functionality to take advantage of new features in Mac OS X 10.6. In the process, I became a sort of de facto expert on handling dragging, which is a shame, because we could sure use a <em>real</em> expert, instead!</p>
<p>The other day, an issue came up that relates to the dragging of Flickr files. If the download is taking a while, and the user tries to cancel, mouse clicks are apparently ignored and they are stuck with the progress dialog above. I agreed to look into the issue, but there was just one problem: my network is too fast! Whenever <em>I</em> try to drag a Flickr image to another app, it&#8217;s done within a couple seconds, and I don&#8217;t have time to play around with clicking the cancel button.</p>
<p>If only I could get a <em>really slow connection</em> to Flickr, then I could easily test this. In the old days of Mac OS 9 or earlier, I may have resorted to plugging in a slow modem to simulate the experience of the less bandwidth-fortunate. In Mac OS X however, I can take advantage of the advanced firewall software that comes bundled with the operating system, and which allows me to configure &#8220;traffic shaping&#8221; policies on the traffic coming in and out of my computer. I found a great <a href="http://hints.macworld.com/article.php?story=20080119112509736">hint from Macworld</a> that got me on the right track.</p>
<p>My goal is to cause Flickr downloads to be artificially slow. In order to achieve this goal I need to find the specific web address that the downloads come from. To do this, I use the standard tcpdump terminal utility, which also comes bundled with Mac OS X:</p>
<pre>
sudo tcpdump -Atqp -s 0 -ien1
</pre>
<p>The only part you may want to change is the bit at the end that says &#8220;en1&#8243;. Depending on the network interface you&#8217;re using, you might want en0 or en2 instead. With this running in the terminal, I go back to iMedia and start downloading Flickr files. This lets me see what the addresses of those files look like, and I discover the pertinent host name is &#8220;farm5.static.flickr.com&#8221;. Using the information I gleaned from the Macworld article, I set up the following firewall traffic shaping rules:</p>
<pre>
sudo ipfw pipe 1 config bw 15KByte/s
sudo ipfw add 1 pipe 1 src-port 80 src-ip farm5.static.flickr.com
</pre>
<p>Translation?</p>
<ol>
<li>Create a pipe (you might prefer to call it a &#8220;tube&#8221;). A pipe is an artificial pass-through which can be configured to slow down, block, or otherwise alter the network traffic that goes through it.</li>
<li>Configure the pipe to limit bandwidth to a crawling 15KByte/s.</li>
<li>Configure all traffic coming from port 80 (the standard HTTP port), and originating from a specific hostname at Flickr, to pass through that pipe.</li>
</ol>
<p>As soon as these commands are executed, the pipe is in place, and Flickr download speeds are brought to screeching halt. I can now debug the issue with the download dialog and the cancel button patiently and curiously, instead of racing to try clicking the button while I still have the chance.</p>
<p>When I&#8217;m done debugging, I definitely want to delete the pipe, so that download speeds go back to normal:</p>
<pre>
sudo ipfw delete 1
</pre>
<p>Mucking around with the built-in firewall on Mac OS X is not for the extremely faint-of-heart. This is why all the commands listed in this entry require &#8220;sudo&#8221; superuser privileges. Yes, you could seriously screw up your computer&#8217;s network connection if you do something wrong. But if you are the type of person whose work requires you to test and debug network related tasks, this traffic shaping functionality can be a real asset when it comes to mimicking the network environments of other people.</p>
<p><strong>Addendum:</strong> I should have known I might be doing it the hard way, as usual. Clint Ecker <a href="http://twitter.com/clint/status/24032579293">reported on Twitter</a>, and several folks in the comments below, that <a href="http://mschrag.github.com/">speedlimit</a>, a Mac OS X preference pane, gets the job done in a much friendlier manner.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/1397/hold-on-a-minute/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>RegExKitLite v. Clang</title>
		<link>http://www.red-sweater.com/blog/1345/regexkit-clang</link>
		<comments>http://www.red-sweater.com/blog/1345/regexkit-clang#comments</comments>
		<pubDate>Fri, 23 Jul 2010 21:42:21 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/?p=1345</guid>
		<description><![CDATA[I finally updated to Xcode 3.2.3. I was a little late because I had other priorities, but I wanted to get my iPhone projects building and installing onto my iPhone OS 4.0 devices, so I decided to download and install the latest SDK. Unfortunately, this seemingly minor update presented a major failure in my debug [...]]]></description>
			<content:encoded><![CDATA[<p>I finally updated to Xcode 3.2.3. I was a little late because I had other priorities, but I wanted to get my iPhone projects building and installing onto my iPhone OS 4.0 devices, so I decided to download and install the latest SDK.</p>
<p>Unfortunately, this seemingly minor update presented a major failure in my debug builds, which I&#8217;m adventurously compiling using the LLVM clang compiler. They built fine with Xcode 3.2.2, but starting in 3.2.3, I got a linkage failure, tracing back to the popular open source <a href="http://regexkit.sourceforge.net/RegexKitLite/">RegExKitLite</a>:</p>
<pre>
Undefined symbols:
  "___gxx_personality_v0", referenced from:
      _rkl_debugCacheSpinLock in RegexKitLite.o
      ...
  "__ZSt9terminatev", referenced from:
      +[NSString(RegexKitLiteAdditions) clearStringCache]
      in RegexKitLite.o
</pre>
<p>What? Those symbols smack of C++, but there isn&#8217;t any C++ code in my project. At least, I don&#8217;t think there is. RegExKitLite is so famously <em>advanced</em> in its designed, I couldn&#8217;t easily tell you whether there was stuff in there intended as C++ or not. On a whim, I tried to switch the file type to C++ to see if that made clang any happier. No, it screamed bloody murder. It agrees with me, RegExKitLite is <em>not</em> C++ code.</p>
<p>So why the link errors? I examined the compile line carefully for RegExKitLite and confirmed that it&#8217;s using clang in a manner that should only be generating plain C linkage:</p>
<pre>
/Developer/usr/bin/clang -x objective-c -arch x86_64 ...
</pre>
<p>But when I look at the resulting RegExKitLite.o with the &#8220;nm&#8221; command-line tool, it shows the culprits symbols have been listed as references in the binary object file:</p>
<pre>
% nm RegexKitLite.o | grep -e terminate\\\|personality
                 U __ZSt9terminatev
                 U ___gxx_personality_v0
</pre>
<p>Normally when I&#8217;m getting some kind of issue like this, I just type in the problematic symbols in to Google and usually find somebody else has found and solved the problem. No such luck this time. There are lots of false positives for the typical reason somebody runs into this link error: they are compiling legitimate C++ code but neglecting to link with the stdc++ library. But in our case, we are <em>not compiling C++ code</em>, but we&#8217;re ending up with C++ dependencies nonetheless.</p>
<p>I hopped on to the #clang IRC channel on irc.oftc.net, where a couple extremely helpful clang engineers (thanks to dgregor and rjmccall) helped talk me through the problem, and determine that it does seem to be a clang 1.5 bug. They confirmed that with their latest and greatest clang the bug seems to be fixed, but I was curious to confirm it myself, so I <a href="http://clang.llvm.org/get_started.html#build">checked out and built</a> the latest clang, too. Sure enough, all is well for future generations!</p>
<p>But what do we do now, stuck with the clang 1.5 that ships with Xcode? There is a crude workaround: simply link to stdc++. But yuck! All that C++ linkage dirtying up my pristine Objective-C project? Since I only use clang (for now) to build debug builds, I don&#8217;t have too much of a problem doing this. But if I was shipping these binaries I would be very hesitant to make that concession.</p>
<p>Radar #<a href="rdar://problem/8230225">8230225</a>: clang 1.5 forces linkage to C++ for non-C++ source file<br />
(<a href="http://openradar.appspot.com/8230225">Open Radar Link</a>)</p>
<p>The best we can do is report the issue to Apple and let them decide whether it&#8217;s worth their time to backport whatever fix in later clang is missing from clang 1.5. If you have other suggestions for how to work around the problem in the mean time, please do chime in with a comment below.</p>
<p><strong>Update:</strong> The author of RegExKitLite kindly chimed in below with a pointer to the <a href="http://llvm.org/viewvc/llvm-project?view=rev&#038;revision=103938">revision</a> in the clang source repository that that fixes the issue. He also suggests a simple, and seemingly safe workaround, involving a slight tweak to the RegExKitLite source code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/1345/regexkit-clang/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>A Stroke Of Luck</title>
		<link>http://www.red-sweater.com/blog/1150/a-stroke-of-luck</link>
		<comments>http://www.red-sweater.com/blog/1150/a-stroke-of-luck#comments</comments>
		<pubDate>Fri, 09 Apr 2010 18:28:38 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Macintosh]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/?p=1150</guid>
		<description><![CDATA[One of my customers reported a really subtle bug having to do with a keyboard shortcut for a command. I&#8217;m going to change some facts to protect the innocent, but imagine I got a report: &#8220;Every time I press cmd-N to create a new document and start typing, instead of accepting the text, it just [...]]]></description>
			<content:encoded><![CDATA[<p>One of my customers reported a really subtle bug having to do with a keyboard shortcut for a command. I&#8217;m going to change some facts to protect the innocent, but imagine I got a report:</p>
<blockquote>
<p>&#8220;Every time I press cmd-N to create a new document and start typing, instead of accepting the text, it just beeps at me.&#8221;</p>
</blockquote>
<p>This seems impossible to me. Creating a new document and typing into it is fundamental to my product. Surely if it was broken I would know from my own daily testing of the application. I try diligently to reproduce it, but of course, I can&#8217;t. Create a new document. Start typing. Everything works, everybody&#8217;s happy. Except the person who reported the bug.</p>
<p>At some point in my tinkering I stumble upon the bug. Beep. I can&#8217;t type. There it is! What a drag. <em>This application sucks!</em></p>
<p>Now that I&#8217;ve seen and heard the bug with my own eyes, I&#8217;m more committed than ever to fixing it. But how on earth did I do it? I try several more times and am unable to reproduce the problem.</p>
<p>I have only spotted the issue once in my dozens of trials, yet the customer claims it affects him <em>every single time.</em> ﻿What explains this? Maybe it simply doesn&#8217;t happen as often on my Mac as it does on his. My thoughts turn to the brute force of AppleScript. If this happens only once in a blue moon on my Mac, surely I can reproduce it by running a script that iterates the test conditions hundreds or thousands of times. I open AppleScript Editor and enter the following:</p>
<p><pre>
tell application "System Events"
	repeat 100 times
		keystroke "n" using command down
		keystroke "Testing typing"
	end repeat
end tell</pre>
</p>
<p>
Nothing! Even after running it 1000 times, nothing. How can this be? How could something so common for the customer, something that I saw myself <em>once</em>, be so difficult to reproduce on my Mac?
</p>
<p>
After playing around a bit more, I started to reproduce it more readily. What was happening? I couldn&#8217;t figure it out, but something &#8220;felt&#8221; a little different when I reproduced it. I thought carefully about the parameters of the bug, as exemplified (I thought) by my script:
</p>
<ol>
<li>The command key is pressed.</li>
<li>The N key is pressed.</li>
<li>The N key is released.</li>
<li>The command key is released.</li>
<li>Typing into the new document is attempted.</li>
</ol>
<p>
I looked again at the script. Perhaps this &#8220;keystroke&#8221; command is not literal enough. For all I know it&#8217;s circumventing the normal key events that get generated when you type on the keyboard. On a lark, I modified the script to be more explicit:
</p>
<p><pre>
tell application "System Events"
	repeat 100 times
		key down {command}
		key down  "n"
		key up "n"
		key up {command}
		key down "x"
		key up "x"
	end repeat
end tell</pre>
</p>
<p>
Here we have a more literal match with my analysis of what happens. Hold down the command key, press the N key, release, then type something. In this case I just type an x character because I figure any typing is enough to trigger the bug.
</p>
<p>
I ran this 100 times as well and no luck. The bug is simply not reproducible through scripting. I guess I&#8217;ll have to figure out what conditions are making it more likely for the customer to run into the bug. Maybe he has some 3rd party software that is interfering. Or &#8230; wait a minute.
</p>
<p><pre>
tell application "System Events"
	repeat 100 times
		key down {command}
		key down  "n"
		key up {command}
		key up "n"
		key down "x"
		key up "x"
	end repeat
end tell</pre>
</p>
<p>
I ran the modified script and the bug immediately exhibited itself. So what changed? Look carefully and you&#8217;ll see that my previous script assumed that when a keyboard shortcut is pressed, there is a sort of nested symmetry to the order of pressing and releasing the keys. When I press keyboard shortcuts, I hold the modifier keys down throughout the stroke, and release only after the letter key has been released. But this customer has muscle memory that inclines him to instead release the keys in the order they were pressed. When he releases the N key, the command key has &#8220;long&#8221; since been released. </p>
<p>
This subtle difference turns out to trigger a bug in my event monitoring code that, to make a long story short, robs first responder status from the default view in the document. So when he creates a new document, there is no first responder, and his typing just causes a bunch of beeps. When I create a new document, there&#8217;s always a first responder, so I don&#8217;t see the bug.
</p>
<p>
As difficult as this bug was to track down, it would have been near impossible without the theory testing, disproving, and ultimately proving tool of using AppleScript and System Events to zero on in the behavior. Sometimes when the steps a customer provides to reproduce a bug seem <em>exactly the same</em> as what you&#8217;re doing, you&#8217;re just not trying hard enough to find the difference.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/1150/a-stroke-of-luck/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Wil Shipley On Localization</title>
		<link>http://www.red-sweater.com/blog/965/wil-shipley-on-localization</link>
		<comments>http://www.red-sweater.com/blog/965/wil-shipley-on-localization#comments</comments>
		<pubDate>Wed, 21 Oct 2009 03:35:36 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Indie]]></category>
		<category><![CDATA[Links]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/?p=965</guid>
		<description><![CDATA[Lots of great information and sample code to boot. I am always feeling overwhelmed and helpless when it comes to localization. The tools at our disposal don&#8217;t make it easy enough to &#8220;do it perfectly,&#8221; so I end up (for the most part) not offering localizations at all. Maybe I should give in and adopt [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://wilshipley.com/blog/2009/10/pimp-my-code-part-17-lost-in.html">Lots of great information</a> and sample code to boot.</p>
<p>
I am always feeling overwhelmed and helpless when it comes to localization. The tools at our disposal don&#8217;t make it easy enough to &#8220;do it perfectly,&#8221; so I end up (for the most part) not offering localizations at all.
</p>
<p>
Maybe I should give in and adopt Wil&#8217;s strategy of essentially providing a UI that fits all languages. Unwanted white space be damned!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/965/wil-shipley-on-localization/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>User Friendly Heuristics</title>
		<link>http://www.red-sweater.com/blog/909/user-friendly-heuristics</link>
		<comments>http://www.red-sweater.com/blog/909/user-friendly-heuristics#comments</comments>
		<pubDate>Fri, 21 Aug 2009 13:44:44 +0000</pubDate>
		<dc:creator>Daniel Jalkut</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Links]]></category>

		<guid isPermaLink="false">http://www.red-sweater.com/blog/?p=909</guid>
		<description><![CDATA[Wil Shipley writes about the compromised perfection we must strive for in order to provide users an experience that meets their human expectations: &#8220;Classic computer programming has largely failed, because it failed to copy nature. Nothing in nature works 100% of the time, but it sure works well MOST of the time – and when [...]]]></description>
			<content:encoded><![CDATA[<p>Wil Shipley writes <a href="http://wilshipley.com/blog/2009/08/pimp-my-code-part-16-heuristics-and.html">about the compromised perfection</a> we must strive for in order to provide users an experience that meets their human expectations:</p>
<blockquote><p>&#8220;Classic computer programming has largely failed, because it failed to copy nature. Nothing in nature works 100% of the time, but it sure works well MOST of the time – and when it fails, well, you die and get replaced. A human being, for instance, is an absolutely amazing machine, and is provably NOT provably correct.&#8221;</p></blockquote>
<p>I particularly like the example in the second half, having to do with smartly interpreting a typed ISBN numbers for product search. How do you strip the meaningless dashes from a search term, except when they&#8217;re utterly meaningful? This kind of thinking is important to fine-tuning an application. Nobody will appreciate the hours you spent laboring over the question, but for some reason they&#8217;ll just think your product is particularly awesome.</p>
<p>It&#8217;s interesting that the pursuit of perfection in an application has to involve the pursuit of compromise. By solving a problem in a way that degrades gracefully to unsolvable, you offer a happy, possibly even surprise solution to many people who would not otherwise expect one.</p>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.red-sweater.com/blog/909/user-friendly-heuristics/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

