Blast From The Past

January 20th, 2011

Following the cues of friends Shawn Blanc, Marco Arment, and Neven Mrgan, among others, I’m digging in to the Red Sweater Blog archives to find some older posts that I think are worth reading, if you missed them the first time around.

I love the idea of highlighting things that others have written, but since I don’t have a convenient repository of these items, and haven’t got time to scour my mind for suitable candidates, I’m sticking to what I know best. Presented here with a brief synopsis:

  • AdiĆ³s a las Computadoras Dell. On the eve of Apple’s transition to Intel processors, I speculate that the end is nigh for Dell.
  • Magical Code. Based on my experience working at very low levels inside Apple, and on my own high level stuff, I dispel the notion that any code is so magical that you can’t understand it.
  • Five Things I May or May Not Know. Particularly meaningful for folks who are grappling with the idea that their full-time work is not for them, and are toying with the idea of branching out on their own.
  • The Road Less Traveled. The story of my transition from a full-time Apple engineer to a self-bootstrapped software business owner.
  • Forget the Shortest Path. Wisdom inspired by lessons in sailing. Sometimes moving directly at your objective is not the most pragmatic way of reaching it.
  • It Should Be Free. My reaction to the expectation among some customers that things should be free. I dig into the true cost of “free” things.
  • Getting Pretty Lonely. My rant against the GPL open source license.
  • Elements of Twitter Style. My fairly recent prescription for getting the most out of Twitter, while annoying the fewest.

Thanks, as always, for your attention to my blog and my writing.

Instapaper Keyboard Shortcut

January 14th, 2011

Like many people these days, I am using Marco Arment’s Instapaper to facilitate effortless postponement of reading longer, potentially interesting content I find on the web.

Marco provides a handy bookmarklet that you can add to your browser’s button bar, so when you find something cool you just click “Read Later” and it gets added to your Instapaper collection. This is handy, and if you’re using a browser like Safari, these bookmark bar items even get mapped to default keyboard shortcuts based on their position, e.g. Cmd-1, Cmd-2, etc.

My news reader of choice, NetNewsWire, also supports Instapaper, allowing me to easily add any news item’s underlying content to my “Read Later” list. In NetNewsWire, the keyboard shortcut is Ctrl-P (for paper!), and I’ve gotten hard wired to punting stuff to my reading list with a quick flick of the keys.

For months I’ve thought it would be nice if I had the same workflow in Safari and in NetNewsWire: see something, want to read it, don’t have time, press Ctrl-P. I don’t know why I took so long to sit down and spend the 5 minutes it took to write an AppleScript wrapper for Marco’s bookmarklet, and install it in my scripts folder to invoke with FastScripts.

If you want to be cool like me:

  1. Download and install FastScripts. Free for up to 10 shortcuts!
  2. From the FastScripts menu-bar icon, select FastScripts -> Create Safari Scripts Folder.
  3. Download this script, and move it to the Safari-specific scripts folder: [Home] -> Library -> Scripts -> Applications -> Safari
  4. Switch to Safari.
  5. While holding the Cmd key, select “Read Later” from the FastScripts menu.
  6. Assign a keyboard shortcut of your choice. (Ctrl-P for NNW-likeness).

Now whenever you see a cool page in Safari, just press Ctrl-P to instantly tag it for later reading.

Update: David Kendal observes on Twitter that you can assign custom keyboard shortcuts to bookmarks in Safari by simply using the System Preferences Keyboard Shortcuts and assigning to the correctly named bookmark. I was not aware that this would work with bookmarks! Very cool. It diminishes the necessity of the above workflow considerably, though I was pleased to be able to take “Read Later” out of my bookmarks bar. Another downside to the System Preferences route? Apparently the keyboard shortcuts will never take effect until you’ve shown the menu that they appear in at least once per Safari-launch.

The Mac App Store Debug Menu

January 9th, 2011

I can’t help myself. It’s probably worth noting that nobody knows for sure what these options do, and you might do serious damage to your Mac or your App Store account by playing with them. But … just a look can’t hurt … can it?

  1. Quit App Store.app
  2. Open Terminal
  3. defaults write com.apple.appstore ShowDebugMenu -bool true
  4. Relaunch App Store

Enjoy it while you can. I’m sure it will be gone in the next update, especially if anybody at Apple sees this post.

The Future Of Mac App Store Installs

January 7th, 2011

It’s only been one day since the launch of the Mac App Store, and the Mac developer and user communities are buzzing with consequences, both good and bad, of the store and how it operates.

One particularly vexing issue is the question of whether an app that is already on your Mac is “installed” or not in the eyes of the App Store application. Dan Moren of Macworld presents a great summary of the situation.

In a nutshell: if App Store thinks an app is installed, it’s impossible to buy it. If App Store thinks an app is installed, but it’s not really from the App Store, there’s a risk of repurchasing something that you already own a license for.

What this brings into focus is the very problematic nature of that small multi-purpose button the App Store, that allows for either buying an app you don’t own, or for linking to an app that you do own:

App Store-2.jpg

As it happens, the App Store user interface is implemented primarily in HTML. Using a surprisingly under-appreciated feature of WebKit, the omnipresent web inspector, I was able to look behind the scenes at some of the interesting HTML that supports this Buy/Installed button. For Black Ink’s button above, this is what I see:

<button version-string="1.2.3" is-rental="0" is-pre-order="0"

buy-params="productType=C&amp;price=24990&amp;

salableAdamId=402376365&amp;pricingParameters=STDQ"

preflight="http://a1757.phobos.apple.com/us/r1000/ 057/Purple/e7/fb/12/mzm.gytejomu.pfpkg"

is-install-button="0"

large-icon="http://a1.phobos.apple.com/us/r1000/013/ Purple/74/8c/bb/mzi.wpgwhzjm.170x170-75.png"

