Store Kit and testing In-App Purchases for Mac App Store

October 23, 2013 — 2 Comments

Lately I’ve been working on my next project CodeGofer and it involved learning new things in OS X land. Two things I postponed for as long as I could were full text search and In-App purchases. Being prone to NIH syndrome I tried to come up with home made framework for the former but though better of it and did my online research, which yielded a Search Kit, really neat and simple way to do full text search for Cocoa apps. And the latter led to brief but intense struggle with Store Kit. Search Kit will get its own blog post but at the moment I’d like to document my experience with Store Kit and testing in-app purchases. There are quite a few tutorials about iOS in-app purchases but information about how to do it on Mac OS X is somewhat scarce. So here is my woes as of today:

Debug configuration wouldn’t do it

The first show stopper was inability to get products from sandbox environment. I did all by the book but this code

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
    if ([response.invalidProductIdentifiers count] > 0)
        NSLog(@"Invalid product ids: %@", response.invalidProductIdentifiers);

    NSLog(@"Products: %@", response.products);
}

showed that all product ids I had submitted were invalid. I checked and double checked but no luck. Then I switched configuration for “Run” action (Alt+Click on “Run” button and modify “Run” action’s config) to “Release” and voila: response.products were no longer empty. I am not sure why Debug configuration does’t work, I’ll update post once this mystery is solved. And the strange thing: without Xcode Debug configuration works (see below)

Alas attempt to purchase item always ended up with Current receipt invalid or mismatched ds person id. message.

Would you like your receipt?

Some googling turned up the reason for that message: Store Kit checks receipt for IAP against Mac App Store receipt and since we run application from Xcode there is nothing of this kind. I believe that receipts are generated in two cases: when app is purchased from MAS or when app requests it from system notifying it by very specific exit status: 173. I failed to find the way to emulate MAS purchase but exit status turned out to be more fruitful. First of all for testing purposes we do not need full blown receipt checking code. We just need to know if it’s there. I added these lines to the very beginning of applicationDidFinishLaunching method of App Delegate:

    NSURL *url = [[NSBundle mainBundle] appStoreReceiptURL];
    
    if (![[NSFileManager defaultManager] fileExistsAtPath:[url path]])
        exit(173);

When you run application from Xcode its exit status is handled by IDE and what it does is it does nothing. So there are two options:

Do not use Xcode
Build you project using xcodebuild and run application using open. Something like:

xcodebuild -target CodeGofer -config Release && open ./build/Release/CodeGofer.app 

In this case exit code will be passed to the system and handled accordingly.

Generate receipt for Xcode build on demand
Try to run application and see it fail. Now find the bundle in ~/Library/Developer/Xcode/DerivedData (in my case it’s /Users/gonzo/Library/Developer/Xcode/DerivedData/CodeGofer-gobendvulmorviaazseuzbheeoht/Build/Products/Release/CodeGofer.app), run it once using open, e.g.:

open /Users/gonzo/Library/Developer/Xcode/DerivedData/CodeGofer-gobendvulmorviaazseuzbheeoht/Build/Products/Release/CodeGofer.app

It will generate receipt and it will be successfully picked up by application run from Xcode. Until you perform clean of course. At which point you’ll need to generate new receipt.

With all this bells and whistles I finally got my IAP working in sandboxed environment so now I can happily code further.

Oleksandr Tymoshenko

Posts

2 responses to Store Kit and testing In-App Purchases for Mac App Store

  1. this saved me hours after some hours of searching. In my case, when testing in debug mode I was receiving the products but instead any purchase request ended up with an Unknown Code 0 Error in UpdatedTransactions

Leave a Reply

*

Text formatting is available via select HTML. <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>