1

I'm trying to do the following;

Obtain the previous purchases but only load into the payment queue one which is selected by the user. I don't want the user downloading multiple restored purchases. Apple recommend allowing the user to decide what to restore and this is where I'm stuck. At the moment, I'm allowing RestoreCompletedTransactions to be called when the user selects restore but this then means I have to clear the selected paymentqueue. This seems like an unnecessary procedure and causes more problems than it solves. I'm sure there is an easy way of doing this but I've trawled the web for hours looking for a solution and Apple documentation does not give me any reasonable procedure for this. I'd be grateful if anyone can give me some direction here.

My purchase of these Non-Consumables is working fine, its just the restore thats bogging me down.

By the way - its Apple hosted content!

- (IBAction)buyProduct:(id)sender { //checked!!

NSLog(@"Performing in-app purchase: %@",_product);

SKPayment *payment = [SKPayment paymentWithProduct:_product];
[[SKPaymentQueue defaultQueue] addPayment:payment];

}

- (IBAction)Restore:(id)sender {

NSLog(@"Performing in-app restore_product: %@",_product);
NSLog(@"Performing in-app restore_productID: %@",productID);

[self restoreThePurchase];

}

- (BOOL)restoreThePurchase {

// restore the purchase
[[SKPaymentQueue defaultQueue]restoreCompletedTransactions];

return YES;
}

#pragma mark -
#pragma mark SKPaymentTransactionObserver methods

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

for (SKPaymentTransaction *transaction in transactions) {
    switch (transaction.transactionState) {
        case SKPaymentTransactionStatePurchased: {

            NSLog(@"Transaction State Purchased");


            [[SKPaymentQueue defaultQueue] startDownloads:transaction.downloads];
            [self completeTransaction:transaction];

            break;
        }

        case SKPaymentTransactionStateFailed: {
            // transaction didn't work
            [self displayAlertViewWithMessage:@"There was a problem with your purchase. Please try again later."];
            break;
        }

        case SKPaymentTransactionStateRestored: {
            // purchase has been restored

            transactionRestored = [[NSMutableArray alloc] init];

            NSLog(@"received restored transactions: %lu", (unsigned long)queue.transactions.count);

            for (SKPaymentTransaction *transaction in queue.transactions)
            {
                {
                    NSString *aProductID = transaction.payment.productIdentifier;
                    [transactionRestored addObject:aProductID];

                }

                NSLog(@"TransactionRestoredArray in PQRCTF : %@", transactionRestored);
                NSLog(@"Restore indentifier in PQRCTF : %@", transaction.payment.productIdentifier);
                NSLog(@"ProductID in PQRCTF : %@", productID);
                NSLog(@"Transaction in PQRCTF : %@", transaction);
                NSLog(@"OrignianalTransaction in PQRCTF : %@", transaction.originalTransaction);
                NSLog(@"OrignianalTransaction in PQRCTF : %@", transaction.payment.productIdentifier);


                if ([transactionRestored containsObject:productID]) {

                    NSLog(@"Was purchased before!in PQRCTF");
                    //[self restoreTransaction:transaction];

                } else {

                    [[SKPaymentQueue defaultQueue]finishTransaction:transaction];

                }


            break;

        }

        case SKPaymentTransactionStatePurchasing: {
            // currently purchasing
            break;
        }

        default:
            break;
    }
}
}
}
Slarty Bartfast
  • 635
  • 7
  • 13
  • perhaps you should test with a new iTunes Connect User. It looks like your restore is restoring duplicate transactions – Daniel Galasko Oct 06 '14 at 11:02
  • Thats just it. I want to allow the user to select only one transaction to restore rather that restoring them all. How do I force RestoreCompletedTransactions to only load a selected product into the payment queue instead of them all? – Slarty Bartfast Oct 06 '14 at 11:13
  • Are you testing this on production or in development? – Daniel Galasko Oct 06 '14 at 11:13
  • Because if you are testing in development using an iTunes Connect User chances are you have multiple purchases linked to that user. Create a new user and test fresh. In production you won't have the scenario – Daniel Galasko Oct 06 '14 at 11:14
  • Anytime! Purchases can be a real pain :) – Daniel Galasko Oct 06 '14 at 11:22

1 Answers1

8

My suspicion is that you are testing with an iTunes Connect Test User with duplicate purchases. This issue will never happen in production but stumps a lot of developers during testing. The reason being that you can purchase the same product multiple times against a Test User and these purchases will be added to the Test Users Account, when you attempt a restore, every single purchase made will be restored, bogging your app down.

Currently, there is no way to clear purchases from a Test User. This means that your best bet is to create a new Test User with a specific configuration: In this scenario that configuration would be that the user has purchased a product with a specific identifier. You could name your test user with the specific product identifier to be more direct with newcomers attempting to make purchases with this user.

So set up a new user and test your code again.

Community
  • 1
  • 1
Daniel Galasko
  • 23,617
  • 8
  • 77
  • 97
  • 1
    Thanks Daniel your advice helped! I had pending downloads also. When I deleted that user from the sandbox test users, reset the test iPhone, and created a new user the purchases and the restore seem to work well. I have another issue so I'll repost but thanks again for the help! – Slarty Bartfast Oct 07 '14 at 18:30