Ios 某些客户端的应用内购买不起作用或无法恢复

Ios 某些客户端的应用内购买不起作用或无法恢复,ios,objective-c,xcode,in-app-purchase,Ios,Objective C,Xcode,In App Purchase,我的一些客户告诉我,即使他们进行应用内购买,产品也没有加载。但我的大多数客户都没有这个问题。我是在指示他们做恢复手术,但那没有帮助。问题是,它们可以在其他具有相同苹果id的设备上正确恢复 没有特定的设备或IOS版本,应用程序没有崩溃。它只是说恢复正确或购买正确,但它没有这样做 它让我发疯,因为我在很多设备上都试过,而且它对我来说是正确的 我想分享我使用的代码,这可能会帮助你们理解我不能理解的问题 - (void)productsRequest:(SKProductsRequest *)reque

我的一些客户告诉我,即使他们进行应用内购买,产品也没有加载。但我的大多数客户都没有这个问题。我是在指示他们做恢复手术,但那没有帮助。问题是,它们可以在其他具有相同苹果id的设备上正确恢复

没有特定的设备或IOS版本,应用程序没有崩溃。它只是说恢复正确或购买正确,但它没有这样做

它让我发疯,因为我在很多设备上都试过,而且它对我来说是正确的

我想分享我使用的代码,这可能会帮助你们理解我不能理解的问题

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {

    SKProduct *validProduct = nil;
    NSUInteger count = [response.products count];

    if( count > 0 ) {
        validProduct = [response.products objectAtIndex:0];
        NSLog(@"Products Available!");
        [self purchase:validProduct];
    }
    else if(!validProduct){
        NSLog(@"No products available");
        [self hideProgressHud];
        isProgress = NO;

        UIAlertController *alert = [UIAlertController alertControllerWithTitle:LocalizedString(@"Notice") message:LocalizedString(@"Product is not available now.") preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *cancelBtn = [UIAlertAction actionWithTitle:LocalizedString(@"OK") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        }];
        [alert addAction:cancelBtn];
        [self presentViewController:alert animated:true completion:nil];
    }
}

- (void)purchase:(SKProduct *)product {
    SKPayment *payment = [SKPayment paymentWithProduct:product];
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}

- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {

    NSLog(@"received restored transactions: %lu", (unsigned long)queue.transactions.count);
    for(SKPaymentTransaction *transaction in queue.transactions){
        if(transaction.transactionState == SKPaymentTransactionStateRestored || transaction.transactionState == SKPaymentTransactionStateRestored){
            NSLog(@"Transaction state -> Restored");
            NSString *productID = transaction.payment.productIdentifier;
            [[InAppPurchaseManager sharedManager] savePurchaseItem:productID];
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            break;
        }
    }
    [self hideProgressHud];
}

- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {

    [self hideProgressHud];
}

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

    static bool isOnce = false;
    for(SKPaymentTransaction *transaction in transactions){
        if (transaction.transactionState == SKPaymentTransactionStatePurchasing) {
            //called when the user is in the process of purchasing, do not add any of your own code here.
            NSLog(@"Transaction state -> Purchasing");
        }
        else if (transaction.transactionState == SKPaymentTransactionStatePurchased) {               
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            [self refresh_purchaseBtn];

            return;
        }
        else if (transaction.transactionState == SKPaymentTransactionStateRestored) {
            NSLog(@"Transaction state -> Restored");
            [self hideProgressHud];
            isProgress = NO;
            //add the same code as you did from SKPaymentTransactionStatePurchased here
            NSString *productID = transaction.payment.productIdentifier;
            if ([productID isEqualToString:kPURCHASE_ITEM_TYPE_A] || [productID isEqualToString:kPURCHASE_ITEM_TYPE_B] || [productID isEqualToString:kPURCHASE_ITEM_TYPE_C]) {
                [[InAppPurchaseManager sharedManager] savePurchaseItem:productID];
            }
            else {
                NSArray *arr = [Workout MR_findByAttribute:@"productId" withValue:productID inContext:ApplicationDelegate.managedObjectContext];
                if (arr.count > 0) {
                    Workout *workout = (Workout *)[arr firstObject];
                    workout.state = @"purchased";
                    [ApplicationDelegate.managedObjectContext MR_saveOnlySelfAndWait];
                }
                [[InAppPurchaseManager sharedManager] savePurchasedReadyProgram:productID];
            }

            if (!isOnce) {
//                UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:LocalizedString(@"Notice") message:LocalizedString(@"Purchased Item restored succesfully") delegate:self cancelButtonTitle:LocalizedString(@"Ok") otherButtonTitles: nil];
//                [alertView show];   
                isOnce = true;
            }

            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            [self refresh_purchaseBtn];
        }
        else if (transaction.transactionState == SKPaymentTransactionStateFailed) {
            //called when the transaction does not finish
            if(transaction.error.code == SKErrorPaymentCancelled){
                NSLog(@"Transaction state -> Cancelled");
                //the user cancelled the payment
            }
            [self hideProgressHud];
            isProgress = NO;
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        }
    }
}

你的代码看起来不正确。在
paymentQueueRestoreCompletedTransactionsFinished
中,您不应该做任何事情,除非在需要时更新您的UI。此方法表示恢复已完成,但实际恢复应通过检测
updatedTransactions
中的恢复状态来执行。在
updatedTransactions
中,您正在调用
finishTransaction
以获取
SKPaymentTransactionStatePurchased
状态,而不实际持续购买。基本上,
SKPaymentTransactionStatePurchased
SKPaymentTransactionStateRestored
的代码应该是相同的。您的意思是我应该移动[[SKPaymentQueue defaultQueue]finishTransaction:transaction];在paymentQueueRestoreCompletedTransactionsFinished to updatedTransactions中?您的代码看起来不正确。在
paymentQueueRestoreCompletedTransactionsFinished
中,您不应该做任何事情,除非在需要时更新您的UI。此方法表示恢复已完成,但实际恢复应通过检测
updatedTransactions
中的恢复状态来执行。在
updatedTransactions
中,您正在调用
finishTransaction
以获取
SKPaymentTransactionStatePurchased
状态,而不实际持续购买。基本上,
SKPaymentTransactionStatePurchased
SKPaymentTransactionStateRestored
的代码应该是相同的。您的意思是我应该移动[[SKPaymentQueue defaultQueue]finishTransaction:transaction];在paymentQueueRestoreCompletedTransactionsFinished到updatedTransactions中?