Search code examples
iosobjective-cin-app-purchaseobservers

iOS's SKPayment addTransactionObserver & defaultqueue, what is the story?


I'm struggling with if I need to add a Transaction observer and also if I need to remove the transaction observer and where and what all this is ...

My inherited code includes the app delegate w/ an observer... AppDelegate ->

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    SKPaymentQueue *paymentQueue = [self.injector getInstance:[SKPaymentQueue class]];
    [paymentQueue addTransactionObserver:self.purchaseHelper];
}

and I'm working on the restore part of the purchase helper... PurchaseHelper ->

-(void) beginRestorePurchases:(BOOL)serverRestore {
    self.serverRestore = serverRestore;
    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}



-(void) paymentQueueRestoreCompletedTransactionsFinished : (SKPaymentQueue *) queue {
    for (SKPaymentTransaction *transaction in queue.transactions) {
       [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    }
}

My concern at the moment is with Restoring purchases. ( I realize that i'm using a dependency injection pattern for the other portion(the purchasing part) of the code so it different. I'm not sure if this is having an effect on my problem as well.)

The problem is that I have no idea if I should be adding another observer for restoring or not. If I do I get some weird behavior with iTunes prompting multiple times upon restoring. In SO posts I see some mention of removing the observer. When would you do this if I'm creating it on the app delegate level?

Perhaps the my SKPaymentQueue * paymentQueue object is not a defaultQueue object???? No idea....


Solution

  • You always need to add your transaction observer, and early in the app lifecycle. Actions outside your control can cause transactions to fail to complete and the OS level queue will re-feed these to your app. I can't think of any common, legitimate reason to remove the observer.

    You only need one observer, and that observer should be the gatekeeper to handling all the IAP events.

    You also need to make certain that you're calling finish on each legitimately completed transaction. If you don't, you can wind up stacking lots of duplicated (from the SKU perspective) transactions on top of each other.