MKStoreKit, as you probably know is a framework for implementing In App Purchases in your app. It supports virtually every feature you could tell and every business model you could (or even Lodsys) ever think of. It supports, Auto-renewable subscriptions, Consumables, non-renewable subscriptions, and good old non-consumables and a whole lot others.

The biggest gripe among the developer community is that there is no easy to use, step by step guide on how to use it. There are reasons why I couldn’t publish one.

Why no demo?

First and foremost, a working demonstration app implementing MKStoreKit requires an app to be setup on AppStore and this app cannot obviously be published. Conversely, I cannot open source an app that makes money for me through In App Purchases.

If you have an App on iTunes Connect without publishing it, Apple will send you a polite email after 2 or 3 months asking you to publish. Failing which, they remove it for you and will no longer allow you to create an App by the same name. Deleting the app obviously removes associated In App Purchases and the demonstration code will no longer work. It simply doesn’t make sense to play cat and mouse with Apple and create dummy apps for a demonstration software.

Design of MKStoreKit

However, MKStoreKit has been designed keeping this in mind. The whole integration shouldn’t take more than an hour or so. Implementing the MKStoreKit into your app is as simple as 10 or 15 lines of code.

Step 1: Initialization The first step is the initialize it in the AppDelegate using the code,

[MKStoreManager sharedManager];

Step 2: The Plist magic The second step is to set up your configurations in the plist file, which I think is quite obvious. There are three keys in the plist, one containing an array of non-consumables, one containing an array of consumables and another an array of auto-renewable subscriptions.

Step 3: Configuring for Non consumables Non-consumables need no extra configuration. Just enter the list of product ids in the plist file.

Step 4: Configuring for consumables For Consumables, you need to tell MKStoreKit, which product it belongs to and the quantity it adds.
For example, com.mycompany.myapp.eggbasket1 = 10 eggs, and com.mycompany.myapp.eggbasket2 = 100 eggs, you need to tell MKStoreKit that both these are the same product “Egg” and they add 10 and 100 eggs respectively.

This is precisely what the keys Count and Name stands for.


Step 5: (Auto-renewable subscriptions) For auto-renewable subscriptions, you need to tell the subscription length. MKStoreKit automatically keeps track of subscription expiry and notifies you through NSNotificationCenter if they expire. Since, Apple doesn’t keep track of subscription length, it’s your responsibility (which MKStoreKit takes care of) as a developer to remember those subscription length somewhere in your app.


Step 6: (Shared Secret) If you use auto-renewable subscriptions, you need to enter set your shared secret. You should do this in MKStoreKitConfigs.h. If you don’t do this step, MKStoreKit cannot notify you of subscription expiry. Shared Secret is used for subscription verification and it’s compulsory to set this if you use auto-renewable subscriptions.

Step 7: The real purchase
The real purchase code is a one liner.

 [[MKStoreManager sharedManager] buyFeature:<strong>@"com.mycompany.myapp.feature1"</strong> 
                                    onComplete:^(NSString* purchasedFeature)
     {
         NSLog(@"Purchased: %@", purchasedFeature);
		// provide your product to the user here.
		// if it's a subscription, allow user to use now.
		// remembering this purchase is taken care of by MKStoreKit.
     }
                                   onCancelled:^
     {
         // User cancels the transaction, you can log this using any analytics software like Flurry.
     }];

Everything happens behind the scenes, automatically. For every kind of product, whether it’s a consumable or non-consumable, this code is same.

