2012-06-13 2 views
2

iOS에서 inapp 구매 프로젝트를 진행 중입니다. sdk.i에서 프로젝트의 내부 내용을 활성화하여 appstore에서 app을 구매하기위한 inapp 구매 클래스를 준비했습니다.하지만 내 문제는 SKPaymentQueue입니다. 내 인앱 구매 클래스의 내 class.here의 코드 작업을 완료 :InApp Purchase SKPaymentQueue finish 거래가 작동하지 않습니다.

- (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 번 호출하는 것과 같습니다.

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

} 

에 오신 것을 환영합니다 :

답변

9

내가 당신의 문제가 addTransaction 서버가 문제에 코드 아래

시도 그것의 필수 가공 중복되는 솔루션을 가지고!

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

에 오신 것을 환영합니다!
당신은 의심의 여지가있는 경우 아래

2

이 문제를 해결하려면 단지 추가를 언급 [[SKPaymentQueue defaultQueue]removeTransactionObserver:self]; 바로 [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

관련 문제