2

我正在iOS sdk中的inapp购买项目。我已经准备了inapp购买类,用于从appstore购买应用程序并启用项目的内部内容。但是,我的问题是SKPaymentQueue没有完成我的类的工作。这是我的inapp购买代码班级:

- (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 次。

4

3 回答 3

9

我得到了解决方案,您的问题是 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];

}

欢迎!

于 2012-06-13T05:50:43.663 回答
3

要解决此问题,只需在[[SKPaymentQueue defaultQueue]removeTransactionObserver:self]; 之后添加[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

于 2015-05-19T13:55:00.737 回答
0

你可以这样做:

 - (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];
  }

欢迎!
如果您有任何疑问,请将其评论下来

于 2014-09-01T12:08:32.473 回答