Update: MKStoreKit 3.0, an updated version of the one presented here is available. Please check it out and use 3.0 instead of this.

In-App purchases is a great way for developers to upsell by giving away their app for free and then allow them to charge for features when users start using it. This freemium model has indeed worked very well for upselling your app in the AppStore. But unfortunately, there isn’t an Apple allowed way to allow reviewers to “download” your in-app purchases for free (like giving away promotional codes for your in-app purchases). So most developers again resort to the same “lite”, “pro” model.

After raising the issue to Apple, I even got a official reply that it’s not possible currently to allow reviewers to use your in-app purchases for free.


However, developers’ creativity knows no bounds. In this post, I’ll present a method to allow reviewers to use your in-app purchases for free without having multiple versions of the same app on the app store. The source code for the same is also available royalty-free (as always) for using it in your own apps. Before diving in, it’s advised that you read through my previous tutorial on how to do in-app purchases


As I previously wrote, you can sell consumables, non-consumables and subscriptions using the in-app purchases model. This article is focussed primarily on consumables and non-consumables. However, you can extend it to subscriptions as well by adding a bit more server side PHP programming. This post however focusses on adding this feature to consumable and non-consumable items only.

A Quick Recap

By now, you must be knowing the flow of a in-app purchase request. If you don’t, read through my in-app purchases tutorial. As a recap,

1) You list the items available for sale from your store to the user.

2) When the user chooses a feature, you prepare a SKPayment object and add it to the queue.

3) Listen to notifications and record the purchases within your apps’ NSUserDefaults.

Or it’s even more simple if you had used my MKStoreKit.

The Idea

The idea here is to maintain a list of device IDs on the developer server and check whether the current device is exempted to use the feature without purchasing. If the device is allowed, rather than initiating a purchase, temporarily set the variables as if the transactions were made.

The complete source code, MKStoreKit V2.0 is attached at the end of the post.

You should be glad to know that, you don’t have to make changes to your calling code to add this feature.
In MKStoreKit, there is a function called buyFeature which initiates a in-app purchase request. In version 2.0, this function is modified to make a check first to your server (server code is also attached to this post) passing the UDID of the current device. If your server responds with a YES, it activates the feature temporarily without “actually purchasing”. This will enable your reviewers to review your app without buying your in-app purchase.

– (BOOL) canCurrentDeviceUseFeature: (NSString*) featureID;

This is the function that is called. Currently it checks the server mentioned in the variable ownServer (presently set to nil). To enable this function, you have to do the server side changes as explained in the next step.

Server Side Changes

Setup a database with two tables setup in your server. One table for storing a list of available products and another for storing new review requests as they come in.

The products table has the following fields
productid productName productDesc

The requests table has the following fields
udid productid email message status lastUpdated

You can use the SQL file attached to create these tables. Add a user to your MySql database and fill in the user id and password into the two php files.

Copy the server files from the ServerCode folder to some location like

change the “ownServer” variable in MKStoreManager.m to

The featureCheck.php file checks the requests table for the UDID and the featureID. If the status of that row is 1, it returns YES. If your server returns YES for a particular UDID, the app activates the purchase for the current session without initiating a StoreKit purchase. Note that, this featureCheck happens everytime the app is started. Hence, if you deactivate a UDID on your server after the reviewer has finished reviewing, he will not be able to continue using it for free (Which means, you have actually given the reviewer a sneak-peek to your feature. Even if he likes it, he has to buy it)

How to send your review request?

There are atleast three ways of doing this.
One way is to ask your reviewers to send the UDID to you by email. You can ask them to use the Ad Hoc Helper by Erica Sadun You can then manually add it into the database using the AddDevice.html (present in the Server Code folder)
Second way is, You can “pretty up” the AddDevice.html and host it somewhere in your server. Send a link to this to your reviewers for filling their UDID/Product ID.
Third, as in my case, I’ve created a separate iPhone App for doing this. The only reason for doing so is, filling the UDID is very very cumbersome and error prone. If anyone knows a way to read the UDID of a device from a webapp, do let me know. (The big5 code didn’t work for me)

Going forward

I understand that all this server side setup is quite cumbersome. The server code isn’t even polished like the MKStoreKit. If Apple approves this method (which I will know in another 20 days), In MKStoreKit 3.0, I’ll probably throw of the whole server side code and replace it with a much elegant method by using a Google Spreadsheet. I haven’t yet digged around with the spreadsheets API. This way, you can implement the same feature without even owning a server :).

I might as well add in features to migrate your existing customers who use your pro version to the version with in-app purchases. Stay tuned!

Source Code (Much awaited)

MKStoreKit V2.0 Please use version 3 of this code instead. You can get it from the blog post below.
If you cannot successfully use this, you can hire me to do it for you. :)

Update 4: (8th July 2011) MKStoreKit 4.0, an updated version of the one presented here is available. Please check it out and use 4.0 instead of this.

Support me

Hourly rates of a iPhone developer is skyrocket high. I believe this code would have saved your coding hours by at least a day. You can consider supporting further development by funding me through PayPal.  My PayPal email is mugunth.kumar@gmail.com

Follow me on Twitter