utorak, 27. prosinca 2011.

In App purchase coding, programming guide for xcode


I will present you my solution that was processed to app store without problem

1. you need unique app ID (that is app ID that doesn't have wildcard *)
  you can create it accessing trough http://developer.apple.com/iphone

2. create new provisioning profile and download it to your mac

3. code it using xcode (all of above you have detailed expalantion on web site given above, only thing that you don't have to is submit (upload binary) and than cancel your app, that much has changed since author wrote it.

here is how (hope it helps)

in header file
#import <StoreKit/StoreKit.h>

#define kInAppPurchaseManagerProductsFetchedNotification @"kInAppPurchaseManagerProductsFetchedNotification"
#define kInAppPurchaseManagerTransactionFailedNotification @"kInAppPurchaseManagerTransactionFailedNotification"
#define kInAppPurchaseManagerTransactionSucceededNotification @"kInAppPurchaseManagerTransactionSucceededNotification"

@interface RootViewController : UIViewController<SKProductsRequestDelegate, SKPaymentTransactionObserver> {

   
    IBOutlet UIButton *upgradeButton;
   SKProduct *proUpgradeProduct;
    SKProductsRequest *productsRequest;
 
}



- (IBAction) clickOnUpgrade;

- (void)loadStore;
- (BOOL)canMakePurchases;
- (void)purchaseProUpgrade;
- (void)requestProUpgradeProductData;



@property (nonatomic, retain) UIButton *upgradeButton;


in m file (it was designed to be in rootview controller file)

- (void)viewDidLoad {
    [super viewDidLoad];   
   
    //if upgrade purchased hide upgrade button
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
  //   NSLog(@"haj");
    if ([prefs boolForKey:@"isProUpgradePurchased"]==YES)
        upgradeButton.hidden = YES; else [self loadStore];
   
    [[NSNotificationCenter defaultCenter] addObserver: self
                                             selector: @selector(napraviKupnju:)
                                                 name: kInAppPurchaseManagerProductsFetchedNotification
                                               object: self.view.window];
    [[NSNotificationCenter defaultCenter] addObserver: self
                                             selector: @selector(sakrijGumb:)
                                                 name: kInAppPurchaseManagerTransactionSucceededNotification
                                               object: self.view.window];
   
}

- (IBAction) clickOnUpgrade {
   

    if ([self canMakePurchases]) {
        Kupnja=YES;
    [self requestProUpgradeProductData];
    }
    

   
}

-(void) napraviKupnju: (NSNotification *)notif  {
    //NSLog(@"hello");
   
   
    if (Kupnja==YES)
     [self purchaseProUpgrade];
}

-(void) sakrijGumb: (NSNotification *)notif  {
    upgradeButton.hidden = YES;
}

- (void)requestProUpgradeProductData
{
    NSSet *productIdentifiers = [NSSet setWithObject:@"insert here your unique app ID" ];
    productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
    productsRequest.delegate = self;
    [productsRequest start];
   
    // we will release the request object in the delegate callback
}

#pragma mark -
#pragma mark SKProductsRequestDelegate methods

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSArray *products = 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);
       
        [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerProductsFetchedNotification object:self userInfo:nil];
    }
   
    for (NSString *invalidProductId in response.invalidProductIdentifiers)
    {
        NSLog(@"Invalid product id: %@" , invalidProductId);
    }
   
    // finally release the reqest we alloc/init’ed in requestProUpgradeProductData
    [productsRequest release];
   
   
}



#pragma -
#pragma Public methods

//
// call this method once on startup
//
- (void)loadStore
{
    // restarts any purchases if they were interrupted last time the app was open
    Kupnja = NO;
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
   
    // get the product description (defined in early sections)
    [self requestProUpgradeProductData];
   
}

//
// call this before making a purchase
//
- (BOOL)canMakePurchases
{//NSLog(@"haj can make purchase");
    return [SKPaymentQueue canMakePayments];
}

//
// kick off the upgrade transaction
//
- (void)purchaseProUpgrade
{//NSLog(@"haj purchase upgrade");
   
    SKPayment *payment = [SKPayment paymentWithProduct:proUpgradeProduct];
    [[SKPaymentQueue defaultQueue] addPayment:payment];
   
}

#pragma -
#pragma Purchase helpers

//
// saves a record of the transaction by storing the receipt to disk
//
- (void)recordTransaction:(SKPaymentTransaction *)transaction
{//NSLog(@"haj 7");
    if ([transaction.payment.productIdentifier isEqualToString:kInAppPurchaseProUpgradeProductId])
    {
        // save the transaction receipt to disk
        [[NSUserDefaults standardUserDefaults] setValue:transaction.transactionReceipt forKey:@"proUpgradeTransactionReceipt" ];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

//
// enable pro features
//
- (void)provideContent:(NSString *)productId
{//NSLog(@"haj 6");
    if ([productId isEqualToString:kInAppPurchaseProUpgradeProductId])
    {
        // enable the pro features
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isProUpgradePurchased" ];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

//
// removes the transaction from the queue and posts a notification with the transaction result
//
- (void)finishTransaction:(SKPaymentTransaction *)transaction wasSuccessful:(BOOL)wasSuccessful
{//NSLog(@"haj 5");
    // 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
{//NSLog(@"haj 4");
    [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
{//NSLog(@"haj 3");
    [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
{//NSLog(@"haj 1");
    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
{NSLog(@"haj 2");
    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;
        }
    }
}