paymentQueueRestoreCompletedTransactionsFinished: vs updatedTransactions:
There is an excellent WWDC Video about using StoreKit, it is WWDC2012 Session 302.
To isolate each purchase, your updatedTransactions
method could look something like this:
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for (SKPaymentTransaction *transaction in transactions) {
switch(transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
// Unlock content
//... Don't forget to call `finishTransaction`!
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStatePurchasing:
// Maybe show a progress bar?
break;
case SKPaymentTransactionStateFailed:
// Handle error
// You must call finishTransaction here too!
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
// This is the one you want ;)
// ...Re-unlock content...
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
Once you've determined that the purchase is being restored, you can make content available as you see fit - preferably by calling a separate method from within that switch statement and passing the transaction as a parameter. The implementation is up to you of course.
- Call
[[SKPaymentQueue defaultQueue] addTransactionObserver:self]
in(void)viewDidLoad
or equivalent if applicable. - Then call
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions]
. (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
will be called accordingly through (2).
If you don't call the method in (1), the application will never reach (3) to restore transactions in the first place.