MKStoreKit started off in a pet project a couple of years ago and I wrote the first version in 2009.
Since then, it has seen tremendous adoption rates that, it has been the “go-to” framework for implementing In-App purchases in any iOS app today.

On iOS 4.3, Apple added a new type of subscription framework called, auto-renewable subscriptions.

Today, I’m adding this support to MKStoreKit along with several new features. If you have been following me on Twitter (@mugunthkumar) or on Github, you would have gotten the code a week ago.
Now that, I’m done with my testing it’s finally ready for some real-world adoption in your projects.

What’s New

  1. The main feature includes support for Auto-renewable subscriptions.
  2. The second important change is to move configuration related changes to a separate file,
    MKStoreKitConfigs.h and
    MKStoreKitConfigs.plist

    The plist contains a list of products you support and MKStoreKit automatically reads this and creates StoreKit requests on your behalf. This feature was partly inspired by a issue raised here by a contributor, dfabulich. But I didn’t like adding a datasource to MKStoreKit for various reasons. I think this method is cleaner than that. MKStoreKit now behaves like a standalone drop-in package.

  3. MKStoreKitDelegate removed in favour of Blocks
  4. Keychain support using SFHFKeychainUtils

    How to use

    The most important change to MKStoreKit is the use of a plist file instead of Macro strings for your product ids.
    The following screenshot shows the plist file organization.
    MKStoreKitConfigs.plist
    There are three main sections, Consumables, Non-consumables and Subscriptions. You specify your product inside each category based on how you added them on iTunes connect.
    After that, MKStoreKit does the rest.
    Non-consumable and Subscriptions are straight forward. I think I might need to explain a bit about Consumable support.


    Every consumable entry in this plist needs to be a dictionary with “Count” and “Name” defined. Imagine that your app is a fish tank app with eggs, plants and fishes as consumables. Fishes are going to be sold on a per-fish basis. However, you might be interested in selling eggs as discounted basket. To allow this business model, I’ve added a new entry called unique name to every consumable.

    If your products, for example,

    com.myfishapp.eggbasket50 = $2
    com.myfishapp.eggbasket500 = $15
    com.myfishapp.eggbasket5000 = $ 125

    are in fact same in your business (in this case they are all eggs, just that the count is different and subsidized for bulk purchases), you can define them on plist as individual consumable mapping to the same name.
    MKStoreKit will then treat all these products as same when remembering purchases.

    So instead of you remember how many fish eggs this person has purchased, you can leave that task to MKStoreKit. You get a nice wrapper around them and call these methods on MKStoreKit

    - (BOOL) canConsumeProduct:(NSString*) productName quantity:(int) quantity;

    to check for product availability and

    - (BOOL) consumeProduct:(NSString*) productName quantity:(int) quantity;

    to notify MKStoreKit to deduct the consumable’s balance.

    This support was originally added to MKStoreKit 3.5, but it didn’t support product bundles. MKStoreKit v4 adds support for this.

    Subscriptions expiry notification

    MKStoreKit automatically posts notifications when your auto-renewable subscriptions are renewed or failed validation (expired). Observe the following notifications,

    kSubscriptionsPurchasedNotification
    kSubscriptionsInvalidNotification

    on your view controller or AppDelegate and take corresponding actions.

    A note for MKStoreKit 3 users


    MKStoreKit 4 uses keychain to remember purchases. This is partly to support In-App purchases on the upcoming operating system, OS X Lion. On iOS, all apps are sand-boxed and outside access to NSUserDefaults is not possible (unless the device is jail-broken). So remembering purchases on NSUserDefaults was *good enough*. On Lion, however, NSUserDefaults file is just another plist that could be edited on any text editor and technically “buy” our in-app feature. To circumvent this piracy, MKStoreKit 4 will use keychain instead of NSUserDefaults.
    As such if you have any consumables, they will not be automatically migrated to keychain store by MKStoreKit. You should do that part yourself. Non-consumables and Subscriptions doesn’t have this issue.

    Source Code

    The complete source is available on Github

    Demo Project

    There isn’t a demo project available because of the nature in which In-App purchases work.
    The only way would be to create a dummy project from my iTunes store account and create IAP. But that would add maintenance nightmare for me. However, since MKStoreKit is self-contained, you shouldn’t normally have trouble integrating it into the product.

    Licensing

    It’s licensed under Zlib as I feel that’s the most open license ever.

    A word on third-party components

    MKStoreKit uses the following third-party components.

    1. JSONKit by John Engelhart (BSD or Apache Licensed)
    2. NSData base64 encoding additions by Matt Gallagher (Zlib license)
    3. SFHFKeychianUtils by Buzz Andersen

    Final words

    I’m still making some touchups and final set of changes. But I think they will mostly be *cosmetic* (code refactoring). Feel free to pull/fork MKStoreKit and leave your feedback.

    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

    Mugunth

Follow me on Twitter

  • guhthe

    Hi,

    Is there a new update to make this work for iOS7?
    Because for this version it’s always crash when I try to use it.

    • TrainerLeipzig

      Hey Mugunth,

      thanks for your great StoreKit. But it isn’t work under iOS7…
      Failed transaction: SKPaymentTransaction: 0x1655d950
      error: Error Domain=SKErrorDomain Code=0
      is the NSLog-Message. The sharedInstance find the products.

  • fbartolom

    It is not clear what section to use for non renewing subscriptions. If I enter them into the subscription section I have a weird outcome. Should I handle them as consumable or what?