Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

paymentQueueRestoreCompletedTransactionsFinished: vs updatedTransactions:

I am restoring completed transactions (recurring) with

[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];

and in

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

I got a list of history transactions restored, made by the app, but the method:

- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue

is not even called once, so I wonder which one should I use? I did some research and found that updatedTransactions: method should be used with checking transaction state, but if I got a list of transactions restored, it is just meaningless to treat them all as transactions. Which one should I use? Does paymentQueueRestoreCompletedTransactionsFinished only gives me the latest one (ie sandbox subscription expires in several minutes and I got a full list of history transactions made when testing, in updatedTransactions).

like image 668
hzxu Avatar asked Jan 13 '13 23:01

hzxu


3 Answers

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.

like image 143
Ephemera Avatar answered Nov 08 '22 02:11

Ephemera


  1. Call [[SKPaymentQueue defaultQueue] addTransactionObserver:self] in (void)viewDidLoad or equivalent if applicable.
  2. Then call [[SKPaymentQueue defaultQueue] restoreCompletedTransactions].
  3. (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.

like image 36
El Tomato Avatar answered Nov 08 '22 01:11

El Tomato


I had this same issue with paymentQueueRestoreCompletedTransactionsFinished never getting called. I fixed by going to iTunes & Aoo Stores in Settings and logged out of the sandbox test account and tried it again. Worked as expected the next time after being prompted to login again on a restore.

like image 1
SlickDev Avatar answered Nov 08 '22 02:11

SlickDev