Quick Explanation of the Receipt File

I was explaining the MAS receipt file to a friend and decided to write a blog post instead of an email, on the principle Scott Hanselman has brilliantly advocated that we should conserve and amplify the limited number of keystrokes we have left in us.

I'm purely a Mac developer at the moment, but as far as I know this high-level explanation applies to iOS as well. No idea about watchOS.

WHAT IS THE RECEIPT?

The receipt is a file on your computer used for DRM of purchases from the App Store. There is a separate receipt for each app.

The receipt file contains:

  • Identifying information about the computer on which the app is installed — specifically, the MAC address of the device's primary network interface. Note that "MAC address", with the "MAC" in all caps, is a networking term. Nothing to do with "Mac" as in "Macintosh".

  • Identifying information about the app that the receipt is for — specifically, the app's bundle ID and version number.

  • Purchase history. Information about the app purchase and any subsequent in-app purchases.

WHERE DOES THE RECEIPT LIVE?

The receipt file is located inside the application bundle. On the Mac, it is at Contents/_MASReceipt/receipt. (If you don't know what the application bundle is, I've written another quickie blog post explaining it.)

WHO IS RESPONSIBLE FOR DRM?

The system is responsible for creating the receipt. By "system" I mean the OS in conjunction with the App Store. The system code-signs the receipt to prevent tampering. It's the job of Apple's developers to have gotten this right.

The application is responsible for validating the receipt. It's the job of the app developers to get this right.

WHEN DOES THE RECEIPT GET WRITTEN?

The receipt gets created on your computer when you download the app from the App Store. The receipt is then updated in the following situations:

  • If a newer version of the app becomes available on the App Store, the receipt is updated when you upgrade to the newer version.

  • If the app supports in-app purchases, the receipt is updated whenever you do an in-app purchase.

  • When you "Restore Purchases", the receipt is updated.

Here's what I mean by "Restore Purchases". Certain types of in-app purchases apply to all computers on which you have installed the app, not just the computer on which you made the purchase. A typical example would be an IAP that unlocks premium features. If you made such a purchase on a different computer, you may need to explicitly "restore" that purchase on the computer you are using. Apple's App Store rules require the app to provide a way for you to do this. Usually the app provides a button or menu item with a name like "Restore Purchases".

HOW DOES THE APPLICATION USE THE RECEIPT?

The application does two things with the receipt:

  • It validates the file contents to confirm the receipt hasn't been tampered with.

  • It checks in-app purchases to see what enhanced functionality the user has purchased. In-app purchases may include permanent "unlocking" of features, or they may be subscription-based, in which case the app should check the expiration dates of the subscriptions.

Both of these steps are performed by parsing the receipt file, which is a science in itself. There's an excellent article on objc.io that explains what is required:

You may wonder why Apple hasn’t provided a simple API to validate the receipt. For the sake of demonstration, imagine that such a method exists (for example, [[NSBundle mainBundle] validateReceipt]). An attacker would simply look for this selector inside the binary and patch the code to skip the call. Since every developer would use the same validation method, hacking would be too easy.

Instead, Apple made the choice to use standard cryptography and encoding techniques, and to provide some help — in the form of documentation and WWDC sessions — for implementing your own receipt validation code. However, this is not an easy process, and it requires a good understanding of cryptography and of a variety of secure coding techniques.

Of course, there are several off-the-shelf implementations available (for example, on GitHub), but they are often just reference implementations and suffer from the same problem outlined above if everybody uses them: it becomes very easy for attackers to crack the validation code. So it’s important to develop a solution that is unique and secure enough to resist common attacks.

MORE LINKS

Some Ways I Use Keyboard Maestro

Today, thanks to Michael Tsai, I found out there's a major new release of Keyboard Maestro. I use Keyboard Maestro all day long, and look forward to checking out the upgrade when I have time.

Here are some ways Keyboard Maestro makes my day go much more smoothly:

  • I use the palette feature to navigate to frequently used apps and documents in exactly two keystrokes.

  • I have a "Preferred Window Frame" macro that sets the active window's size and position. My preferred frame varies from app to app, and the macro does the right thing depending on which app is active. Just one keystroke to remember. The macro invokes keyboard shortcuts I've configured in Divvy, but I could also have entered window coordinates directly into Keyboard Maestro.

  • I map ^P/^N to UpArrow/DownArrow so I can use those emacs keys to go up and down in lists, menus, and other places outside of text editing. The ^P/^N keys already work in many apps, but not all, and not in all places within the same app. By setting up this global mapping, I don't have to remember where they work and where they don't.

  • You can create text expansion macros. I have macros for inserting date and time, for a few phrases I type on a regular basis, and for emoji characters. I was happy using Keyboard Maestro for all this but recently moved my text expansion macros to aText, a very nice app at a very reasonable price. My reasons for switching were minor and arguably not worth the time when I had a perfectly good solution. I wouldn't and perhaps shouldn't have bothered, except I am such an obsessive yak shaver.

  • I sometimes use Keyboard Maestro instead of System Preferences to provide alternate menu shortcuts. I do this because Keyboard Maestro syncs my macro definitions on Dropbox, which means that when I make a change, all my Macs automatically get it.

  • I open Xcode's Recent Files menu with one keystroke (I use ^R) instead of three (^1, DownArrow, RightArrow).

  • I have a scratch macro named "Pipe Text" that replaces the currently selected text by piping it through a shell script and pasting the result. The macro has an "Execute Shell Script" action that I edit to do what I have in mind, typically a grep.

  • I keep a personal log in the form of daily text files. I have a macro that opens today's log file in BBEdit, after creating the file if necessary. I use this throughout the day whenever I think of something to add to the file.