is-update="0" item-name="Black Ink" adam-id="402376365"

is-free-download="0" bundle-id="com.red-sweater.blackink.macappstore"

metrics-leaf="1" metrics-loc="Buy" title="Buy, Black Ink: $24.99"

disabled="" its-bound="iTSBuyButton">

<span class="price"></span>

<span class="action">Installed</span>

</button>

Formatting XML, even with a cool app like MarsEdit, is still a huge pain. I’ve tried to make it readable here so you can enjoy some of the interesting tidbits in this markup. There are some tantalizing attributes like is-update and is-free-download, which might lead some of us to imagine whether a paid update may be a configuration away. There’s some hocus-pocus sale parameters which surely mean something to iTunes on the other end of the network connection, and there’s a link to the application’s pretty icon.

Wondering about that global web inspector trick? Any application that has the NSUserDefaults key WebKitDeveloperExtras defined to YES receives access to the sexy WebKit web inspector that is so awesomely utilized in Safari. You can define this for the App Store app by running this from the command line in a Terminal window: defaults write com.apple.appstore WebKitDeveloperExtras -bool true Make sure you quit App Store before you run it, then relaunch it.

But What’s Really Interesting…

All of this is fun to poke around at, but what I find fascinating is the preflight attribute, which points to a mysterious asset on the web. This “.pfpkg” file, which as it turns out is simply xar archive format, contains an interesting file called Distribution, an XML-formatted file that contains rules and attributes for how the application should be installed, how the App Store should locate an “Installed” app on the user’s Mac, etc. I’m not going to the trouble of color formatting this one, but have a look in a separate window:

View Black Ink’s Preflight Rules

I believe the format for this XML document is either completely or partially tied up in the way the Mac OS X Installer packages work. I have been lucky enough in my lifetime not to have to do all that much with installer packages, so I am not sure exactly how to parse the whole file. It’s clear however, that the file contains information about the application, its version and bundle identifier. It also contains similar information for each of the frameworks that ships with the application.

But the interesting stuff begins below that, where we see flags such as customize=no, and an alluring volume-check, which seems to be terminology from Installer-land that alludes to installers being able to determine whether the targeted volume is suitable for installation.

As you can see, the Black Ink preflight document is pretty boring. No, there is no customize flag. No, there are no interesting volume-check attributes, aside from the fact that this requires 10.6.6, like every other dang app on the Mac App Store. Yawn.

I decided to take a look at another application in the App Store. One that, if anything was going to be interesting, surely this one would be.

App Store-3.jpg

One of the things I keep reminding myself, when trying to deduce what Apple’s plans are for a variety of “would be nice” features in the App Store, such as upgrades, trials, etc., is “how does the current setup inconvenience Apple itself?” Many of Apple’s apps are shipped for free with the system and are updated for free along with OS updates. But others are not: iLife and iWork are sold in a bundle with no upgrade pricing, and other apps such as Final Cut Pro and Logic have complicated pricing, which perhaps explains why they aren’t on the App Store at all. But Aperture falls right in the middle: fairly straight-forward pricing, but it’s expensive enough that they offer reasonable upgrade charges for users who already own a license. Maybe there will be something interesting in these preflight rules:

View Aperture’s Preflight Rules

The file length alone indicates that something slightly more complicated is going on, and my eyes are drawn immediately to the JavaScript code in the middle of the document, and a function named shouldAllowPurchaseAndInstall(). Hmm, you mean there’s a choice? Usually what happens when you click “Buy” in the App Store, is you are prompted to login if necessary, and then you are warned that this is going to cost you money, it’s a big deal, etc. But as far as I can tell, a side-effect of clicking Buy in the App Store is that the aforementioned volume-check is also run on the target system, giving App Store one last chance to bail out of the process before something unfortunate is done.

In Aperture’s case, you can see by the nicely commented script that it takes care to only allows the Buy order to go through under certain circumstances. In making this determination, it checks all of the installed copies of Aperture on the system, looking for signs of App Store purchase such as the presence of a “_MASReceipt” inside the app. It also takes care to differentiate between different versions of Aperture, failing in some cases with a specific string that is presumably passed along to the App Store user.

If you’ve managed to follow along this far, you’re probably putting two and two together and realizing that the technology exists today for applications to avoid at least one of the problems mentioned above: the inadvertent redundant purchase that may happen when a user thinks it’s safe to buy an app, because “they already have a license.”

The preflight XML document may be documented in part or in full in the context of Mac OS X Installer Packages, but as far as I know, none of this is documented in the context of the Mac App Store. I do not know if any 3rd party developer has been invited to use this technique, or if it’s something we could just put into our installer packages somehow on our own, and hope for the best.

What’s most interesting about all this is that there is clearly an infrastructure in place for allowing a wide variation of behaviors, all centering around the multi-purpose Buy/Installed button in the App Store. I would like to see the volume-check options documented and made explicitly available to developers, so that we can help prevent unwanted redundant purchases on the part of our customers. I would also be curious to know if other hooks are in place or are planned to for example allow developers whose apps do show up as installed to second-guess that assumption and encourage the App Store to provide a “Buy” option to customers.

Where we’re going, only Apple knows, but I thought the details I discovered in this nook of the App Store app offer some interesting clues. I’m also interested in sharing this because I believe that the more we understand about the App Store install process, the better we’ll be able to offer meaningful enhancement requests to Apple. “Support paid upgrades” and “Allow variable behavior depending on installed apps” are fine feature requests, but if we are able to put them into the context of what Apple already knows is possible, they may be more likely to get implemented.

If anybody else has delved into the underbelly of the App Store and has observations to share, please do so in the comments, or with a link to your own blog article on the subject.