I'm making an in-app purchase, but I have a bug that I can't find where it comes from...
First of all, I have a button and when you click it, my app Request the product, catches the response, you pay, and you get the product (everything works OK). But here comes my problem. If I click the button to buy anything again, I get TWO alerts that I bought something TWO times. Even if I click for a third time, i get THREE alerts that I bought something THREE times, and four and five according to the number of times I clicked.
So it seems like some variable keeps storing the requests.. Here's my code:
This validates the product ID
- (void) validateProductIdentifiers
{
NSString *monedas = @" ID FROM PRODUCT ";
NSSet *product = [NSSet setWithObject:monedas];
productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:product];
productsRequest.delegate = self;
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[productsRequest start];
NSLog(@"STARTED REQUEST");
}
This handles the response from Apple
- (void)productsRequest:(SKProductsRequest *)request
didReceiveResponse:(SKProductsResponse *)response
{
productsRequest=nil;
int found=0;
SKProduct *paraPagar;
skProducts = response.products;
for (SKProduct * skProduct in skProducts) {
NSLog(@"Found product: %@ %@ %0.2f",
skProduct.productIdentifier,
skProduct.localizedTitle,
skProduct.price.floatValue);
found=1;
paraPagar = skProduct;
}
if (found==1){
payment = [SKMutablePayment paymentWithProduct:paraPagar];
payment.quantity = 1;
[[SKPaymentQueue defaultQueue]addPayment:payment];
}else{
//error (not relevant code)
}
}
Accepting payment and finishing transaction
- (void)paymentQueue:(SKPaymentQueue *)queue
updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
NSLog(@"BOUGHT");
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
NSLog(@"FAILED");
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
[self failedTransaction];
break;
case SKPaymentTransactionStateRestored:
NSLog(@"RESTORED");
//[self restoreTransaction:transaction];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
case SKPaymentTransactionStatePurchasing:
NSLog(@"PURCHASING");
default:
break;
}
}
}
Thank you very much for your time!
My problem was that the observer was being duplicated every time I clicked on the button or when I changed views.
The solution is adding a flag, to see if the observer has already been added.
static bool hasAddObserver=NO;
PAYMENT METHOD{
if (!hasAddObserver) {
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
hasAddObserver=YES;
}
.....
I had the same problem, I would click buy on an IAP and would receive multiple responses and purchases from Apple.
addTransactionObserver()
was being called every time I left and came back to the view via viewDidLoad()
.
I needed to un-observe it in viewWillDisappear()
:
override func viewWillDisappear() {
SKPaymentQueue.defaultQueue().removeTransactionObserver(self)
}
I could't use a flag to prevent multiple observers like in mursang's answer because I listened for transactions in other views.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With