【问题标题】:InApp Purchase SKPaymentQueue finish Transaction doesn't work在应用程序购买 SKPaymentQueue finishTransaction 不起作用
【发布时间】:2012-06-13 05:22:00
【问题描述】:

我正在 iOS sdk 中进行应用内购买项目。我已经准备了应用内购买类,用于从应用商店购买应用并启用项目的内部内容。但是,我的问题是 SKPaymentQueue 没有完成我的类的工作。这里的代码我的应用内购买类:

- (void)purchase {
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    SKPayment *payment = [SKPayment paymentWithProductIdentifier:@"com.test"];
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    [[SKPaymentQueue defaultQueue] addPayment:payment];

}

- (void)provideContent:(NSString *)productIdentifier {

    NSLog(@"Toggling flag for: %@", productIdentifier);
    [[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:productIdentifier];
    [[NSUserDefaults standardUserDefaults] synchronize];
    //[_purchasedProducts addObject:productIdentifier];

    [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchasedNotification object:productIdentifier];

}

- (void)completeTransaction:(SKPaymentTransaction *)transaction {

    NSLog(@"completeTransaction...");

    //[self recordTransaction: transaction];
    [self provideContent: transaction.payment.productIdentifier];
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

}

- (void)restoreTransaction:(SKPaymentTransaction *)transaction {

    NSLog(@"restoreTransaction...");

    //[self recordTransaction: transaction];
    [self provideContent: transaction.originalTransaction.payment.productIdentifier];
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

}

- (void)failedTransaction:(SKPaymentTransaction *)transaction {

    if (transaction.error.code != SKErrorPaymentCancelled)
    {
        NSLog(@"Transaction error: %@", transaction.error.localizedDescription);
    }


    [[NSNotificationCenter defaultCenter] removeObserver:self name:kProductPurchaseFailedNotification object:transaction];


    [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchaseFailedNotification object:transaction];


    //[[NSNotificationCenter defaultCenter] postNotificationName:@"NotificationName" object:transaction];

    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

}



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

    for (SKPaymentTransaction *transaction in transactions) {

        switch (transaction.transactionState) {

            case SKPaymentTransactionStatePurchasing:

                break;

            case SKPaymentTransactionStatePurchased:
                [self completeTransaction:transaction];
                //[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

                break;

            case SKPaymentTransactionStateRestored:
                //[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                [self restoreTransaction:transaction];

                break;

            case SKPaymentTransactionStateFailed:
                if (transaction.error.code != SKErrorPaymentCancelled) {
                    NSLog(@"An error encounterd");
                }
                else {
                    NSLog(@"Cancelled!");
                }
                //[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

                [self failedTransaction:transaction];

                break;

        }

    }

}

- (void)dealloc
{
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];

    [request release];
    [super dealloc];

}

