In-App Purchase

I’ve been working with in-app purchases, and would like to share a little of what I’ve found. Today I present a simple view controller that displays the contents of an in-app store. There’s a lot missing from it (e.g., you can’t see detailed descriptions of items, or, ahem, buy anything) but it does demonstrate how you might present a storefront to a user.


Here’s the view controller’s header:

#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>

@interface Store : UIViewController <UITableViewDataSource, UITableViewDelegate, SKProductsRequestDelegate>
	SKRequest*		request;
	NSArray*		products;
	NSNumberFormatter*	priceFormatter;
	UITableView*		tableView;
	UIView*			loadingView;

@property (nonatomic, retain) IBOutlet UITableView* tableView;
@property (nonatomic, retain) IBOutlet UIView* loadingView;


… and its implementation file:

#import "Store.h"

@interface Store ()

@property (nonatomic, retain) SKRequest* request;
@property (nonatomic, retain) NSArray* products;
@property (nonatomic, retain, readonly) NSNumberFormatter* priceFormatter;

- (void)dismiss;


@implementation Store

@synthesize request;
@synthesize products;
@synthesize tableView;
@synthesize loadingView;

- (NSNumberFormatter*)priceFormatter
	if (!priceFormatter)
		priceFormatter = [[NSNumberFormatter alloc] init];
		priceFormatter.formatterBehavior = NSNumberFormatterBehavior10_4;
		priceFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
	return priceFormatter;

- (void)viewDidLoad
	[super viewDidLoad];
	self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(dismiss)] autorelease];
	self.title = @"Store";
	NSArray* a = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Products" ofType:@"plist"]];
	self.request = [[[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithArray:a]] autorelease];
	self.request.delegate = self;
	[self.request start];

- (void)dealloc
	[request cancel];
	[request release];
	[products release];
	[priceFormatter release];
	[tableView release];
	[loadingView release];
	[super dealloc];

#pragma mark Table view data source methods

- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
    return 1;

- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
    return [products count];

- (UITableViewCell*)tableView:(UITableView*)aTableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
	static NSString* CellIdentifier = @"Cell";
	UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
	if (cell == nil)
        	cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
	SKProduct* product = [products objectAtIndex:indexPath.row];
	NSNumberFormatter* pf = self.priceFormatter;
	pf.locale = product.priceLocale;
	cell.textLabel.text = product.localizedTitle;
	cell.detailTextLabel.text = [pf stringFromNumber:product.price];
	return cell;

#pragma mark Table view delegate methods

- (NSIndexPath*)tableView:(UITableView*)tableView willSelectRowAtIndexPath:(NSIndexPath*)indexPath
	return nil;

#pragma mark Products request delegate methods

- (void)productsRequest:(SKProductsRequest*)aRequest didReceiveResponse:(SKProductsResponse*)response
	self.request = nil;
	self.products = response.products;

	[self.tableView reloadData];
	self.loadingView.hidden = YES;

#pragma mark Extension methods

- (void)dismiss
	[self.navigationController.parentViewController dismissModalViewControllerAnimated:YES];


Naturally, you’ll also need a NIB. Note that this code assumes that your project includes a Products.plist file, which encodes an NSArray of product IDs as NSStrings of the form com.yourcompany.yourapp.someproductid.

Finally, the code assumes that it’s running inside a modal navigation controller; this is relevant to the implementation of dismiss.


If you’re working with in-app purchases, you should read the “In App Purchase Programming Guide“, particularly the sections on “Adding a Store to Your Application” and “Testing a Store“. You should should also check the relevant sections of the “iTunes Connect Developer Guide“.

Share and Enjoy:
  • Twitter
  • Facebook
  • Digg
  • Reddit
  • HackerNews
  • Google Bookmarks
  • Slashdot
This entry was posted in iPhone. Bookmark the permalink.

Comments are closed.