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
Focus
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
http://api.mycompany.com/inapp/
change the “ownServer” variable in MKStoreManager.m to
http://api.mycompany.com/inapp/featureCheck.php
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
If you cannot successfully use this, you can hire me to do it for you.
I usually freelance through oDesk.com
Related posts:
- iPhone Tutorial – In-App Purchases Last week, Apple announced that in-app purchases will be available...
- iPhone Tutorial – UISearchDisplayController with NSPredicate Though UISearchDisplayController is seemingly easy (and yes it’s easy), apart...
- iPhone Tutorial: Follow Cost API and a open source wrapper What is Follow Cost? Follow Cost is a interesting and...
- iPhone Tutorial: Elegant way to send formatted In-App email By now, most of you know how to send emails...
- bit.ly wrapper for Objective-C/iPhone Continuing from my part 1, in this section, we will...
53 Responses to “iPhone Tutorial – Enabling reviewers to use your In-App purchases for free”
Trackbacks/Pingbacks
- iPhone Tutorial – In-App Purchases | blog.mugunthkumar.com - [...] posts:iPhone Tutorial – Enabling reviewers to use your In-App purchases for free In-App purchases is a great way for ...
- iphone 3.0 changes | IPHONE - [...] iPhone Tutorial – Enabling reviewers to use your In-App purchases … [...]
- In-App Purchasing at Under The Bridge - [...] Enabling reviewers to use your in-App purchases for free [...]
- Store Kit In-App Purchase Tutorials | iPhone and iPad Development Tutorials and Programming Tips - [...] Included in the Under The Bridge list are a couple of step-by-step tutorials from Mugunth Kumar: In App Purchasing ...


Very nice Tutorial. Thanks for this kind of tutorial I really find it interesting.
We wrote our own "promo code" system for our App – as of right now the user my paste the promo code in a field to unlock – but for version 1.1 we are going to leverage the URL Schema for our app so the user has to click a link and the feature is unlocked.
It works for us since our App is heavily server based – the promo codes are one use and it has worked well so far.
Hi!
I'm using MKStoreKit v2 and it worked perfect from the beginning. The only thing is after completing a succesful purchase if I call [MKStoreManager featureXPurchased] I get the right response (YES) but if I close the app and launch it again, calling to the same method gives me a NO.
Is it because I'm using a test account? Should I do something different?
Thanks!
It should return YES. Can you elaborate more..?
Ok
I implemented a method, let's say featureXPurchased. I complete the purchase of feature X and calling
[MKStoreManager featureXPurchased] = YES
That's right cause I already purchased feature X.
If I restart the app and call again [MKStoreManager featureXPurchased] the answer is NO and it's wrong cause I already purchased feature X.
Should I initialize MKStoreManager in some way when the app loads so that i get the right response?
yes.
You should initialize storemanager in your applicationdidfinishlaunch
The class is singleton. So there is no init method. Just calle [MKStoreManager sharedManager] after your app starts. That should do it.
Worked like a charm!
Thank you very much and congrats for your great work.
Hi!
There's this delegate method to know when a transaction has finished with a purchase
- (void)productPurchased:(NSString *)productId;
Is there any delegate I can implement to know when the transaction has failed or user has cancelled it?
Thanks!
Hmm… As of now, no.
But you can add it if you want into the MKStoreKitDelegate.
Ok, I'll try to add it myself.
It would be a nice update anyway.
Thanks again.
Did anyone managed to implement the failed or cancelled transaction?
My ipod 1G is my most valuable iPod, Pda and far more, also has has been ever since I bought it. It continues to work on the newest iPod system software program, and also any iphone app I need to have it to operate. I’m working with it to leave this comment at the moment. It’s safe to point out it’s a lot more than simply just an “excellent hobbyist system” — it can be an fantastic iPod
While Apple iPhone 3.1.3 firmware was minor terms of new features, it’s had the side effect of opening up a huge market for scam sites. These sites will promise you a 3.1.3 jailbreak for newer devices like the iPod touch 3G, or a baseband 05.12 software unlock. Do not fall in this scams , you can jailbreak iPhone 3G 3GS firmware 3.1.3 with Sn0wbraze V1.5 for free
Thank you for this tutorial. I have a question about the MKstoreKitDelegate protocol. My productPurchased method never gets called and I may not be setting things up right. Please excuse my naivete.
I implement the productPurchased: method in the MKStoreManager class. I set the .h file interface line like so
@interface MKStoreManager:NSObject
I then assign
_delegate = self;
in the sharedManager method.
But in the provideContent method, the respondsToSelector call always fails. Any ideas what I am doing wrong?
The interface line above dropped the angle bracket MKStoreKitDelegate close angle bracket
Ok figured out that I had to call
[MKStoreManager setDelegate:[MKstoreManager sharedManager]];
Thanks
Ok figured out that I had to call
[MKStoreManager setDelegate:[MKstoreManager sharedManager]];
Thanks
what about enabling the restore function that apple recommends to do? anyone done that yet?
Hi, Thanks for your excellent articles. Maybe I did not see your comment , but please tell me if Apple approved this method of free in-app purchase.Thanks.
Yes apple approves this. They specifically called me regarding this and gave a go ahead!
Sent from my iPhone
Hello
.
I am really new with this language at all but after your tutorials i feel good to start with IAP
Thanks. If you need some help with the PHP-Part of your app, hit me with a mail.
Jailbreak & Unlock Software For Iphone 3g 3.0 Os quik2unlockbycode Store UNLOCK AND JAILBREAK SOFTWARE FOR IPHONE 3G FIRMWARE VERSION 3.0 OS IPHONE 3GS NOT SUPPORTED STEP BY STEP EASY JAILBREAK UNLOCK INSTRUCTIONS FOR YOUR IPHONE 3.G with new FIRMWARE VERSION 3.0 OS UNLOCK YOUR IPHONE 3G OS FROM ….