Restore button for iOS non-consumable in-app purch

2020-01-31 02:25发布

问题:

Apple have unfortunately rejected my app for not having a restore button. I wanted to have a seamless experience for the user but there are some problems.

- (void)purchaseProUpgrade
{ 
   [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

   // User is prompted for iTunes username and password here (1)
   [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}

// Then this delegate Function Will be fired
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
    if( queue.transactions.count == 0 ) {

        [self setUpgradeProductId];

       // User is prompted for iTunes username and password here (2)
        SKPayment *payment = [SKPayment paymentWithProductIdentifier:kInAppPurchaseProUpgradeProductId];
       [[SKPaymentQueue defaultQueue] addPayment:payment];                                                                 

    }else {

      [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerTransactionSucceededNotification object:self userInfo:NULL];
    }
  }

Is the above a good solution? The logic would be:

  1. User presses button to remove in-app purchase.
  2. Check if the user has already made a purchase (user has to enter username and password)
  3. If user has already made a purchase, restore
  4. If user has not already made a purchase,prompt for payment (user has to enter password again).

The problems with this approach are: 1. An additional server call 2. User has to enter details twice.

Has anyone actually implemented a Restore button that they can demonstrate?

回答1:

No need of implementing your own logic Just implement this

- (IBAction)restorePreviousTransaction:(id)sender {
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}

This will call this method

 - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
   case SKPaymentTransactionStateRestored:
                if ([self respondsToSelector:@selector(restoreTransaction:)]) {
                    [self restoreTransaction:transaction];
                    return;                
}

This will call these delegate methods for transaction success or failure

- (void)restoreTransaction:(SKPaymentTransaction *)transaction
-(void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
-(void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue


回答2:

Add this code to the page where you had added the restore button:

- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {  
     NSLog(@"%@",error);
}

// Call This Function
- (void) checkPurchasedItems
{
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}

//Then this delegate Function Will be fired
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
    purchasedItemIDs = [[NSMutableArray alloc] init];
    NSLog(@"received restored transactions: %i", queue.transactions.count);

    for (SKPaymentTransaction *transaction in queue.transactions)
    {
        NSString *productID = transaction.payment.productIdentifier;

        [purchasedItemIDs addObject:productID];

        NSLog(@"%@",purchasedItemIDs);
    }
}


回答3:

Apple rejects application with In App Purchase, that does not have a restore purchase button. In the app view, add a restore button. Then in the In App Purchase helper class, add the following method:

- (void)restoreCompletedTransactions {
    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; 
}

Now call this method from the button click action and it will restore the previous purchase.



回答4:

*- (IBAction)restorePreviousTransaction:(id)sender {
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
delegate method call:
 - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
   case SKPaymentTransactionStateRestored:
                if ([self respondsToSelector:@selector(restoreTransaction:)]) {
                    [self restoreTransaction:transaction];
                    return;                
}
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
    purchasedItemIDs = [[NSMutableArray alloc] init];
    NSLog(@"received restored transactions: %i", queue.transactions.count);
    for (SKPaymentTransaction *transaction in queue.transactions)
    {
        NSString *productID = transaction.payment.productIdentifier;
        [purchasedItemIDs addObject:productID];
        NSLog(@"%@",purchasedItemIDs);
    }
}*