那行在我的课堂上不起作用[[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 事务未完成。 我的另一个问题是 nsnotificationcenter 调用多次,例如如果我第一次点击它只调用一次没问题,另一次是 nsnotificationcenter 调用 3 次。

【问题讨论】:

    标签: iphone ios xcode ios5


    【解决方案1】:

    我得到了解决方案,您的问题是 addTransaction 服务器与您的问题重复,

    试试下面的代码,它必须工作:

    static bool hasAddObserver=NO;
    
    - (void)purchase {
        if (!hasAddObserver) {//flag to fix this bug
            /*=====================================*/
            [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
            hasAddObserver=YES;
        }
        SKPayment *payment = [SKPayment paymentWithProductIdentifier:@"com.test"];
        //[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
        [[SKPaymentQueue defaultQueue] addPayment:payment];
    
    }
    
    
    - (void)provideContent:(NSString *)productIdentifier {
    
        NSLog(@"Toggling flag for: %@", productIdentifier);
        [[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:productIdentifier];
        [[NSUserDefaults standardUserDefaults] synchronize];
        //[_purchasedProducts addObject:productIdentifier];
    
        [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchasedNotification object:productIdentifier];
    
    }
    
    - (void)completeTransaction:(SKPaymentTransaction *)transaction {
    
        NSLog(@"completeTransaction...");
    
        //[self recordTransaction: transaction];
        [self provideContent: transaction.payment.productIdentifier];
        [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    
    }
    
    - (void)restoreTransaction:(SKPaymentTransaction *)transaction {
    
        NSLog(@"restoreTransaction...");
    
        //[self recordTransaction: transaction];
        [self provideContent: transaction.originalTransaction.payment.productIdentifier];
        [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    
    }
    
    - (void)failedTransaction:(SKPaymentTransaction *)transaction {
    
        if (transaction.error.code != SKErrorPaymentCancelled)
        {
            NSLog(@"Transaction error: %@", transaction.error.localizedDescription);
        }
    
    
    
    
        [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchaseFailedNotification object:transaction];
    
    
        //[[NSNotificationCenter defaultCenter] postNotificationName:@"NotificationName" object:transaction];
    
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    
    }
    
    
    
    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
    
        for (SKPaymentTransaction *transaction in transactions) {
    
            switch (transaction.transactionState) {
    
                case SKPaymentTransactionStatePurchasing:
    
                    break;
    
                case SKPaymentTransactionStatePurchased:
                    //[self completeTransaction:transaction];
                    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    
                    break;
    
                case SKPaymentTransactionStateRestored:
                    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                    //[self restoreTransaction:transaction];
    
                    break;
    
                case SKPaymentTransactionStateFailed:
                    if (transaction.error.code != SKErrorPaymentCancelled) {
                        NSLog(@"An error encounterd");
                    }
                    else {
                        NSLog(@"Cancelled!");
                    }
                    //[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    
                    [self failedTransaction:transaction];
    
                    break;
    
            }
    
        }
    
    }
    
    - (void)dealloc
    {
        [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    
        [request release];
        [super dealloc];
    
    }
    

    欢迎!

    【讨论】:

      【解决方案2】:

      要解决这个问题,只需添加[[SKPaymentQueue defaultQueue]removeTransactionObserver:self]; 紧随[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

      【讨论】:

        【解决方案3】:

        你可以这样做:

         - (void)buyProduct:(SKProduct *)product {
        
        NSLog(@"Buying %@...", product.productIdentifier);
        SKPayment * payment = [SKPayment paymentWithProduct:product];
        [[SKPaymentQueue defaultQueue] addPayment:payment];
        
         }
        
        
        - (void)validateReceiptForTransaction:(SKPaymentTransaction *)transaction {
        VerificationController * verifier = [VerificationController sharedInstance];
        [verifier verifyPurchase:transaction completionHandler:^(BOOL success) {
            if (success) {
                NSLog(@"Successfully verified receipt!");
                [self provideContentForProductIdentifier:transaction.payment.productIdentifier];
            } else {
                NSLog(@"Failed to validate receipt.");
                [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
        
            }
        }];
        }
        
        
        #pragma mark SKPaymentTransactionOBserver
        
        - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
        {
        for (SKPaymentTransaction *transaction in transactions) {
            switch (transaction.transactionState) {
                case SKPaymentTransactionStatePurchasing:
                    NSLog(@"Prossing.............");
        
                    break;
        
                case SKPaymentTransactionStatePurchased:
                {
        
                    [self completeTransaction:transaction];
                    NSError* error;
                    NSDictionary* jsonDict = [NSJSONSerialization
                                          JSONObjectWithData:transaction.transactionReceipt
        
                                          options:kNilOptions 
                                          error:&error];
                    NSLog(@"JSON Receipt: %@",jsonDict);
        
                    [[NSUserDefaults standardUserDefaults] setObject:jsonDict forKey:@"A"];
                    NSLog(@"Purchase was a Success.....");
                }
                    break;
                case SKPaymentTransactionStateFailed:
        
                    [self failedTransaction:transaction];
        
                    NSLog(@"Purchase cancelled");
        
        
                    break;
        
                case SKPaymentTransactionStateRestored:
        
                    [self restoreTransaction:transaction];
        
                    default:
        
                    break;
            }         
        }
        }
        
        
        
        - (void)completeTransaction:(SKPaymentTransaction *)transaction {
        NSLog(@"completeTransaction...");
        
        [self validateReceiptForTransaction:transaction];
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        }
        
        
        - (void)restoreTransaction:(SKPaymentTransaction *)transaction {
        NSLog(@"restoreTransaction...");
        
        [self validateReceiptForTransaction:transaction];
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        }
        
        
         - (void)failedTransaction:(SKPaymentTransaction *)transaction {
        
        NSLog(@"failedTransaction...");
        
        [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
        
        
        if (transaction.error.code != SKErrorPaymentCancelled)
        {
            NSLog(@"Transaction error: %@", transaction.error.localizedDescription);
            MedPulseAppDelegate *appdelegate =( MedPulseAppDelegate *)[[UIApplication sharedApplication]delegate];
            [appdelegate hideLoading];
        }
        
        [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
        }
        
        
        
         - (void)provideContentForProductIdentifier:(NSString *)productIdentifier {
        
        if ([productIdentifier isEqualToString:kMDPulseSubscriptionProductIdentifier]) {
            [self purchaseSubscriptionWithMonths:1];
         }
        
        [[NSNotificationCenter defaultCenter] postNotificationName:IAPHelperProductPurchasedNotification object:productIdentifier userInfo:nil];
        
          }
        
        
        
          - (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {
        NSLog(@"%s","User Cancel.");
        
        
        
          }
        
        
        
         - (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
         {
        NSLog(@"Restore completed transactions finished.");
        NSLog(@" Number of transactions in queue: %d", [[queue transactions] count]);
        for (SKPaymentTransaction *trans in [queue transactions])
          {
            NSLog(@" transaction id %@ for product %@.", [trans transactionIdentifier], [[trans payment] productIdentifier]);
            NSLog(@" original transaction id: %@ for product %@.", [[trans originalTransaction] transactionIdentifier],
                  [[[trans originalTransaction] payment]productIdentifier]);
        
        
            if ([[[trans payment] productIdentifier] isEqual: kMDPulseSubscriptionProductIdentifier]) {
        
                NSLog(@"Purchase Restored");
        
                // Do your stuff to unlock
            }
          }
         }
        
        
         - (void)restoreCompletedTransactions
         {
            NSLog(@"Restore Tapped in transaction process");
            [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
            [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
          }
        

        欢迎!
        如果你有任何疑问,请评论它

        【讨论】:

          猜你喜欢
          • 2011-05-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多