Powered by Squarespace
Development Blog Archive
CIRCUS BLAST

Test your aiming skills! 

Circus Blast -- 3D Puzzle Shooter. You're a monkey. In a circus. Trying to help the other animals escape, with a cannon!

 

 App. is no longer available. 

SUMO TAP

Enter the dohyou to challenge yourself to a fast pace game of Sumo Tap! Play online with friends, using Bluetooth and post your high scores to Twitter.

 

 App is no longer available.

« Ruby on Rails For iPhone | Main | iPhone Facebook Integration on Rails »
Saturday
Mar062010

Adding In-App Store to Cocos2D

There's been a few good tutorials about setting up items for purchase on In-App Stores (http://blog.mugunthkumar.com/coding/iphone-tutorial-–-in-app-purchases/ and http://troybrant.net/blog/2010/01/in-app-purchases-a-full-walkthrough/ were helpful) but there were some missing pieces about how to create a singleton to manage the store and how to display the results. The design pattern we use follows some of the singleton conventions in Cocos2D, and we've used it to create an in-app store to allow users to purchase level upgrades and multiple character upgrades and display the store using either UIKit or Cocos2D.

As a first step, you need to enable your products for sale with In-App Purchasing, including creating a unique App ID and provisioning profile. Then you'll need to create your products.

To manage the display and purchase of the in-app purchases, we created the following singleton class using the Cocos2D design pattern:

InAppPurchaseManager.h

http://pastie.org/886863

 

InAppPurchaseManager.m

http://pastie.org/886892

The usage of this singleton is pretty simple. First, before calling your product display view/scene initialize the store with this call:

[[InAppPurchaseManager sharedInAppManager] loadStore];

This will asynchronously load the store data for later display. We use plists to store the in-app store products names and titles, and then use this information to display a simple summary via a UITableView. The tricky part is knowing when the product data has loaded. We could have used an NSNotificationCenter callback but instead decided to have a simple function to poll whether the store loaded. We poll this function with an NSTimer, repeating every 5 seconds:

if ([[InAppPurchaseManager sharedInAppManager] storeLoaded])
{
// Update the UI to show that the store has loaded, ie. the user can make a purchase
}

After the user selects an item they'd like to buy, we display a more detailed view/scene that loads descriptions from the in-app store and stores them in SKProduct records. We do this with calls to product specific methods within the singleton:

SKProuct *prod = [[InAppPurchaseManager sharedInAppManager] getLevelUpgradeProduct];

We've written methods for each of our products and then keep track of the product index (ie., the displayed list of products) using a plist so we can change the display order if we'd like to promote one product higher than another for example. Once the user is satisfied with the details of the product and decides to make a purchase, we call the

And during initialization of our scene/view, we register for NSNotificationCenter callbacks for the purchase success or failure:

 

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(purchaseSuccess:) name:kInAppPurchaseManagerTransactionSucceededNotification object: nil];

 

Where the purchaseSuccess: method displays a simple thank you message. Last but not least, we need to provide a way for the user to restore previous purchases if they upgrade devices, etc. We needed to support this because our products are consumable. This simply means you need to eventually place a button in your in-app store scene/view which makes a call to this method:

 

[[InAppPurchaseManager sharedInAppManager] restoreCompletedTransactions];

 

With that, you're up & running. Good selling!

--yarri

References (12)

References allow you to track sources for this article, as well as articles that were written in response to this article.
  • Response
    Response: return
    play-N-give : Play, Give, Share - Blog - Adding In-App Store to Cocos2D
  • Response
    play-N-give : Play, Give, Share - Blog - Adding In-App Store to Cocos2D
  • Response
    Response: see this here
    play-N-give : Play, Give, Share - Blog - Adding In-App Store to Cocos2D
  • Response
    Response: вконтакті
    вкантакте
  • Response
    play-N-give : Play, Give, Share - Blog - Adding In-App Store to Cocos2D
  • Response
    Response: find this
    play-N-give : Play, Give, Share - Blog - Adding In-App Store to Cocos2D
  • Response
    Response: find this
    play-N-give : Play, Give, Share - Blog - Adding In-App Store to Cocos2D
  • Response
    So many people are using your web site services. Your blog is providing the best superior writing service and online book services. So many people are searching for your blog services very helpful our educational future. Good share.
  • Response
    Response: Walk In Tubs
    play-N-give : Play, Give, Share - Blog - Adding In-App Store to
  • Response
  • Response
    Brownstone Law
  • Response

