Mac App Store Receipts and Mavericks

The storeagent and I aren’t getting along too well these days.

We’re in the process of getting a new release of xScope ready for release. As a developer tool, we’ve been compatible with Mavericks for several months now, but there are some minor bug fixes that we’d like to get out before the new version of OS X ships.

As you might be aware, this is the first time I’ve done a build on Mavericks itself. Things haven’t exactly been smooth sailing.

Today’s revelation is how storeagent creates the /Contents/_MASReceipt/receipt file in Mavericks. It’s subtly different, and will confuse the heck out of you until you understand what’s going on.

For the past few days, I’ve been testing a beta release of the .pkg using the standard command:

sudo installer -store -pkg /tmp/xScope.pkg -target /

This version had a CFBundleShortVersionString of “3.6.2b1”. The installer and receipt checking code was working great.

Until I did the final build and used the version string “3.6.2”. I got this message after I double-clicked the app and entered my Test User Apple ID:

After checking the code signing, bundle IDs and all other parts of the app, I finally fired up the debugger and discovered that the receipt validation code was failing when checking receipt attribute type 3, the Application version field (in Table 1-1).

After decrypting and checking the receipt payload, the value was “3.6.2b1” not the version I just installed. Where did this old version number come from? Why did following the advice in the dialog and deleting the app not fix the problem. How come this old receipt kept showing up no matter what I did?

Receipts from older versions had never been a problem in previous versions of OS X, so there must be some new behavior in Mavericks. And it took me almost a whole day to figure out that new behavior.

It turns out that storeagent is doing some kind of in-memory cache of receipts that have been downloaded from iTunes. Since a network connection is needed to retrieve the receipt, keeping it around would prevent a little bit of network traffic. In previous versions, the receipt was presumably recreated each time it was requested, so you always had a fresh copy.

The workaround is fairly simple. It even gives me a bit of pleasure at this point:

$ killall -KILL storeagent

You’ll need to delete the app at this point and re-install it using:

$ sudo installer -store -pkg YourApp.pkg -target /

When you relaunch your app, you’ll see the Apple ID login dialog. Since storeagent is launched on demand by launchd, a new process will be started at this point. After entering your Test User credentials, a new, and valid, receipt will be written into the _MASReceipt folder.

One could imagine this caching of receipt data being a problem with apps that are downloaded from the App Store. If someone never reboots between two versions of the same app being “Ready for Sale”, it may trigger the same problem. I have no way to test this hypothesis.

For any Apple folks that might be reading, here you go: rdar://problem/15283740

Sonderklasse

Let’s talk about cars for a second.

If you’re driving a car manufactured in the past five years, it’s likely it has anti-lock brakes. A standard feature at this point in time, but who came up with it first?

Mercedes-Benz first introduced it on the S-Class line back in 1978. It was a revolutionary technology and the first hint of how digital electronics would change the course of the automotive industry.

The S-Class pioneered many other safety innovations: crash crumple zones, air bags and traction control are a few of the most notable. This line has also become synonymous with comfort and luxury: it was the first Mercedes to be available with an automatic transmission. There’s even an armored version with a customized crocodile, gold and birch interior!

It’s clear this car is in a class by itself: “Sonderklasse”

“S-Class” is an anglicisation of “”S-Klasse,” a German abbreviation of “Sonderklasse,” which means “special class” (in the sense of “a class of its own”). In automotive terms thus refers to “a specially outfitted car”.

The current S600 model sports a 5.5L twin turbo V12 motor with a 7-speed automatic transmission. Enough power to propel a 4,950 lb vehicle from 0 to 60 mph in just 4.5 seconds. And that’s before AMG gets their hands on it. Impressive automotive technology, to be sure.

More importantly, these special cars have been recognized as a driving force behind the company’s success.

And now…

Another premium technology brand has an S-Class product: iPhone 5s.

“Craftsmanship”, “Power”, “Safety & Security”, “Ahead of its time”. Are we talking about a car or a phone?

Look at the words that dominate the iPhone 5s features page: Forward thinking. That’s a strategy that’s worked superbly at Mercedes-Benz for almost 60 years. I suspect Apple will get a pretty good run out of it, too.

It’s the Production Line, Stupid

“Apple Absolutely Has To Make An iPhone With A Bigger Screen”

(Warning: Business Insider link)

While that may be true, take a look at what happened at the end of last year: 47.8 Million iPhones Sold.

That’s a shitload of iPhones. But how many is a shitload?

47.8M iPhones
/ 90 days = 530K per day
/ 24 hours = 22K per hour
/ 60 minutes = 369 per hour
/ 60 seconds = 6 per second

That means that every second of every day you need six cases, six headphone jacks, six LCD screens, six batteries, six CPUs, six 10µf capacitors, six 10kΩ surface mount resistors, and thousands of other components.

Look at where all the leaks about new products come from: it’s always the supply chain that produces all these components. This should give you an idea of how many partners are involved.

Basically, Apple creates a pipeline that produces devices at an amazing rate. And it’s a finely tuned machine with a lot of inertia. You don’t just walk in and say, “Hey, let’s change the screen!” Doing so would throw that machine out of balance: a new screen means that some of the components (like the headphone jack) don’t change, while others would (the case, for example.)

A finely tuned production machine takes a lot of time and money to set up. Take a look at Apple’s capital expenditures. A mere $10B in 2012.

These capital expenditures show that Apple is planning ahead. At least 2-3 years, maybe more. You don’t just walk into Foxconn and ask for 50M iPhones. You need to predict the future.

Sure, it would be great to have a larger screen iPhone from what is known about current market conditions. But was a larger screen a sure thing 2-3 years ago? While you were falling in love with the new Retina display on your iPhone 4, I bet you weren’t thinking “Man, this display has got to be bigger!”

The cost to setup that production line is also a part of the final cost of the device. More frequent changes to the production line means that each device costs more or earns less profit for Apple.

As Apple continues to sell ever more devices, I see two things that could happen:

  1. A broader range of products (meaning more, smaller production lines to spread the demand)
  2. Increase the size of the production lines along with amount of time they stay online (meaning new devices are introduced every three years instead of two)

Given the highly competitive nature of the mobile space, I suspect we’ll see the first option come into play in the coming years. In the meantime, screens tick, while speed tocks:

Launch Services Woes

For the past week or so, I’ve been suffering from slowness in the Finder, corrupted icons and terrible performance in our version control client (Versions).

Today, I decided to do something about it. The first step was to sample Versions while it was beachballing. The app was spending most of its time in [NSWorkspace iconForFile:]. That, along with the corrupted icons I was seeing in various apps made me suspect that there was a corrupted database somewhere. But where?

After a lot of Googling, I finally found this link. The path to lsregister has changed a bit in Mountain Lion, so this is the command I ended up using:

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -seed -r

My development machine immediately felt like it was running at normal speed (I refuse to say snappy until they update the Mac Pros.) And, of course, as soon as I figured that out, I found that someone smarter had beaten me to it.

So how did this happen? In looking at the documentation for the Launch Services database, there is a lot of information that’s collected when applications are first launched. As developers, we launch applications all fricken’ day. And we also know that pounding on a database is the best way to break it.

So, the next time you’re seeing general slowness on your Mac, don’t forget to give Launch Services a kick in the pants. Guaranteed to be more effective than zapping your PRAM.

iPhone 5 Scuff Remover

Removes unsightly scratches, dings and scuffs IN MERE SECONDS! *

Get yours NOW!

And we think you’re going to love it.

* black iPhones only