¿Se llama a paymentQueue: updatedTransactions cuando no debería?

I'm having a weird problem with an in-app purchase...

After I'm requesting the product information, sometimes the paymentQueue:updatedTransactions gets called automatically for some reason.

In my store's viewDidLoad method, I initialize and start the request:

- (void)viewDidLoad
    [super viewDidLoad];

    productsArray = [[NSArray alloc] init];

    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

    NSSet *productIdentifiers = [NSSet setWithObjects:PRODUCT_ID, nil];
    productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
    productsRequest.delegate = self;
    [productsRequest start];

Then I get a response:

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
    productsArray = [[NSArray alloc] initWithArray:response.products];

    NSLog(@"Products Count: %d",[productsArray count]);
    NSLog(@"Invalid Products Count: %d",[response.invalidProductIdentifiers count]);

    if ([productsArray count] > 0)
        NSLog(@"Product title: %@" ,[productsArray objectAtIndex:0]);
        [self hideLoadingView];

    } else {
        UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"No products found"
                                                            message:@"There might have been a problem. Please try again soon." delegate:self 
                                                  cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];
        [alertView release];

        [self hideLoadingView];
        [purchaseBtn setEnabled:NO];


    [productsRequest release];

    [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerProductsFetchedNotification object:self userInfo:nil];


This is where I expect the process to end, and wait for the user to tap the buy button... but sometimes (like, 70% of the times), I get a username/password alert box pop-up in order to buy the item... but the user didn't tap anything... (and if the user is already "logged in", then it buys the item without asking. Which is NOT how it should be.

This is the method that is being called automatically sometimes:

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
    NSLog(@"updated transaction");
    for (SKPaymentTransaction *transaction in transactions)
        switch (transaction.transactionState)
            case SKPaymentTransactionStatePurchased:
                [self completeTransaction:transaction];
            case SKPaymentTransactionStateFailed:
                [self failedTransaction:transaction];

and this is the IBAction of the buy button:

-(IBAction)buyItem:(id)sender {

    [self showLoadingView];

    SKPayment *payment = [SKPayment paymentWithProductIdentifier:[(SKProduct *)[productsArray objectAtIndex:0] productIdentifier]];
    [[SKPaymentQueue defaultQueue] addPayment:payment];


I thought that the user/password alert box of StoreKit shouldn't get displayed until I call the defaultQueue's "addPayment" method, which appears ONLY in the IBAction.

¿Algunas ideas? ¡Gracias!

preguntado el 10 de marzo de 12 a las 01:03

1 Respuestas

Once you add a transaction observer iOS will check the default Queue if there is any non completed transaction (which mean you didn't finish it) so it will show the alert box every time there is a transaction until you finish it even if you didn't do any action to add a new payment.

respondido 10 mar '12, 14:03

Thanks Malek! That indeed was the reason. Is there a preferred way to handle this? Is the customer already charged if the transaction is interrupted and waiting in the queue? Is there a way to cancel that transaction that was interrupted and still waits in the queue? Thank you very much! - itai alter

well this is an advantage point in iOS .. because you can ensure if the user pay for your product and you didn't deliver it (download it) next time you add a transaction observer to download it and finish the transaction .. you need to be carful to finish the transaction just when you download your product item ... now for your case to workAround your issue with this alert you can enter the password and in the updateTransactions function call the finishTransaction method .. after the queue is empty returned the updateTransaction as it was. - malek_jundi

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.