Hmm, you don't need to pay anyone when you can get free help here..
The thing is, it's actually not that hard, it's the connecting to iTunes Connect that actually sucks.
(i'm gonna post the entire code, but this isn't top notch, so i hope someone can refactor it a bit)
Basically, You want an InAppPurchaseManager
->
InAppPurchaseManager.h (I used SynthesizedSingleton, to make it a Singleton, so you need to download this one from my cloud ->
http://cl.ly/420y0p111f1x3H3Z1a0A)
Code:
//
// InAppPurchaseManager.h
//
// Created by Thijs Bastiaens on 06/04/12.
#import <Foundation/Foundation.h>
#import <StoreKit/StoreKit.h>
#import "SynthesizeSingleton.h"
#define kInAppPurchaseManagerProductsFetchedNotification @"kInAppPurchaseManagerProductsFetchedNotification"
#define kInAppPurchaseManagerTransactionFailedNotification @"kInAppPurchaseManagerTransactionFailedNotification"
#define kInAppPurchaseManagerTransactionSucceededNotification @"kInAppPurchaseManagerTransactionSucceededNotification"
@interface InAppPurchaseManager : NSObject <SKProductsRequestDelegate, SKPaymentTransactionObserver>
{
SKProduct *proUpgradeProduct;
SKProductsRequest *productsRequest;
}
+ (InAppPurchaseManager *) sharedInAppPurchaseManager;
// public methods
- (void) requestAddonMPack1Data;
- (void) requestAddonFPack1Data;
- (void)loadStore;
- (BOOL)canMakePurchases;
/* PURCHASE PACKS */
- (void)purchaseMAddonPack1;
- (void)purchaseFAddonPack1;
@end
InAppPurchaseManager.m
Code:
//
// InAppPurchaseManager.m
//
// Created by Thijs Bastiaens on 06/04/12.
#import "InAppPurchaseManager.h"
#import "SVProgressHUD.h"
/*
#define kInAppMPack1ProductId @"com.yourcompany.yourappName.malePack1"
#define kInAppFPack1ProductId @"com.yourcompany.yourappName.femalePack1"
*/
#define kInAppMPack1 @"malePack1"
#define kInAppFPack1 @"femalePack1"
@implementation InAppPurchaseManager
SYNTHESIZE_SINGLETON_FOR_CLASS(InAppPurchaseManager);
- (id)init
{
self = [super init];
if (self) {
}
return self;
}
- (void)requestAddonMPack1Data
{
NSSet *productIdentifiers = [NSSet setWithObjects:kInAppMPack1, nil];
productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
productsRequest.delegate = self;
[productsRequest start];
}
- (void) requestAddonFPack1Data {
NSSet *productIdentifiers = [NSSet setWithObjects:kInAppFPack1, nil];
productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
productsRequest.delegate = self;
[productsRequest start];
}
#pragma mark -
#pragma mark SKProductsRequestDelegate methods
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
/*
NSMutableArray *products = [[NSMutableArray alloc] initWithArray:response.products];
proUpgradeProduct = [products count] == 1 ? [[products objectAtIndex:0] retain] : nil;
if (proUpgradeProduct)
{
NSLog(@"Product title: %@" , proUpgradeProduct.localizedTitle);
NSLog(@"Product description: %@" , proUpgradeProduct.localizedDescription);
NSLog(@"Product price: %@" , proUpgradeProduct.price);
NSLog(@"Product id: %@" , proUpgradeProduct.productIdentifier);
}
for (NSString *invalidProductId in response.invalidProductIdentifiers)
{
NSLog(@"Invalid product id: %@" , invalidProductId);
}*/
[[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerProductsFetchedNotification object:self userInfo:nil];
}
#pragma -
#pragma Public methods
//
// call this method once on startup (For example, App Delegate)
//
- (void)loadStore
{
// restarts any purchases if they were interrupted last time the app was open
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
// get the product description (defined in early sections)
[self requestAddonMPack1Data];
[self requestAddonFPack1Data];
}
//
// call this before making a purchase
//
- (BOOL)canMakePurchases
{
NSLog(@"%i", [SKPaymentQueue canMakePayments]);
return [SKPaymentQueue canMakePayments];
}
//
// kick off the upgrade transaction
//
- (void)purchaseMAddonPack1
{
SKPayment *payment = [SKPayment paymentWithProductIdentifier:kInAppMPack1];
[[SKPaymentQueue defaultQueue] addPayment:payment];
[SVProgressHUD showWithStatus:@"Requesting Male Package" maskType:SVProgressHUDMaskTypeGradient];
}
- (void)purchaseFAddonPack1 {
SKPayment *payment = [SKPayment paymentWithProductIdentifier:kInAppFPack1];
[[SKPaymentQueue defaultQueue] addPayment:payment];
[SVProgressHUD showWithStatus:@"Requesting Female Package" maskType:SVProgressHUDMaskTypeGradient];
}
#pragma -
#pragma Purchase helpers
//
// saves a record of the transaction by storing the receipt to disk
//
- (void)recordTransaction:(SKPaymentTransaction *)transaction
{
if ([transaction.payment.productIdentifier isEqualToString:kInAppMPack1])
{
// save the transaction receipt to disk
[[NSUserDefaults standardUserDefaults] setValue:transaction.transactionReceipt forKey:@"addonMPack1TransactionReceipt" ];
[[NSUserDefaults standardUserDefaults] synchronize];
} else if ([transaction.payment.productIdentifier isEqualToString:kInAppMPack1]) {
// save the transaction receipt to disk
[[NSUserDefaults standardUserDefaults] setValue:transaction.transactionReceipt forKey:@"addonFPack1TransactionReceipt" ];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
//
// enable pro features
//
- (void)provideContent:(NSString *)productId
{
if ([productId isEqualToString:kInAppMPack1])
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isMAddonPackage1Bought" ];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName:@"packageBought" object:nil];
} else if ([productId isEqualToString:kInAppFPack1])
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isFAddonPackage1Bought" ];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName:@"packageBought" object:nil];
}
}
//
// removes the transaction from the queue and posts a notification with the transaction result
//
- (void)finishTransaction:(SKPaymentTransaction *)transaction wasSuccessful:(BOOL)wasSuccessful
{
// remove the transaction from the payment queue.
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:transaction, @"transaction" , nil];
if (wasSuccessful)
{
// send out a notification that we’ve finished the transaction
[[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerTransactionSucceededNotification object:self userInfo:userInfo];
}
else
{
// send out a notification for the failed transaction
[[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerTransactionFailedNotification object:self userInfo:userInfo];
}
}
//
// called when the transaction was successful
//
- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
[self recordTransaction:transaction];
[self provideContent:transaction.payment.productIdentifier];
[self finishTransaction:transaction wasSuccessful:YES];
}
//
// called when a transaction has been restored and and successfully completed
//
- (void)restoreTransaction:(SKPaymentTransaction *)transaction
{
[self recordTransaction:transaction.originalTransaction];
[self provideContent:transaction.originalTransaction.payment.productIdentifier];
[self finishTransaction:transaction wasSuccessful:YES];
}
//
// called when a transaction has failed
//
- (void)failedTransaction:(SKPaymentTransaction *)transaction
{
if (transaction.error.code != SKErrorPaymentCancelled)
{
// error!
[self finishTransaction:transaction wasSuccessful:NO];
}
else
{
// this is fine, the user just cancelled, so don’t notify
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
}
#pragma mark -
#pragma mark SKPaymentTransactionObserver methods
//
// called when the transaction status is updated
//
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
break;
default:
break;
}
}
[SVProgressHUD dismiss];
}
@end
You can also use an SKProduct category called LocalizedPrice (this is taken from a blog the code, so I don't take any credit).
SKProduct+LocalizedPrice.h
Code:
//
// SKProduct+LocalizedPrice.h
//
// Created by Thijs Bastiaens on 06/04/12.
#import <StoreKit/StoreKit.h>
@interface SKProduct (LocalizedPrice)
@property (nonatomic, readonly) NSString *localizedPrice;
@end
.M file
Code:
//
// SKProduct+LocalizedPrice.m
//
// Created by Thijs Bastiaens on 06/04/12.
#import "SKProduct+LocalizedPrice.h"
@implementation SKProduct (LocalizedPrice)
- (NSString *)localizedPrice
{
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setLocale:self.priceLocale];
NSString *formattedString = [numberFormatter stringFromNumber:self.price];
[numberFormatter release];
return formattedString;
}
@end
After that, basically in your code you can do stuff like this ->
Code:
- (IBAction)pressedButton:(id)sender {
UIButton *button = (UIButton*)sender;
NSInteger taggie = button.tag;
if (taggie == 0) {
[self goToMainVCWithArray:[[DataUtil sharedDataUtil] getArrayWithInteger:taggie+1]];
}
else if ([self packageBought]) {
[self goToMainVCWithArray:[[DataUtil sharedDataUtil] getArrayWithInteger:taggie+1]];
} else {
if ([[DataUtil sharedDataUtil] gender] == kTypeMale) {
[[InAppPurchaseManager sharedInAppPurchaseManager] purchaseMAddonPack1];
} else if ([[DataUtil sharedDataUtil] gender] == kTypeFemale) {
[[InAppPurchaseManager sharedInAppPurchaseManager] purchaseFAddonPack1];
}
}
}
- (BOOL) packageBought {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([[DataUtil sharedDataUtil] gender] == kTypeMale) {
if ([defaults boolForKey:@"isMAddonPackage1Bought"] == YES) {
return YES;
} else {
return NO;
}
} else if ([[DataUtil sharedDataUtil] gender] == kTypeFemale) {
if ([defaults boolForKey:@"isFAddonPackage1Bought"] == YES) {
return YES;
} else {
return NO;
}
}
return NO;
}
I tried to make a clean example, I hope it can helps you

(the itunes connect steps are ignored in my "guide")
EDIT
ALso, in your view controller, you can listen to ->
Code:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadButtons) name:@"packageBought" object:nil];
To optionally refresh your UI
