<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>rentzsch.tumblr.com</title><generator>Tumblr (3.0; @rentzsch)</generator><link>http://rentzsch.tumblr.com/</link><item><title>My Mother Tries an iPhone</title><description>&lt;p&gt;My mother tried an iPhone for the first time. Here&amp;#8217;s my &lt;a href="http://en.wikipedia.org/wiki/Usability_testing#Hallway_testing"&gt;Hallway Usability Testing&lt;/a&gt; report.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Slide to Unlock&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Easy Start. Knew to take her finger, touch the &amp;#8220;slider&amp;#8221; and move it to the right all the way. The instructional text and appearance of a groove that affords sliding the slider along it win the day.&lt;/p&gt;

&lt;p&gt;Problem occurred during release. She&amp;#8217;s being very &lt;em&gt;deliberate&lt;/em&gt; with her actions, which caused an issue here and later. She&amp;#8217;s thinking about what she&amp;#8217;s seeing and her next action, which causes a delay: she didn&amp;#8217;t just quickly lift her finger from the screen to complete the unlock.&lt;/p&gt;

&lt;p&gt;Instead, she unintentionally let her finger slide to the left a bit while waiting for the iPhone to do something (she&amp;#8217;s used to computers also taking a while to do something, so it may not just be her being tentative but also her waiting to see if the machine needs to &amp;#8220;catch up&amp;#8221; to her actions&amp;#8221; (a sadly common occurrence)).&lt;/p&gt;

&lt;p&gt;When nothing happened, she lifted her finger from the screen only to watch the slider spring back to its original virtual resting position.&lt;/p&gt;

&lt;p&gt;She tried again, only more slowly since the machine wasn&amp;#8217;t operating as expected, so perhaps she has to do things even more slowly. Same result.&lt;/p&gt;

&lt;p&gt;I hinted at her to try lifting her finger faster, and then she was able to succeed.&lt;/p&gt;

&lt;p&gt;Suggestion: Slide to Unlock would benefit by taking into account time spent with the finger down on the unlock position and/or additional slop as to what&amp;#8217;s considered a valid unlock request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial Screen&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Seemed fine enough. No problem thinking of icons as touchable buttons. No expressed puzzlement of the two tiers of icons on the top and another set of icons along the bottom (the dock).&lt;/p&gt;

&lt;p&gt;I took the liberty of moving all the apps I knew she wouldn&amp;#8217;t use to the second page and even the Utility apps (Voice Memos, Calculator, etc) out of their confusing group and onto the normal page.&lt;/p&gt;

&lt;p&gt;She mentioned the Clock is wrong. She thought it odd since the other, textual clocks were correct (the first on the Slide to Unlock screen and the uppermost status bar clock). The Calendar app&amp;#8217;s date is correct, so she has no reason to believe that the Clock&amp;#8217;s icon just happens to be static. I never noticed this inconsistency myself.&lt;/p&gt;

&lt;p&gt;Suggestion: while I&amp;#8217;d probably be annoyed at it (especially with the second hand), the Clock app&amp;#8217;s icon should be live and accurate.&lt;/p&gt;

&lt;p&gt;In the same vein, she noted the Weather app must be showing the inside temperature (72°) since it&amp;#8217;s currently in the mid-30°s outside when she was looking at it.&lt;/p&gt;

&lt;p&gt;Suggestion: the Weather app should display the current location&amp;#8217;s weather/temperature or a new, different static icon that&amp;#8217;s clear isn&amp;#8217;t trying to represent current conditions.&lt;/p&gt;

&lt;p&gt;I told her to press the Mail icon. Again she got snagged by her deliberate movements, and accidentally triggered wiggle (icon rearrangement) mode. Apps wouldn&amp;#8217;t launch and she didn&amp;#8217;t know how to fix it.&lt;/p&gt;

&lt;p&gt;Suggestion: wiggle mode is such a bad idea. Better to have a dedicated app to arrange Springboard pages/groups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Safari&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Like many (most?) people, she doesn&amp;#8217;t understand URLs, so I typed in Google from her and then puzzled how to navigate to Google News (google.com now hides it under their burger button). She used Google News on her Mac, so I wanted to show her the same information is available on the iPhone. I wanted her to see something that offered the safety of familiarity.&lt;/p&gt;

&lt;p&gt;She was immediately thwarted when tapping a headline link opened the page in a new tab. Her Google News page was pushed away and the Los Angeles Times&amp;#8217; page came frontmost. Because it was a new page, the back button wasn&amp;#8217;t enabled. She was at a loss at how to go back, not noticing the nondescript tabs button that held the key to her return.&lt;/p&gt;

&lt;p&gt;Suggestion: Safari should initially operate in a simpler single-page-at-a-time mode, which is how nonadvanced users use the web or do a better job of visually indicating and managing multiple tabs. Granted, this is a hard design problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Miscellaneous&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When she opened the Weather app, she wondered whether it was showing the upcoming weather or historical weather.&lt;/p&gt;

&lt;p&gt;I showed her Google Maps and had her type in a old address. She informed me that her fingers were too large to possibly hit the little keyboard. I assured her to try anyway, and after wrestling with finger placement to compensate for her nails (see below) she was able to input an address and switch back to the alphabetic keyboard without prompting (I prompted her on how to switch to the numeric keyboard).&lt;/p&gt;

&lt;p&gt;I sent her a link via iMessage to look at a page on Amazon. The link was long, and wrapped extensively. For some reason tapping anywhere on the link except the first line didn&amp;#8217;t work to open the page. This bug reduced her confidence that blue underlined text is universally tappable on iPhones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Physicality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I told her a few times to press the home button. She was confused as to which button it was. I considered calling it the Rounded Rectangle Button, but that seemed excessively wordy. I wish Apple would have used a house icon (something like ⌂) instead of the current quite-rounded rectangle. The downside is a house icon suggests an orientation, and could be annoying if your primary use is in a different orientation.&lt;/p&gt;

&lt;p&gt;She tried to use her fingernails to touch things, which are long enough that they do a good job of keeping her fingertips away from being detected by the capacitive touch screen. Here a resistive touch screen actually has an edge (not that I&amp;#8217;d ever go back).&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/45615154468</link><guid>http://rentzsch.tumblr.com/post/45615154468</guid><pubDate>Sun, 17 Mar 2013 15:53:29 -0500</pubDate><category>iphone</category><category>usablity-test</category></item><item><title>Semantic Version Branches for Submodules</title><description>&lt;p&gt;When you create a new git repo, you get a master branch for free. That&amp;#8217;s fine in many cases.&lt;/p&gt;

&lt;p&gt;Lately I&amp;#8217;ve been using a different branching system for code that&amp;#8217;s meant to be used as a library (perchance a git submodule or a &lt;a href="http://rentzsch.tumblr.com/post/22061209807/apps-i-love-git-subtree"&gt;subtree&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s how it works:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Name the branch based on the code&amp;#8217;s &lt;a href="http://semver.org/"&gt;Semantic Version&lt;/a&gt;. Examples:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;em&gt;Brand-new code base that&amp;#8217;s still being written:&lt;/em&gt; name the branch &lt;code&gt;semver-0.x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;x&lt;/code&gt; in the branch name denotes a variable, so this branch could house v0.0, v0.1, v0.1.42 and so forth.&lt;/p&gt;

&lt;p&gt;You probably could get away with a simple &lt;code&gt;v0.x&lt;/code&gt; or even &lt;code&gt;0.x&lt;/code&gt;, but I think the explicitness is helpful indicator for humans and paves the way for machine recognition of semantic branch names.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;First version of the code base with a stable public API:&lt;/em&gt; &lt;code&gt;semver-1.x&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Upcoming not-yet-stable second version of code base:&lt;/em&gt; &lt;code&gt;semver-2.x-beta&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Initially I went with &lt;code&gt;semver-2.x-unstable&lt;/code&gt;, but I found myself confused when I came back to the project later. Does that mean the code is unstable and crashy? Or just the API is subject to change? Both?&lt;/p&gt;

&lt;p&gt;Whereas with beta it was instantly clear to me this branch holds the work-in-progress for version 2.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Second version of the code base with a stable public API:&lt;/em&gt; &lt;code&gt;semver-2.x&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There&amp;#8217;s no master branch.&lt;/p&gt;

&lt;p&gt;&amp;#8220;master&amp;#8221; is too generic a concept and it&amp;#8217;s an attractive nuisance for submodules. Too often I look at a project, see lots of branches and no way to immediately tell what&amp;#8217;s going on, so I reach for the familiar: the master branch.&lt;/p&gt;

&lt;p&gt;Learning from my own behavior, I see it&amp;#8217;s important to take away that crutch and force perspective library consumers to understand the project&amp;#8217;s current state and semver branch structure. Fortunately GitHub makes it easy to select a non-master default branch, so it should be mostly transparent to your users.&lt;/p&gt;

&lt;p&gt;Even better, switching the default branch gives the library&amp;#8217;s author the ability to easy start migrating new users to newer versions of your library (while retaining backwards compatibility with your existing users). For example, update your default branch from &lt;code&gt;semver-1.x&lt;/code&gt; to &lt;code&gt;semver-2.x&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;It&amp;#8217;s best if you start off immediately using semver branching, but it&amp;#8217;s straightforward to migrate to them even after you publicly release your library using the old fuddy-duddy master branch model. In that case you&amp;#8217;ll have to weigh the conceptual clarity and usability advantages of deleting the master branch against breaking the assumed-master branch of your clients.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/45552867242</link><guid>http://rentzsch.tumblr.com/post/45552867242</guid><pubDate>Sat, 16 Mar 2013 22:03:23 -0500</pubDate><category>git</category><category>github</category><category>semver</category><category>branch</category><category>sub-modules</category><category>sub-tree</category></item><item><title>NS: Poor Man's Namespacing for Objective-C</title><description>&lt;p&gt;Objective-C unfortunately lacks namespaces. This leads to both compile-time woes and runtime woes. You may have been witness to this runtime warning:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Class SUUpdater is implemented in both MyApp.app/Contents/Frameworks/Sparke and MyAppPlugin. One of the two will be used. Which one is undefined.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While &lt;a href="http://www.optshiftk.com/2012/04/draft-proposal-for-namespaces-in-objective-c/"&gt;Kyle Sluder has been leading the charge&lt;/a&gt; towards getting the feature as a first-class citizen in Objective-C, I&amp;#8217;ve been successfully using a nine-line preprocessor hack for a few years now that effectively works-around the problem. I call it &lt;strong&gt;NS&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#ifndef NS
    #ifdef NS_NAMESPACE
        #define JRNS_CONCAT_TOKENS(a,b) a##_##b
        #define JRNS_EVALUATE(a,b) JRNS_CONCAT_TOKENS(a,b)
        #define NS(original_name) JRNS_EVALUATE(NS_NAMESPACE, original_name)
    #else
        #define NS(original_name) original_name
    #endif
#endif
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Instead of writing your classes like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@interface Person : NSObject
@property(strong) NSString *name;
@end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Write it like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@interface NS(Person) : NSObject
@property(strong) NSString *name;
@end
#define Person NS(Person)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then use the class like you normally would:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Person *p = [Person new];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now your code supports &lt;em&gt;compile-time prefix insertion&lt;/em&gt;. If you don&amp;#8217;t do anything else, your classes will remain unprefixed.&lt;/p&gt;

&lt;p&gt;However, you can now prefix all participating classes with one easy flick of a preprocessor definition:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;-D NS_NAMESPACE=MyFramework
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That turns the code above into:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;MyFramework_Person *p = [MyFramework_Person new];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With judicious targeting of your &lt;code&gt;-D NS_NAMESPACE=&lt;/code&gt; use, this should enable you to work-around class collisions at both compile-time and runtime.&lt;/p&gt;

&lt;p&gt;P. S. I recognize it&amp;#8217;s probably a bad idea for me to squat on something as Apple-generic as &lt;strong&gt;NS&lt;/strong&gt;, but I don&amp;#8217;t care.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;a href="https://twitter.com/uliwitness/status/292151884779765760"&gt;Uli Kusterer points out&lt;/a&gt; this hack doesn&amp;#8217;t cover XIBs, since they reference classes by name and avoid the preprocessor&amp;#8217;s reach.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve only used this technique with pure code libraries, so that limitation hasn&amp;#8217;t bitten me.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/40806448108</link><guid>http://rentzsch.tumblr.com/post/40806448108</guid><pubDate>Thu, 17 Jan 2013 19:43:17 -0600</pubDate><category>cocoa</category><category>ns</category></item><item><title>Nginx Homebrew Support</title><description>&lt;p&gt;If you run nginx on OS X via Homebrew, you&amp;#8217;ll probably be interested in my &lt;a href="https://github.com/rentzsch/nginx-homebrew-support"&gt;nginx-homebrew-support&lt;/a&gt;.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/39939246318</link><guid>http://rentzsch.tumblr.com/post/39939246318</guid><pubDate>Mon, 07 Jan 2013 12:09:16 -0600</pubDate><category>nginx</category><category>homebrew</category><category>github</category></item><item><title>enum =&gt; NSString</title><description>&lt;p&gt;I wish it were possible in C to access an enum&amp;#8217;s name in string form given a type and its integer value. It&amp;#8217;s great for logging/debugging.&lt;/p&gt;

&lt;p&gt;Until that day arrives, here&amp;#8217;s a small Ruby script which automates the process of vending an NSString given typed enum value:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def NSStringFromEnum(input)
  inputArray = input.lines.collect
  typeNameLine = inputArray[-1]
  typeName = typeNameLine.match(/(\w+);/)[1]

  output = "NSString* NSStringFrom#{typeName}(#{typeName} value) {\n    switch (value) {\n";

  constantLines = inputArray[1..-2]
  constantLines.each {|constantLine|
    constantName = constantLine.match(/(\w+)/)[1]
    output += "        case #{constantName}:\n";
    output += "            return @\"#{constantName}\";\n";
    output += "            break;\n";
  }
  output += "        default:\n";
  output += "            return [NSString stringWithFormat:@\"&amp;lt;unknown #{typeName}: %d&amp;gt;\", value];\n";

  output + "    }\n}"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Example input:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;typedef enum {
    JRStream_Disconnected,
    JRStream_Connecting,
    JRStream_Connected,
    JRStream_Disconnecting
}   JRStreamState;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Example output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NSString* NSStringFromJRStreamState(JRStreamState value) {
    switch (value) {
        case JRStream_Disconnected:
            return @"JRStream_Disconnected";
            break;
        case JRStream_Connecting:
            return @"JRStream_Connecting";
            break;
        case JRStream_Connected:
            return @"JRStream_Connected";
            break;
        case JRStream_Disconnecting:
            return @"JRStream_Disconnecting";
            break;
        default:
            return [NSString stringWithFormat:@"&amp;lt;unknown JRStreamState: %d&amp;gt;", value];
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Guess I should mention how I use it. I put this script into an Automator Service. Apparently you can also use &lt;a href="https://twitter.com/_Krisso_/status/277737710712651776"&gt;TextExpander&lt;/a&gt; and probably &lt;a href="http://www.ergonis.com/products/typinator/"&gt;Typinator&lt;/a&gt; as well. Finally, &lt;a href="https://twitter.com/benedictC"&gt;Benedict Cohen&lt;/a&gt; wrote a &lt;a href="https://gist.github.com/4246759"&gt;C macro version&lt;/a&gt; that looks promising.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I extended Benedict Cohen&amp;#8217;s excellent work and I&amp;#8217;m pleased to offer &lt;a href="https://github.com/rentzsch/JREnum"&gt;JREnum&lt;/a&gt;.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/37512716957</link><guid>http://rentzsch.tumblr.com/post/37512716957</guid><pubDate>Sat, 08 Dec 2012 18:05:56 -0600</pubDate></item><item><title>Xcode Comment Alignment</title><description>&lt;p&gt;I finally put my finger on something that&amp;#8217;s been bugging me about Xcode&amp;#8217;s comment indentation since forever.&lt;/p&gt;

&lt;p&gt;For short comments, I typically use &lt;code&gt;//&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// This is a
// short comment.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#8217;s fine unless comments grow long:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// Lengthy essay
// about the high-level
// overview of the code
// perhaps with parameter-level
// machine-readable API documentation.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Having to prefix each of my lines with an &lt;code&gt;//&lt;/code&gt; gets on my nerves, so I switch to classic C comment style:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/*
Lengthy essay
about the high-level
overview of the code
perhaps with parameter-level
machine-readable API documentation.
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, Xcode wants to format it like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/*
 Lengthy essay
 about the high-level
 overview of the code
 perhaps with parameter-level
 machine-readable API documentation.
 */
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note each line after the initial comment opening is prefixed by one space.&lt;/p&gt;

&lt;p&gt;I think this is because Xcode wants to help you line up the asterisks, like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/*
 * Lengthy essay
 * about the high-level
 * overview of the code
 * perhaps with parameter-level
 * machine-readable API documentation.
 */
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However the entire reason I use classic C comments is when I don&amp;#8217;t want to have to bother with per-line prefixes.&lt;/p&gt;

&lt;p&gt;For now I just manually delete the extraneous spaces, but I wish I could easily suppress this behavior.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/36763776883</link><guid>http://rentzsch.tumblr.com/post/36763776883</guid><pubDate>Wed, 28 Nov 2012 16:31:35 -0600</pubDate><category>xcode</category></item><item><title>Functional Cocoa Collections</title><description>&lt;p&gt;&lt;a href="https://twitter.com/tonyarnold/status/272860617084383230"&gt;Tony Arnold / @tonyarnold&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Alrighty guys: best map/reduce/filter categories for NSArray/NSSet/etc — what do you have/use? /cc &lt;a class="twitter-link" href="https://twitter.com/#!/atnan" title="Nathan de Vries"&gt;@atnan&lt;/a&gt; &lt;a class="twitter-link" href="https://twitter.com/#!/orj" title="Oliver Jones"&gt;@orj&lt;/a&gt; &lt;a class="twitter-link" href="https://twitter.com/#!/rob_rix" title="Rob Rix"&gt;@rob_rix&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I made a brief aside about this in the latest &lt;a href="http://www.edgecasesshow.com/028-the-plumbers-guide-to-blocks.html"&gt;Edge Cases episode about blocks&lt;/a&gt;, so Tony&amp;#8217;s question is topical. Here&amp;#8217;s the ones I know about, roughly in order of my first-glace preference:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="https://github.com/robrix/RXCollections"&gt;RXCollections&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/hborders/HBCollections"&gt;HBCollections&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mikeash/MACollectionUtilities"&gt;MACollectionUtilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pandamonia/BlocksKit"&gt;BlocksKit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://underscorem.org/"&gt;Underscore.m&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I haven&amp;#8217;t used any of these in anger yet (but have been happy with &lt;a href="http://underscorejs.org/"&gt;Underscore.js&lt;/a&gt;).&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/36567481825</link><guid>http://rentzsch.tumblr.com/post/36567481825</guid><pubDate>Sun, 25 Nov 2012 21:30:33 -0600</pubDate></item><item><title>mogenerator 1.27</title><description>&lt;p&gt;&lt;a href="http://rentzsch.github.com/mogenerator"&gt;What&amp;#8217;s New&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;[NEW] You can now pass .xcdatamodeld paths to mogenerator. mogenerator will look inside the directory, read its hidden &lt;code&gt;.xccurrentversion&lt;/code&gt; file and use the &amp;#8220;current&amp;#8221; .xcdatamodel file. (&lt;a href="https://github.com/rentzsch/mogenerator/pull/102"&gt;Alexander Zats&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[NEW] Replaced mogenerator&amp;#8217;s previous testing system (the test mule) with a new Rakefile-based system that eases building &amp;amp; testing from the current source tree and tests both MRC and ARC. (&lt;a href="https://github.com/rentzsch/mogenerator/blob/master/test/Test%20README.markdown"&gt;rentzsch&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[NEW] Property declarations generated from attributes can now be qualified as readonly by adding a &lt;code&gt;mogenerator.readonly&lt;/code&gt; to an attribute&amp;#8217;s userinfo. (&lt;a href="https://github.com/rentzsch/mogenerator/pull/111"&gt;crispinb&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[NEW] &lt;code&gt;--configuration&lt;/code&gt; option that limits generation to the specified configuration. (&lt;a href="https://github.com/rentzsch/mogenerator/pull/104"&gt;Sixten Otto&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[NEW] &lt;code&gt;--base-class-import&lt;/code&gt; option for fine-grained control of base class import statements. (&lt;a href="https://github.com/rentzsch/mogenerator/pull/135"&gt;David Aspinall&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[CHANGE] Optimized &lt;code&gt;keyPathsForValuesAffectingValueForKey:&lt;/code&gt; generated code (returns after first match). (&lt;a href="https://github.com/rentzsch/mogenerator/issues/98"&gt;Sean M&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[CHANGE] Add default private class extension to human source template. (&lt;a href="https://github.com/rentzsch/mogenerator/pull/95"&gt;Jonas Schnelli&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[FIX] Align generated code&amp;#8217;s pointer asterisks more consistently. (&lt;a href="https://github.com/rentzsch/mogenerator/pull/103"&gt;Tony Arnold&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[FIX] Missing import when using mogenerator.customBaseClass entity userinfo key. (&lt;a href="https://github.com/rentzsch/mogenerator/pull/109"&gt;Thomas Guthrie&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[FIX] Handle case in generated fetch request wrapper machine code when predicate variables are repeated. (&lt;a href="https://github.com/rentzsch/mogenerator/pull/125"&gt;Sergei Winitzki&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[FIX] Explicitly set mogenerator project&amp;#8217;s deployment target to 10.6 to avoid segfaulting on 10.8 for some reason. &lt;a href="https://github.com/rentzsch/mogenerator/issues/121"&gt;issue 121&lt;/a&gt; (reported by Sixten Otto, diagnosed by Florian Bürger)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[FIX] Cast to unsigned in machine source to avoid clang format string warning. (&lt;a href="https://github.com/rentzsch/mogenerator/commit/82dca52d3fa8082163931141b4e8257f8be8191c"&gt;rentzsch&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[FIX] Don&amp;#8217;t attempt to report errors through -[NSApp reportError:] in generated machine source unless targeting AppKit. (&lt;a href="https://github.com/rentzsch/mogenerator/commit/0f4d8295e98832f5acdab8d24d3193a1141839a8"&gt;rentzsch&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[WORKAROUND] Recent versions of Xcode use an empty string to mark entities that do not have a custom subclass. (&lt;a href="https://github.com/rentzsch/mogenerator/pull/132"&gt;Matthias Bauch&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[CHANGE] make_installer.command: assume PackageMaker now lives in /Applications/Utilities. (&lt;a href="https://github.com/rentzsch/mogenerator/commit/aa4d3d5ba274985bd0a9f636efb0c5c82ce33381"&gt;rentzsch&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://rentzsch.tumblr.com/post/35713971034</link><guid>http://rentzsch.tumblr.com/post/35713971034</guid><pubDate>Wed, 14 Nov 2012 12:13:56 -0600</pubDate><category>mogenerator</category></item><item><title>Simple Code</title><description>&lt;p&gt;&lt;a href="https://twitter.com/damienkatz/status/268272910672740354"&gt;damien katz / @damienkatz&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Invented a design pattern I call &amp;#8220;simple code&amp;#8221;. When I need the code to do something new I &amp;#8220;modify it&amp;#8221;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I&amp;#8217;ve wasted too much brain power over the years over-engineering software, bracing my designs for scenarios that fail to ever materialize.&lt;/p&gt;

&lt;p&gt;My suggestion, at least for the first cut: &lt;a href="http://c2.com/xp/DoTheSimplestThingThatCouldPossiblyWork.html"&gt;do the simplest thing that could possibly work&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re like me, that engages your intellect towards simple solutions instead of over-engineering against invisible foes.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/35654572932</link><guid>http://rentzsch.tumblr.com/post/35654572932</guid><pubDate>Tue, 13 Nov 2012 15:13:13 -0600</pubDate></item><item><title>OS X 10.8 Apple Software RAID</title><description>&lt;p&gt;After &lt;a href="https://twitter.com/rentzsch/status/171854961850851328"&gt;my&lt;/a&gt; &lt;a href="https://twitter.com/rentzsch/status/171863108929859585"&gt;poor&lt;/a&gt; &lt;a href="https://twitter.com/rentzsch/status/171863658991861762"&gt;experience&lt;/a&gt; with Software RAID on Mac OS X 10.7.3, I&amp;#8217;m pleased to report that software RAID on OS X 10.8 seems improved over 10.7.&lt;/p&gt;

&lt;p&gt;Enabling Software RAID does have some tradeoffs:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;&lt;p&gt;You lose &lt;a href="http://www.apple.com/osx/recovery/"&gt;OS X&amp;#8217;s Recovery Partition&lt;/a&gt;. Internet Recovery should still work and you could always build your own &lt;a href="http://support.apple.com/kb/DL1433"&gt;Recovery Disk&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FileVault isn&amp;#8217;t supported.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;For my server purposes, I don&amp;#8217;t care about either of these limitations, so I&amp;#8217;m happy that OS X Software RAID is realistic option again (the &amp;#8220;Repair Disk&amp;#8221; button actually works).&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s how I set up my new 2x1TB Mac mini Server:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.shirt-pocket.com/SuperDuper/"&gt;SuperDuper&lt;/a&gt; the Mini&amp;#8217;s boot drive (&amp;#8220;Server HD&amp;#8221;) onto an external drive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Boot from the external drive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repartition both drives into three slices each: 50GB Boot, 50GB Boot Backup and the rest Data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create three new RAID 1 (Mirroring) sets encompassing those slices, respectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SuperDuper the external drive back onto the Boot RAID volume and boot off it.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Here&amp;#8217;s my set-up as it appears in Disk Utility:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://dl.dropbox.com/u/14209/blog/mac-mini-disk-utility-raid.png" width="943" height="726" alt="Mac Mini Server Disk Utility RAID Setup"/&gt;&lt;/p&gt;

&lt;p&gt;This set-up enables me to perform system software updates with a bootable backup safety-net in place.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m backing up that Data partition offsite, so I&amp;#8217;m not backing it up locally on the Mini itself (I&amp;#8217;m just SuperDuper&amp;#8217;ing the Boot volume to the Boot Backup volume nightly).&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/34660818811</link><guid>http://rentzsch.tumblr.com/post/34660818811</guid><pubDate>Tue, 30 Oct 2012 17:24:24 -0500</pubDate><category>sysadmin</category><category>raid</category></item><item><title>My Amazon Ebook Insurance Policy</title><description>&lt;p&gt;When iTunes Music Store first came out I studied it and decided to buy music off it. Not because I trusted Apple, but because I had a spare Mac that I could use as a DRM lifeboat.&lt;/p&gt;

&lt;p&gt;I copied my purchases as I made them to the old Mac. The Mac was also disconnected from the Internet after its initial authorization. Finally, I had software in place to extract the audio I purchased even if Apple pulled the DRM football from me just as I tried to kick it.&lt;/p&gt;

&lt;p&gt;Fortunately Apple&amp;#8217;s iTMS DRM dog never barked. But after &lt;a href="http://www.bekkelund.net/2012/10/22/outlawed-by-amazon-drm/"&gt;today&amp;#8217;s Amazon Ebook controversy&lt;/a&gt; I decided it&amp;#8217;s time to share my similar Amazon Ebook Insurance Policy:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;&lt;p&gt;Have the Kindle&amp;#8217;s network turned off most of the time. I do this to conserve battery on my Kindle 3, but it has the nice side-effect that Amazon can&amp;#8217;t remotely delete content at its whim.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Buy &lt;a href="http://www.econtechnologies.com/pages/cs/chrono_overview.html"&gt;Chronosync&lt;/a&gt; and set it up to copy purchased Ebooks to my Mac whenever I connect+charge my Kindle. That way I can recover even from an unexpected remote wipe from Amazon.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use (and hopefully donate to) &lt;a href="http://calibre-ebook.com"&gt;Calibre&lt;/a&gt; and then &lt;a href="http://apprenticealf.wordpress.com/"&gt;install plugins&lt;/a&gt; to strip Amazon&amp;#8217;s DRM from your purchased Ebook files. Calibre can then export your .azw and .azw1 files to unencumbered .mobi and .epub formats.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Zachary West &lt;a href="https://twitter.com/zacwest/status/260485896619569150"&gt;offers&lt;/a&gt; specific &lt;a href="http://zacwe.st/blog/kindle-to-epub"&gt;steps on converting Amazon to ePub&lt;/a&gt; using Calibre.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/34116769431</link><guid>http://rentzsch.tumblr.com/post/34116769431</guid><pubDate>Mon, 22 Oct 2012 15:53:57 -0500</pubDate><category>amazon</category><category>ebook</category></item><item><title>Xcode 4 Splits</title><description>&lt;p&gt;One of the features Apple took away in Xcode 4 was splits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/rentzsch/status/259392573058211840"&gt;rentzsch / @rentzsch&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;predicted headline feature of Xcode 5: splits&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But it turns out you can clumsily emulate them with Xcode 4&amp;#8217;s Assistant Editors:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/kongtomorrow/status/259394293796569100"&gt;kongtomorrow / @kongtomorrow&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a class="twitter-link" href="https://twitter.com/#!/rentzsch" title="rentzsch"&gt;@rentzsch&lt;/a&gt; like text splits? already there. View &amp;gt; Assistant Editor &amp;gt; Add Assistant Editor (and various shortcuts)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://twitter.com/rentzsch/status/259395079331004400"&gt;rentzsch / @rentzsch&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a class="twitter-link" href="https://twitter.com/#!/kongtomorrow" title="kongtomorrow"&gt;@kongtomorrow&lt;/a&gt; that only works when you have an assistant editor showing. Very rarely that I do. Need it for standard editor&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://twitter.com/tgaul/status/259396362653802500"&gt;Troy Gaul / @tgaul&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a class="twitter-link" href="https://twitter.com/#!/rentzsch" title="rentzsch"&gt;@rentzsch&lt;/a&gt; &lt;a class="twitter-link" href="https://twitter.com/#!/kongtomorrow" title="kongtomorrow"&gt;@kongtomorrow&lt;/a&gt; You can open the same file in the assistant editor and then stack the editors vertically in your window.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://twitter.com/kongtomorrow/status/259396699200557060"&gt;kongtomorrow / @kongtomorrow&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a class="twitter-link" href="https://twitter.com/#!/tgaul" title="Troy Gaul"&gt;@tgaul&lt;/a&gt; &lt;a class="twitter-link" href="https://twitter.com/#!/rentzsch" title="rentzsch"&gt;@rentzsch&lt;/a&gt; ooh, thanks, thought that was there somewhere. View &amp;gt; Assistant Editor &amp;gt; All Editors Stacked Vertically&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://twitter.com/rentzsch/status/259398066015178750"&gt;rentzsch / @rentzsch&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a class="twitter-link" href="https://twitter.com/#!/kongtomorrow" title="kongtomorrow"&gt;@kongtomorrow&lt;/a&gt; &lt;a class="twitter-link" href="https://twitter.com/#!/tgaul" title="Troy Gaul"&gt;@tgaul&lt;/a&gt; ah that’s clumsy, but it will work when I’m desperate. Thanks!&lt;/p&gt;
&lt;/blockquote&gt;</description><link>http://rentzsch.tumblr.com/post/33912837363</link><guid>http://rentzsch.tumblr.com/post/33912837363</guid><pubDate>Fri, 19 Oct 2012 16:09:32 -0500</pubDate><category>xcode</category></item><item><title>Wherein I Write Apple's Technote About OpenSSL on OS X For Them</title><description>&lt;p&gt;&lt;strong&gt;Technical Note TNNaN: OpenSSL on OS X&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Long story short: we screwed up when we included OpenSSL (&lt;code&gt;libcrypto&lt;/code&gt;) in OS X in the first place.&lt;/p&gt;

&lt;p&gt;(We learned our lesson and didn&amp;#8217;t repeat the mistake with iOS.)&lt;/p&gt;

&lt;p&gt;Now there&amp;#8217;s some transitionin&amp;#8217; to do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommendations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;em&gt;New Code Should Use SecTransform.&lt;/em&gt; SecTransform is cool: it&amp;#8217;s high-level, rather declarative, fast and even leverages GCD. It solves OpenSSL&amp;#8217;s issues described below in the &lt;em&gt;Backgrounder&lt;/em&gt; section.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Code That Uses OpenSSL Just for Hashing Should Switch to CommonCrypto.&lt;/em&gt; CommonCrypto provides a thin OpenSSL compatibility shim for common cryptographic message digests. It&amp;#8217;s called &lt;code&gt;COMMON_DIGEST_FOR_OPENSSL&lt;/code&gt; and lives in &lt;code&gt;CommonDigest.h&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Apps That Need OpenSSL Should Include Their Own Copy.&lt;/em&gt; You should stop using the system&amp;#8217;s supplied &lt;code&gt;libcrypto.dylib&lt;/code&gt;, build your own and link it into your app.&lt;/p&gt;

&lt;p&gt;We know that&amp;#8217;s a pain, but &lt;a href="https://github.com/sqlcipher/openssl-xcode"&gt;this project&lt;/a&gt; should help you out.&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;-isystem "$(SRCROOT)/openssl-1.0.1c/include"&lt;/code&gt; to &lt;code&gt;OTHER_C_FLAGS&lt;/code&gt; to pick up your project&amp;#8217;s local OpenSSL headers instead of the system&amp;#8217;s headers (which are outdated and throb with deprecation attributes).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Backgrounder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The crux of the problem is OpenSSL doesn&amp;#8217;t offer API compatibility between versions.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;d love to ship updated versions of OpenSSL, but there&amp;#8217;s only two feasible routes, both of which are seriously problematic:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;em&gt;Apps link to &lt;code&gt;/usr/lib/libcrypto.dylib&lt;/code&gt; symlink.&lt;/em&gt; In theory we should be able to always point that to the latest version of libcrypto.dylib and apps get free security + capability updates.&lt;/p&gt;

&lt;p&gt;In practice we&amp;#8217;d break shipping apps since the APIs are different. So it&amp;#8217;s kinda stuck. (Notice we&amp;#8217;re still shipping v0.9.8r when v1.0.1c is the latest.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Apps link to a specific version of libcrypto.&lt;/em&gt; For example: &lt;code&gt;/usr/lib/libcrypto.0.9.8.dylib&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now your app doesn&amp;#8217;t get security + capability updates for free. When there&amp;#8217;s a security hole, it&amp;#8217;s now our job to backport the fixes in the latest OpenSSL into the old-ass version your app is linked against.&lt;/p&gt;

&lt;p&gt;Nobody wins in this case.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Ideally the OpenSSL project would do a better job at API compatibility, but it&amp;#8217;s really not in their unixy source-code-oriented worldview. Sure we could get big into the project to try to improve it, but we&amp;#8217;d rather put the resources into making OS X rock harder.&lt;/p&gt;

&lt;p&gt;Both SecTransform and lowly CommonCrypto offer API compatibility, allowing us to add functionality and fix security problems even in shipping apps, which is awesome for users.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/33696323211</link><guid>http://rentzsch.tumblr.com/post/33696323211</guid><pubDate>Tue, 16 Oct 2012 01:06:31 -0500</pubDate><category>openssl</category></item><item><title>Working Around Apple's Deprecation of OpenSSL</title><description>&lt;p&gt;Apple has started deprecating &lt;a href="http://www.openssl.org"&gt;OpenSSL&lt;/a&gt; on Mac OS X 10.7 SDK and later. I guess they&amp;#8217;d prefer you use SecTransform or something. Unfortunately SecTransform isn&amp;#8217;t on iOS yet and even it were, some of us have codebases that aren&amp;#8217;t Apple-platform exclusive. Feels kind of like a dick move to me.&lt;/p&gt;

&lt;p&gt;Anyway, I continued to use OpenSSL in my code &amp;#8212; I just stuck a big fat&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#pragma clang diagnostic ignored "-Wdeprecated-declarations"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;on the top of my OpenSSL-using source files.&lt;/p&gt;

&lt;p&gt;Unfortunately that turns off deprecation warnings for the entire file. I tried downloading OpenSSL (/usr/include/openssl/opensslv.h&amp;#8217;s &lt;code&gt;OPENSSL_VERSION_TEXT&lt;/code&gt; indicates you want v0.9.8r) and using their header files directly but was stumped:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/rentzsch/status/257996351193882620"&gt;rentzsch / @rentzsch&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;lazytwitter: how do I get Xcode to prefer my local openssl header dir to the SDK’s (that’s littered with with deprecation attributes)?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://twitter.com/rentzsch/status/257996370332491780"&gt;rentzsch / @rentzsch&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;(setting &lt;code&gt;ALWAYS_SEARCH_USER_PATHS&lt;/code&gt;, &lt;code&gt;HEADER_SEARCH_PATHS&lt;/code&gt; &amp;amp; &lt;code&gt;USER_HEADER_SEARCH_PATHS&lt;/code&gt; doesn&amp;#8217;t seem to be enough or I&amp;#8217;m doing it wrong)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fortunately Christopher Lloyd answered my query:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/cjwl/status/258001342382096400"&gt;Christopher Lloyd / @cjwl&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="https://twitter.com/rentzsch" title="rentzsch"&gt;@rentzsch&lt;/a&gt; -isystem &amp;lt;myincludedir&amp;gt; added using other c flags should do it&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I just tried it and it works. Thanks again, Christopher!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I take back my &amp;#8220;feels kind of like a dick move&amp;#8221; statement. There are good reasons for Apple to deprecate OpenSSL, I just wish they wrote a Technote about it. So I &lt;a href="http://rentzsch.tumblr.com/post/33696323211/wherein-i-write-apples-technote-about-openssl-on-os-x"&gt;wrote one&lt;/a&gt; for them as penance. Apologies, Apple peeps.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/33677771290</link><guid>http://rentzsch.tumblr.com/post/33677771290</guid><pubDate>Mon, 15 Oct 2012 19:52:27 -0500</pubDate><category>openssl</category></item><item><title>Lich: simple, general, human-sympathetic binary data format</title><description>&lt;p&gt;&lt;a href="https://github.com/rentzsch/lich"&gt;Lich&lt;/a&gt; is my new mostly-human-readable binary data format. Check it out if you like bencode or need a space-efficient JSON.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/32890485420</link><guid>http://rentzsch.tumblr.com/post/32890485420</guid><pubDate>Thu, 04 Oct 2012 15:46:41 -0500</pubDate><category>lich</category></item><item><title>Apple Maps and OpenStreetMaps</title><description>&lt;p&gt;&lt;a href="https://twitter.com/buzz/status/249931973353672704"&gt;Buzz Andersen / @buzz&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Second vintage tactic I wish Apple used with Maps: align Apple resources (a la WebKit) with a promising open source effort (OpenStreetMaps).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I agree with Buzz here: feels like a missed opportunity for Apple and indeed humanity.&lt;/p&gt;

&lt;p&gt;Apple &lt;a href="http://blog.osmfoundation.org/2012/03/08/welcome-apple/"&gt;uses OpenStreetMaps in iPhoto for iOS&lt;/a&gt;, so it&amp;#8217;s not like they never heard of the project. I can only surmise somehow OpenStreetMaps wasn&amp;#8217;t a fit (or Apple knew it was about to pour a billion dollars into a project and didn&amp;#8217;t want to share the project&amp;#8217;s fruits with competitors).&lt;/p&gt;

&lt;p&gt;See also: &lt;a href="http://llvm.org/"&gt;llvm&lt;/a&gt; and &lt;a href="http://www.marco.org/2011/04/09/facebooks-open-compute-project"&gt;Facebook&amp;#8217;s Open Compute Project&lt;/a&gt;.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/32782951117</link><guid>http://rentzsch.tumblr.com/post/32782951117</guid><pubDate>Tue, 02 Oct 2012 21:54:22 -0500</pubDate></item><item><title>Edge Cases Podcast</title><description>&lt;p&gt;I started a new Apple-developer-related podcast with my friend &lt;a href="https://twitter.com/apontious"&gt;Andrew Pontious&lt;/a&gt; called &lt;a href="http://www.edgecasesshow.com/"&gt;Edge Cases&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To kick off the show we&amp;#8217;re going to catch up with our backlog and post an episode each day this week.&lt;/p&gt;

&lt;p&gt;&lt;a href="pcast://feeds.feedburner.com/EdgeCases"&gt;Click here&lt;/a&gt; to subscribe to the show.&lt;/p&gt;

&lt;p&gt;You can also follow the show on twitter: &lt;a href="https://twitter.com/edgecasesshow"&gt;@edgecasesshow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Special thanks to &lt;a href="https://twitter.com/violasong"&gt;Victoria Wang&lt;/a&gt; for the website design and coding.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/25370949798</link><guid>http://rentzsch.tumblr.com/post/25370949798</guid><pubDate>Mon, 18 Jun 2012 12:11:47 -0500</pubDate><category>edgecases</category></item><item><title>Mac App Store vs Buying Direct</title><description>&lt;p&gt;Since the launch of the Mac App Store, a common question potential customers ask developers is &amp;#8220;Should I buy your app directly or through the Mac App Store?&amp;#8221;&lt;/p&gt;

&lt;p&gt;Developers have been remarkably cagey, mostly replying with the non-answer &amp;#8220;choose whichever is better for you&amp;#8221;.&lt;/p&gt;

&lt;p&gt;Fortunately Apple now only accepts sandboxed Mac apps, clarifying the situation: &lt;strong&gt;customers should buy Mac apps directly&lt;/strong&gt; unless there&amp;#8217;s a good reason not to.&lt;/p&gt;

&lt;p&gt;Here are some reasons why it&amp;#8217;s preferable to buy non-sandboxed apps directly from developers:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Better App User Experience:&lt;/strong&gt; Non-sandboxed apps can auto-navigate the user to correct folders in Open/Save panels, run user-written AppleScripts, control iTunes* and install PDF Services automatically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;More features:&lt;/strong&gt; Non-sandboxed BBEdit can directly edit files that require administrator privileges, non-sandboxed OmniFocus can automatically determine the selected document in the Finder when creating a clipping. &lt;a href="http://www.macworld.com/article/1167055/sandboxing_deadline_arrives_what_it_means_for_apple_developers_and_you.html"&gt;There&amp;#8217;s lots more&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Better Data Integrity:&lt;/strong&gt; Document-based Core Data apps are &lt;a href="http://christiankienle.blogspot.de/2012/05/core-data-document-based-application.html?m=1"&gt;incompatible with Sandboxing&lt;/a&gt;. One work-around is to disable disk-based journaling, increasing the risk of data corruption. It appears sandboxed Core Data Mac apps will need to switch to packages for a long-term solution, changing file formats for no good reason (and packages are less convenient for data sharing than flat files).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;More and Faster Updates:&lt;/strong&gt; Different developers follow different update schedules, but typically direct apps get updated more often and with less latency than Mac App Store apps. Some developers intentionally throttle down their direct update schedule to match Apple&amp;#8217;s delays and avoid customer confusion, but that&amp;#8217;s the developer&amp;#8217;s decision.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Less Risk of Losing Your Software Investments:&lt;/strong&gt; I bought &lt;a href="https://mizage.com/divvy/"&gt;Divvy&lt;/a&gt; via the Mac App Store. Unfortunately Divvy relies on Apple&amp;#8217;s Accessibility APIs, which aren&amp;#8217;t allowed for sandboxed apps. That means aside from minor bug fixes, I will no longer receive updates for the application I purchased.&lt;/p&gt;

&lt;p&gt;Some developers are &lt;a href="http://www.red-sweater.com/blog/1678/this-app-is-your-app"&gt;going out of their way&lt;/a&gt; to allow seamless cross-grading from Mac App Store versions of their apps to direct apps, which is commendable and helps alleviate somewhat the situation Apple has created.&lt;/p&gt;

&lt;p&gt;Sandboxing is just the latest App Store rule change, I&amp;#8217;m sure there&amp;#8217;s more to come. All things being equal, it&amp;#8217;s safer to buy directly instead of being cut off from your own software based on an arbitrary Apple policy change.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;More Money Goes to the Developer:&lt;/strong&gt; For a $10 application, only $7 goes to the developer when you buy it through the Mac App Store. For a direct purchase, it&amp;#8217;s more on the order of $9.&lt;/p&gt;

&lt;p&gt;The fact more developers weren&amp;#8217;t encouraging customers to buy directly is a testament to how much Mac developers care about User Experience &amp;#8212; they&amp;#8217;re willing to forego the extra profit of selling direct to make things easier for their customers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;However, as alluded to above, there are downsides to buying directly. Buying through the Mac App Store offers these benefits:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Better Purchasing Experience:&lt;/strong&gt; Apple probably already has the customer&amp;#8217;s credit card on file. No .zip to unpackage and drag into the right place. It Just Works.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Better Maintenance Experience:&lt;/strong&gt; Buy a new Mac, launch App Store.app and enter your Apple credentials. Ta-da, a list of the apps you purchased ready to reinstall. No trying to remember what apps you previously had installed, who wrote them, what the developer&amp;#8217;s website is or what your license key was.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;iCloud Access:&lt;/strong&gt; Apple has decided only Mac App Store apps (and thus now sandboxed apps) can access iCloud. Fortunately this isn&amp;#8217;t much of an issue since the smart folks at &lt;a href="http://www.smilesoftware.com/"&gt;SmileOnMyMac&lt;/a&gt; have already demonstrated a work-around of having a &amp;#8220;&lt;a href="http://itunes.apple.com/us/app/pdfpen-cloud-access/id494133864?mt=12"&gt;bridge&lt;/a&gt;&amp;#8221; Mac App Store application which allows its directly-sold PDFPen to access iCloud as well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Vetted By Apple:&lt;/strong&gt; I don&amp;#8217;t hold this benefit in very high regard, but it does add a safety net versus downloading and running arbitrary software off the web. For example, I&amp;#8217;m looking forward to &lt;a href="http://www.macworld.com/article/1165408/mountain_lion_hands_on_with_gatekeeper.html"&gt;10.8&amp;#8217;s Gatekeeper&lt;/a&gt; as a way of limiting the software my mother downloads and attempts to run on her Mac (though this is apparently &lt;a href="http://www.maclife.com/article/howtos/how_limit_mac_app_store_access_parental_controls"&gt;possible since 10.6&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The bottom line is that sandboxing has effectively collapsed the ambiguity and customers should now purchase their apps directly instead of through the Mac App Store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;* Update:&lt;/strong&gt; Originally I wrote here &amp;#8220;send Growl notifications&amp;#8221;. I was corrected by Growl Project CEO &lt;a href="https://twitter.com/The_Tick"&gt;Chris Forsythe&lt;/a&gt; that the version of Growl in the Mac App Store appears to now listen on a machine-local network port, which works around sandbox-disallowed Mach messaging.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/24207015641</link><guid>http://rentzsch.tumblr.com/post/24207015641</guid><pubDate>Mon, 04 Jun 2012 14:58:36 -0500</pubDate><category>appstore</category></item><item><title>Apps I Love: git-subtree</title><description>&lt;p&gt;My thinking was fuzzy in regards to &lt;a href="http://book.git-scm.com/5_submodules.html"&gt;what&amp;#8217;s&lt;/a&gt; &lt;a href="http://progit.org/book/ch6-6.html"&gt;wrong&lt;/a&gt; &lt;a href="http://blog.fournova.com/2012/02/introducing-git-submodules-in-tower/"&gt;with&lt;/a&gt; git submodules. So I finally opened up an editor window and started typing how I think an Ideal Submodule System should work. I wound up with this:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;&lt;p&gt;The subproject is copied into the super-project&amp;#8217;s repo. At least a snapshot of it, if not the entire history. It&amp;#8217;s a fact of life external resources have a habit of disappearing &amp;#8212; this helps makes your project resilient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git clone foo&lt;/code&gt; is enough. None of this &lt;code&gt;git clone --recursive foo&lt;/code&gt; or &lt;code&gt;git submodule init &amp;amp;&amp;amp; git submodule update&lt;/code&gt; business.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can easily pull subproject updates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can easily push subproject updates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can easily handle super-project branching.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Super-project&amp;#8217;s commits don&amp;#8217;t wind up in subproject&amp;#8217;s history.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subproject&amp;#8217;s commits don&amp;#8217;t wind up in super-project&amp;#8217;s history.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Armed with clearer thinking, I reexamined my options and have settled on &lt;a href="http://apenwarr.ca/log/?m=200904#30"&gt;Avery Pennarun&amp;#8217;s git-subtree&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately its CLI UX is lacking (you have to specify the subproject&amp;#8217;s entire remote repo URL each time you pull or push) and Avery hasn&amp;#8217;t accepted pull requests or budged the project for a year. Fortunately &lt;a href="https://github.com/helmo/git-subtree"&gt;Helmo forked Avery&amp;#8217;s repo&lt;/a&gt;, added &lt;code&gt;.gittrees&lt;/code&gt; support and &lt;code&gt;push-all&lt;/code&gt; and &lt;code&gt;pull-all&lt;/code&gt; subcommands, and generally seems to be keeping on top of pull requests and moving the project forward.&lt;/p&gt;

&lt;p&gt;I just started using &lt;code&gt;git-subtree&lt;/code&gt;, but so far it&amp;#8217;s making my life better than before.&lt;/p&gt;

&lt;p&gt;P.S. Here&amp;#8217;s a &lt;a href="http://ruleant.blogspot.com/2011/04/git-subtree-module.html"&gt;short primer on using git-subtree&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Hmm, I discovered and turned to Helmo&amp;#8217;s fork after I got tired of reentering my remote repo URL each time I wanted to push or pull a subtree. Turns out Helmo&amp;#8217;s fork is currently unstable &amp;#8212; the tests don&amp;#8217;t pass and there&amp;#8217;s a definite bug in it when adding a repo as a subtree that doesn&amp;#8217;t show up until you attempt push it back. So I recommend using &lt;a href="https://github.com/apenwarr/git-subtree"&gt;Avery&amp;#8217;s original repo&lt;/a&gt; until it&amp;#8217;s fixed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 2:&lt;/strong&gt; I fixed the bug and tests are passing in my &lt;a href="https://github.com/rentzsch/git-subtree"&gt;git-subtree fork&lt;/a&gt;. &lt;code&gt;git subtree push-all&lt;/code&gt; away!&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/22061209807</link><guid>http://rentzsch.tumblr.com/post/22061209807</guid><pubDate>Mon, 30 Apr 2012 04:07:59 -0500</pubDate><category>git</category><category>sub-modules</category><category>appsilove</category><category>subtree</category></item><item><title>Backup Chrome tabs with JSTalk</title><description>&lt;p&gt;Sometimes Chrome has trouble restoring its windows and tabs upon launch (the windows and tabs open, but their content never loads). The worst thing about this bug is that it tends to happen only when I have large number of windows and tabs to restore.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve added the following JSTalk script to my nightly backup routine. It writes out the names and URLs of all open tabs to a text file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var chrome = [SBApplication application:'Google Chrome'];
var windows = SBElementArrayToJSArray([chrome windows]);
var output = '';
windows.forEach(function(window){
    var windowName = [window name];
    if (windowName != 'New Tab') {
        var tabs = SBElementArrayToJSArray([window tabs]);

        output += windowName + '\n';
        tabs.forEach(function(tab){
            output += '\t' + [tab title] + '\n';
            output += '\t' + [tab URL] + '\n\n';
        });
    }
});

Date.prototype.getShortWeekdayName = function(){
    return ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][this.getDay()];
};
var tabsBackupFileName = 'tabs_' + (new Date()).getShortWeekdayName() + '.txt';
var tabsBackupFilePath = [@"~/Documents/backup/browser" stringByExpandingTildeInPath];
tabsBackupFilePath = [tabsBackupFilePath stringByAppendingPathComponent: tabsBackupFileName];

[[NSString stringWithString:output] writeToFile:tabsBackupFilePath atomically:NO encoding:NSUTF8StringEncoding error:nil];

function SBElementArrayToJSArray(sbArray) {
    var sbIdx = 0;
    var sbCount = [sbArray count];
    var result = [];
    for (; sbIdx &amp;lt; sbCount; sbIdx++) {
        result.push([sbArray objectAtIndex:sbIdx]);
    }
    return result;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It uses Cocoa&amp;#8217;s Scripting Bridge to enable JSTalk to talk to Chrome via its AppleScript interface.&lt;/p&gt;</description><link>http://rentzsch.tumblr.com/post/21587071628</link><guid>http://rentzsch.tumblr.com/post/21587071628</guid><pubDate>Sun, 22 Apr 2012 13:29:43 -0500</pubDate><category>chrome</category><category>jstalk</category></item></channel></rss>
