views:

1028

answers:

1

For my app i have it far enought that it will ask for a confirmation and account for an in-app purchase, but I don't know how to enable the item after the purchase is complete.

SKPayment *payment = [SKPayment paymentWithProductIdentifier:@"com.silver.tapp.page2"];

[[SKPaymentQueue defaultQueue] addPayment:payment];

Thats what i have so far

[[p2Controller tabBarItem] setEnabled:TRUE];

this is the code i would like to execute

+5  A: 

First you should really go back and review the In App purchase documentation that Apple provides - they outline this in detail and it's useful to understand what is being done on their side.

What you are missing is the SKPaymentTransactionObserver - it's your responsibility to implement this observer which you add as an observer of the SKPaymentTransactionQueue. Apple recommends that you add the observer at app launch to the default queue so that it will be able to observe all transactions that take place while your app is running.

Essentially you need to write your own class that implements the SKPaymentTransactionObserver protocol. What this class does is observe catch the callbacks from the payment queue when the iTunes store processes the payment and let's you catch the success and failure events.

Here is the skeleton for the Payment Observer:

PaymentObserver.h

#import <StoreKit/StoreKit.h>

@interface PaymentObserver : NSObject <SKPaymentTransactionObserver> {  
}

- (void) completeTransaction: (SKPaymentTransaction *)transaction;
- (void) restoreTransaction: (SKPaymentTransaction *)transaction;
- (void) failedTransaction: (SKPaymentTransaction *)transaction;

@end

PaymentObserver.m

#import "PaymentObserver.h"
@implementation PaymentObserver

- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions
{
  // handle payment cancellation
}

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
  // handle the payment transaction actions for each state
  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];        
      default:
        break;
    }
  }
}



- (void) completeTransaction: (SKPaymentTransaction *)transaction;
{
  // Record the transaction
  //...

  // Do whatever you need to do to provide the service/subscription purchased
  //...

  // Remove the transaction from the payment queue.
  [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

}

- (void) restoreTransaction: (SKPaymentTransaction *)transaction
{
  // Record the transaction
  //...

  // Do whatever you need to do to provide the service/subscription purchased
  //...

  [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}

- (void) failedTransaction: (SKPaymentTransaction *)transaction
{  
  if (transaction.error.code != SKErrorPaymentCancelled)
  {
    // Optionally, display an error here.    
  }
  [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}

@end

Once you have implemented the PaymentObserver you need to add an instance off it to the default payment queue as a transaction observer.

// Done at app launch...
PaymentObserver *paymentObserver = [[PaymentObserver alloc] init];
[[SKPaymentQueue defaultQueue] addTransactionObserver:paymentObserver];
paulthenerd
hey, this answer saved my bacon today. Sure it's in the apple docs, but I was trying to fix a bug in code written by another developer and looking at this, I was able to see what he had missed. Thank you!
Carl Coryell-Martin