I'm happy to share how I do any of the above.

I'm Fine With the Accents on "Fresh Off the Boat"

Yesterday I watched the first two episodes of Fresh Off the Boat, a sitcom loosely based on the childhood of Eddie Huang. It's the first network show in 20 years starring an Asian-American family. The previous one, Margaret Cho's All-American Girl, didn't do too well, so anticipation and expectations were high for Fresh Off the Boat.

Last year when the first teasers came out for the show, viewers' reactions included some concern about the accents of the parents, played by Constance Wu and Randall Park. To me, the accents did indeed sound off-key, but based on everything else I saw, I reserved judgment. I figured maybe I wasn't familiar enough with Taiwanese accents, since I'm more used to the Hong Kong accents in my own family.

Mainly I wanted to take the attitude that I take with Apple product announcements. Whatever optimism or doubts I may have, I always reserve final judgment until I've had hands-on experience. I learned my lesson about that in 2007, when Apple shipped the first iPhone. I was excited about it but thought I could hold off on getting one. I figured I'd wait for other people to find the bugs and for Apple to work out any manufacturing glitches. But then a friend let me play with his iPhone, and I was immediately hooked. The hands-on experience far exceeded my expectations. Minutes later, my friend walked me to the Apple Store and I bought my own iPhone.

This week ABC "shipped" the first two episodes of Fresh Off the Boat and I finally got to go "hands-on". And you know what? I loved the show so much I watched both episodes twice. The show is honest about race — there's a scene in the pilot episode that I think people will be talking about for a long time — but at heart it's a funny show with some poignant moments and some moments of dark humor (though not too dark; remember, this is ABC, not HBO). The narration by the real Eddie Huang adds great depth to the flavor of the show.

I found that the more I watched, the less I cared about the accents. They might be pitch-perfect, or they might be as questionable as James Doohan's impression of a Scot. I'm still not sure, but I don't care any more because I like the characters, and I like them just as they are. I doubt most of non-Asian America will care either.

Put it this way: I find Jackie Chan's genuine accent way more distracting than I ever found Wu's and Park's simulated ones, and I still love Jackie Chan movies.

On Tim Cook being "the first"

Alanna Petroff, writing for CNN.com:

It's a landmark moment for both the gay community and the business world. Tim Cook is now the first and only openly gay chief executive in the Fortune 500.

Of course, many lesbian, gay, bisexual and transgendered employees still struggle with discrimination at work. The executive suite also remains extremely closeted, but there are a few high-ranking openly gay businesspeople.

Not to detract from their accomplishments or their struggles, but none of these examples come close to Tim Cook in terms of power or visibility. It's like pointing out the US had prominent black politicians before Obama; not to take away from any of them, but there is a clear difference. Cook is the first openly gay CEO of a Fortune 500 company, and it's a company with a track record the other 499 would kill to have.

I remember when "Apple is so gay" was a common juvenile taunt. For all I know, it still is. Regardless, times have changed, and we should all be comfortable responding to that taunt with "You say that like it's a bad thing."

Double Hotkeys with Keyboard Maestro

When it comes to hotkeys, there are too few key combinations I'm comfortable with, and my memory is too weak, for me to assign a unique hotkey to each of the things I want to do quickly. Spotlight is great, but it almost always takes more than two keystrokes, often several, for me to get to what I want.

What I want is to jump to things with exactly two keystrokes. Specifically, I want one hotkey to display a menu and the second hotkey to select from that menu — basically, something as easy as old-fashioned text-based menus.

Here's how to set up exactly that in Keyboard Maestro, which is an amazingly terrific utility.

First, create a group with the "Shows a palette for one action when:" option, and specify a hotkey as the "when". Here's one group I created, named "Jump to Application", with the hotkey Control-J:

Jump to Application

Second, add some macros for things you want to do quickly. For these second-level hotkeys, I almost always use plain letters with no modifier keys, because they're easy to type, they're easy to remember, and they won't conflict with any top-level hotkeys. Note that they also won't conflict with any other macros you define in Keyboard Maestro, even if they use the same letter. Here are the ones I defined; I went a little crazy with the names of the macros, for reasons you'll see in a moment:

Jump to Application  Macros

And that's all there is to it — you're done!

Here's what I see when I hit Control-J:

Jump to Application  palette

I put the shortcut keys in the names of the macros and used tab characters to make them line up. [UPDATE 2015-08-04: Keyboard Maestro 7 displays the macro shortcuts in the palette, so I've removed them from my own labels.] This way, I can look at the menu (or as Keyboard Maestro calls it, the palette) to remind myself when I forget. But mostly I don't look. I just hit Control-J,J to jump to BBEdit, and so forth.

A huge advantage of this approach is that only the first hotkey (in this case, Control-J) has to avoid conflicts with other shortcuts, or for that matter with plain text entry. Instead of trying to find twelve available and memorable key combinations, I only need to find one and pop up a menu with twelve items.

I've been calling this approach "double hotkeys". If there's another name that people use, I'd love to know. I'm also curious what other apps use double hotkeys, and what other ways there are to achieve the same thing. I loved how Accessorizer uses double hotkeys, and have since noticed it as an option in Divvy, which is a very clever app, though I haven't made a habit of using it yet.

[UPDATE 2015-08-04: In case you'd like to try this, I've exported the macro group that I use for the above. You can download it here if you'd like to use it as a starting point. After downloading and unzipping the file, you can either double-click it, drag it to the Keyboard Maestro Dock icon, or use the File > Import Macros… menu option.]