Step 8: Expiry notifications for auto-renewable subscriptions Subscribing to subscriptions revoked notifications (only for auto-renewable subscriptions).

	[[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector (subscriptionExpired:) 
name: kSubscriptionsInvalidNotification 
object:nil];

It’s the configuration part that’s hard. So, as I promised that was under 10 lines right? One line in your AppDelegate, 4 or 5 lines in your Store ViewController and 2 lines to listen for subscription expiry notification. That wasn’t hard, was it?

Going forward

Lion

MKStoreKit will soon be released with full support for Lion
Currently, I think it should automatically work, though I haven’t tested it. If you are using it, do let me know.

iCloud


Adding iCloud integration. With iCloud, your purchases will be remembered on iCloud rather than Keychain, which means, you don’t need to restore transactions on every device. iCloud will do it for you automatically.

The code for this is ready, but the NDA prevents me to push it to Github. Wait till Sep 5th (hopefully)

If you have any other feature requests, or want me to look at your changes, do send me a pull request for the code on Github
http://github.com/mugunthkumar/MKStoreKit

Hope MKStoreKit helps you and your business. Do consider a paypal donation to mugunth.kumar@gmail.com.

Thanks,

Mugunth

Follow me on Twitter

  • Doron Katz

    Awesome just twitted to ask you but got this here. Just the part that I’m stuck on is the plist. I know you say its obvious but for some reason, when i put the full namespace (which is bundleID plus the appID) i get an issue with iTunes saying it can’t find it but when i just put the featureID in plist it seems to accept it at least from an NSLOG perspective. Am i doing it right? 

  • Celeretaudax

    I get all this. But since my app was in review, my in-app subscriptions now say “Waiting For Review” and for some odd reason, [[MKStoreManager sharedManager] purchasableObjectsDescription] returns nothing. I check before for [[MKStoreManager sharedManager] isProductsAvailable] and it returns “YES”. So it’s not an issue there. It seems to be failing at this line:

    NSMutableArray *productDescriptions = [[NSMutableArray alloc] initWithCapacity:[self.purchasableObjects count]];productDescriptions returns nothing. However, at one time this configuration was working. So could it be with the “Waiting For Review” status of the In-App subscription?

    • http://twitter.com/jamiebullock Jamie Bullock

      This is a 2 year old post, but I’m answering here in case it’s useful to anyone else. Basically you need to listen for the kProductFetchedNotification via Notification Centre, and only access [[MKStoreManager sharedManager] purchasableObjects] etc after this notification has been received.

  • http://twitter.com/Soulghai Gadzhiev Zakhar

    Purchasing function does not work on my iPod first gen. 
    The program catches EXC_BAD_ACCESS in function buyFeature. On line self.onTransactionCompleted = completionBlock; 

    On the iPhone 4G everything works well. 

    Any ideas =)?

  • prospectus

    I added all the files to my project, and then tried to add [MKStoreManager sharedManager]; in my app delegate, and when I build it says “error: ‘MKStoreManager’ undeclared (first use in this function)”.  Am I missing something?

  • akr

    Doesnt compile on lion. Pls keep me posted if available.

  • Myhandisalwaysnice

    What is the reason having verifyProductForReviewAccess dialog inside buyFeature?

  • http://pulse.yahoo.com/_ZQL7U6T2SLDL5O5QHDKXGF323U Brad

    1. Any idea why the following line keeps returning true, even after I uninstalled the app and used a different test user?:

    if([MKStoreManager isFeaturePurchased:@"com.myapp.myfeature"])

    2. How does one differentiate between user cancelled in-app purchases and failures?

    Thanks in advance for your help.

    • Ebarnes

       I had the same problem for your first question. You forgot to add the iap in the MKStoreKitConfigs.plist

      • Kolenc Gasper

        I am having the same problem as Brad for his first question. The IAP is included in MKStoreKitConfigs.plist, so what could be the problem?

        • http://www.facebook.com/fahri.azimov Fahri Azimov

          He is storing the IAP id in keychain.

  • Michael Trimm

    How do you track the count of consumable products using this framework and how do you start the count at a given value instead of 0?

  • nobreak

    Hi, i’m using your library – very nive. Now I want to user auto-renewable subscription for a month, 2 month and one year feature. But how many day’s have a month or a year ?

    1 month have 30 or 31 days ?
    1 year have 365 or 366 days ?

    For this cases what I have to setup in plist file of MKStoreKit ?

  • Raseljka

    Hi!

    First of all, great work! Congratulations! I was wondering how to turn off auto-renewable subscription for test user? Can it be done?!

    Thanks!

  • Nicholas Barrowclough

    I’m using your latest code but I get an automatic reference counting ARC error when I compile. It says “No known class method for selector ‘Shared manager’”

    Any ideas?

    • Caseroman

      I have the same problem! Did you find the answer?? Thanks

  • Zaakk

    Hello!!

    Thanx for this great work, but can you write full manual how can I implement auto renewable subscription in my app, cause all information not in one place and I have any troubles with it :(

    Many thanx!

  • Ashot Tonoyan

    Why is this wonderful library so horribly documented?

    • Ashot Tonoyan

      Where can I get a documentation on NON-renewable subscriptions?

      • Paul Jacobs

        Seriously, PLEASE provide some documentation for non-autorenewing subs which most of us end up being forced to use.

  • Paulmatos

    Hi, quick question is there any kind of timeout feature with the ‘buyfeature’ method. Right now if an incorrect feature id is passed in, or if the itunes store is down, the seems to just hang.

  • KoD@K

    Could you explain how to use this?

    I copied this line of code and pasted into my IBAction, changed Product ID of in-app to mine. How show dialog “Confirm your in-app purchase”?

  • Antonio

    Hi Mugunth,

    I’m trying to implement a multi-platform app with in-app purchases. I’m using MKStoreKit and non-consumable content. I would use user registration in the server side. The app could be used without registering any user, so it would be possible to download content without being registered.The problem comes because I’m not handling the purchases, but Apple (using Apple ID).If I buy one content with userA, then log in as userB and try to buy the same content, an alert pops up saying something like “You’ve already purchased this In App Purchase but it hasn’t been downloaded.”, how can I handle this?
    If I purchase some content without being registered and then register a user, how can I sent my purchases and bind them with this user only?
    If I buy some content with userA and then change my Apple ID, I won’t own that content anymore according to my Apple ID, how can I handle this kind of situations?It seems a little messy to deal with Apple IDs, registered and non-registered users… It would be easier to buy consumable coins, but I’m afraid of Apple’s rejection.I’m really struggled with this…Thanks for any help.

  • Loganathan

    Hi,
           I am using mkstorekit 4 in my app for In-App features. It seems good in
    kinds of consumable, non-consumable and auto renewable subscription. But
    today i tried to implement non-renewing subscription with mkstorekit 4.
    But am not able to do that. Here any one knows how to implement
    non-renewing subscription and how to configure the product id’s in
    mkstorekit 4 plist, Then please tell me.

    Thanks,
    loganathan

  • http://twitter.com/tabletjournal Marc N Watson

    I was using MKStoreKit 4 for well over 2 years and had no issues. Am updating my main app, but I could not refactor to ARC due to MKStoreKit4. Now have discovered Facebook is requiring it as well, so… I took the plunge. You state in your ReadMe… “Dont’ expect it to work out of the box if you are updating from a previous version. Refactoring should however be a simple 5 minute work.” NOT!! All of the purchasable items used to be integers. Now they are strings. This change is made more difficult due to the lack of documentation or examples. I’ve now spent almost an entire day… just changing items for refactoring. Have you created any other documentation or examples for how to implement this code?

  • http://www.facebook.com/satya.svv Satyam Satyanarayana

    Hi Mugnuth, I tried your latest inapp purchase library. Its really good. I’m hosing the content on Apple server for non-consumable purchase item. But when the download happens, it stops at 75%. I tried with different content hosted on apple server, but still i am not getting complete download. Is there any specific reason? Any suggestions to debug?

    • http://www.facebook.com/travis.weerts Travis Weerts

      I am having the same issue, did you ever figure this out?

  • fbartolom

    Not clear where in the code is to be installed the callback for executing actions on the server once a purchase has been completed.