Reader Comments (12)

Great thanks!

This is a bookmark :)

October 2, 2010 | Unregistered CommenterMike

Great post, and source code. Thank you!

I added the singleton to my project, and it all seems to work well, but it attempts to purchase the product twice, as if finishTransaction isn't being called. You say in the post that you add an observer called purchaseSuccess. Is this method supposed to call your completeTransaction function so that finishTransaction is called? If so, how do you get the transaction details?

Cheers,
Andrew.

November 11, 2010 | Unregistered CommenterAndrew

I'd actually love to review these boxes on my shopping/lifestyle blog. i wonder if they'd send me a sample box to talk about? nzolta nzolta - Moncler Daunenjacke.

November 21, 2011 | Unregistered Commenterpzxxyz pzxxyz

I Really enjoyed your blog. I just bookmarked it. I am a regular visitor of your website I will share It with my friends .Thanks.......

Thanks for this post. It's proving to be very useful. Putting In-App purchase in cocos2d was a PITA until I came across your post. I'm not done implementing it yet but i got further with your example than with any other I could find.

I am creating grenades that the user can buy in packs of five in the game. How can you keep track of how many grenades the user has bought so far, then subtract one each time he uses a grenade?

February 28, 2012 | Unregistered CommenterMarc Renaud

Can get full complete code ?

October 22, 2012 | Unregistered CommenterHua Wai

Great post, thanks. I was thinking about trying out in-app, so you have the perfect timing :)

(It is sad to see so much spam in the comments though.)

December 3, 2012 | Unregistered Commenterniw3

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(purchaseSuccess:) name:k this is line is missing some code... what is the k for?

March 29, 2013 | Unregistered CommenterRandy

kInAppPurchaseManagerTransactionSucceededNotification

May 25, 2013 | Unregistered CommenterNaveed

Hi, I am new to iOS development and I'm trying to implement IAP but I'm having a little bit of trouble getting my head around how to actually make the purchase. I've got a buy button which i want to start the transaction. This button is in a class which imports InAppPurchaseManager.h and StoreKit. I've implemented and tested the code provided and the product is being fetched correctly.

-(void) buy: (id) sender {

/*In-App Code*/
if ([[InAppPurchaseManager sharedInAppManager] storeLoaded])
{
NSLog(@"The Store has loaded");

// Update the UI to show that the store has loaded, ie. the user can make a purchase
SKProduct *prod = [[InAppPurchaseManager sharedInAppManager] getLevelUpgradeProduct];


NSString *desc = prod.localizedDescription;

NSString *title = prod.localizedTitle;

NSDecimalNumber *price = prod.price;


NSLog (@"Title %@", title);

NSLog (@"Description %@", desc);

NSLog (@"Price %@", price);

if( [[InAppPurchaseManager sharedInAppManager] canMakePurchases]){
[[InAppPurchaseManager sharedInAppManager] purchaseLevelUpgrade];
}

// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(purchaseSuccess:) name:kInAppPurchaseManagerTransactionSucceededNotification];

}else{
NSLog(@"The Store has not loaded");
}

}

I'm not really sure what I'm doing, can anyone help?

February 3, 2014 | Unregistered CommenterBooms

I am totally impressed with your work because your work is very grateful. I really like it very much. Your post and article is really informative.

It's very useful and helpful for me and everyone. Thanks for this informative post. Please give us more information. Keep it up

August 17, 2015 | Unregistered CommenterSticker printing uk

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>