The Future Of Mac App Store Installs

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:

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">



Installed



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.

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.