2010-11-19 16 views
2

私のアプリケーションでIn App Purchaseを使用していますが、テストしているときに問題があります。私は4つの消耗品を持っています。 tableviewに示す商品に関する情報商品を購入するためにボタンをクリックすると、取引の状態がSKPaymentTransactionStateFailedupdatedTransactionになりますが、transaction.error localizedFailureReasonは常にnullです。 1回の取引が2回更新されたことがわかりました(updatedTransactionの機能取引で同じtransactionIdentifierがある場合、取引の状態はSKPaymentTransactionStatePurchasedです)。その商品は2回購入されましたか?iPhone In App購入の問題

だから私はどこに問題があるか分かりません。私を助けてください。私が作る関数didFinishLaunchingWithOptionsでAppDelegateで

@implementation InAppPurchaseManager 

@synthesize upgradeProducts; 
@synthesize productsRequest; 
@synthesize delegate; 

- (id) init 
{ 
    self = [super init]; 
    if (!self) return nil; 

    if ([SKPaymentQueue canMakePayments]) { 
     [self loadStore]; 
     [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 
    } 

    upgradeProducts = [[NSMutableArray alloc] init]; 
    delegate = nil; 

    return self; 
} 

+ (InAppPurchaseManager *) sharedInstance 
{ 
    static InAppPurchaseManager *myInstance = nil; 

    if (nil == myInstance) { 
     myInstance = [[[self class] alloc] init]; 
    } 

    return myInstance; 
} 

- (void) loadStore 
{ 
    NSSet *productsIdentifiers = [[NSSet alloc] initWithObjects:PRODUCT_1_ID, PRODUCT_2_ID, PRODUCT_3_ID, PRODUCT_4_ID, nil]; 
    [self requestUpgradeProductsData:productsIdentifiers]; 
     [productsIdentifiers release]; 
} 

- (void) requestUpgradeProductsData:(NSSet *) productIdentifiers 
{ 
    productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers]; 
    productsRequest.delegate = self; 
    [productsRequest start]; 
} 

- (void) productsRequest:(SKProductsRequest *) request didReceiveResponse:(SKProductsResponse *) response 
{ 
    [upgradeProducts removeAllObjects]; 

    for (int i = 0; i < [response.products count]; i++) { 
     SKProduct *product = [response.products objectAtIndex:i]; 

     UpgradeProduct *upgradeProduct = [[UpgradeProduct alloc] initWithProductID:product.productIdentifier]; 
     upgradeProduct.title = product.localizedTitle; 
     upgradeProduct.description = product.localizedDescription; 

     NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; 
     [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; 
     [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; 
     [numberFormatter setLocale:product.priceLocale]; 
     NSString *price = [numberFormatter stringFromNumber:product.price]; 
     [numberFormatter release]; 

     upgradeProduct.price = price; 

     [self.upgradeProducts addObject:upgradeProduct]; 

     [upgradeProduct release]; 
    } 

     [productsRequest release]; 

    if ([self.delegate respondsToSelector:@selector(didLoadStore:)]) 
     [self.delegate didLoadStore:self.upgradeProducts]; 
} 

+ (BOOL) canMakePurchases 
{ 
    if ([SKPaymentQueue canMakePayments]) 
     return YES; 
    else { 
     [Global showAlertViewWithTitle:NSLocalizedString(@"Payment Error", @"Payment Error Alert Title") 
              message:NSLocalizedString(@"You are not authorized to purchase from AppStore", @"Payment Error Alert Text when user cannot make payments from store")]; 
     return NO; 
    } 
} 

- (void) purchaseUpgrade:(NSString *) productIdentifier 
{ 
    if ([InAppPurchaseManager canMakePurchases]) { 
     SKPayment *payment = [SKPayment paymentWithProductIdentifier:productIdentifier]; 
     [[SKPaymentQueue defaultQueue] addPayment:payment]; 
    } 
} 

- (void) recordTransaction:(SKPaymentTransaction *) transaction 
{ 
    [[NSUserDefaults standardUserDefaults] setValue:transaction.transactionReceipt forKey:@"upgradeTransactionReceipt" ]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 
} 

- (void) finishTransaction:(SKPaymentTransaction *) transaction 
{ 
    [self paymentSucceeded:transaction]; 
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
} 

- (void) paymentSucceeded:(SKPaymentTransaction *) transaction 
{ 
    // provide content here 

    if ([self.delegate respondsToSelector:@selector(didFinishPaymentTransaction)]) 
     [self.delegate didFinishPaymentTransaction]; 
} 

- (void) completeTransaction:(SKPaymentTransaction *) transaction 
{ 
    [self recordTransaction:transaction]; 
    [self finishTransaction:transaction]; 
} 

- (void) restoreTransaction:(SKPaymentTransaction *) transaction 
{ 
    [self recordTransaction:transaction.originalTransaction]; 
    [self finishTransaction:transaction]; 
} 

- (void) failedTransaction:(SKPaymentTransaction *) transaction 
{ 
    if (transaction.error.code != SKErrorPaymentCancelled) { 
     NSMutableString *messageToBeShown = [[NSMutableString alloc] init]; 

     if ([transaction.error localizedFailureReason] != nil) { 
      [messageToBeShown setString:[NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"Reason:", @"Reason Text in alert when payment transaction failed"), [transaction.error localizedFailureReason]]]; 

      if ([transaction.error localizedRecoverySuggestion] != nil) 
       [messageToBeShown appendFormat:@", %@ %@", NSLocalizedString(@"You can try:", @"Text for sugesstion in alert when payment transaction failed"), [transaction.error localizedRecoverySuggestion]]; 
     } 

     [Global showAlertViewWithTitle:NSLocalizedString(@"Unable to complete your purchase", @"Payment transaction failed alert title") 
              message:messageToBeShown]; 

     [messageToBeShown release]; 

     if ([self.delegate respondsToSelector:@selector(didFailedPaymentTransaction)]) 
      [self.delegate didFailedPaymentTransaction]; 
    } else { 
     if ([self.delegate respondsToSelector:@selector(didCancelPaymentTransaction)]) 
      [self.delegate didCancelPaymentTransaction]; 
    } 

    [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
} 

- (void) paymentQueue:(SKPaymentQueue *) queue updatedTransactions:(NSArray *) transactions 
{ 
    for (SKPaymentTransaction *transaction in transactions) { 
     switch (transaction.transactionState) { 
      case SKPaymentTransactionStatePurchased: 
       [self completeTransaction:transaction]; 

       break; 
      case SKPaymentTransactionStateFailed: 
       [self failedTransaction:transaction]; 

       break; 
      case SKPaymentTransactionStateRestored: 
       [self restoreTransaction:transaction]; 

       break; 
      default: 
       break; 
     } 
    } 
} 

- (void) request:(SKRequest *) request didFailWithError:(NSError *) error 
{ 
    [Global showAlertViewWithTitle:NSLocalizedString(@"Payment Error", @"Payment Error Alert Title") 
     message:[NSString stringWithFormat:@"%@, %@", NSLocalizedString(@"Could not contact App Store properly", @"Alert text when request did fail"), 
       [error localizedDescription]]]; 
} 

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

    [upgradeProducts release]; 

    if (productsRequest) 
     productsRequest = nil; 

    [super dealloc]; 
} 

@end 

こと:私はアプリ内購入で管理するために、そのクラスを使用

:購入ビューで

[InAppPurchaseManager sharedInstance]; 

私は私が作るボタンをクリックしてください

UpgradeProduct *selectedProduct = [self.faxProducts objectAtIndex:[purchaseButton.identifier intValue]]; 

if (selectedProduct) { 
    [[InAppPurchaseManager sharedInstance] purchaseUpgrade:selectedProduct.productID]; 
} 

答えて

0

AppIDを正しく使用してください。私は同じ問題を「ユーザーがキャンセル」していたし、両方とも正しいIDでトランザクションを呼び出すことはなかった。私は自動的にcom.mycompany.product "という接頭辞をコードに追加しますが、場合によってはcom.mycompany.productが既に追加されていました...ルーキーバグ...

0

私は間違った製品識別子。

1

私は同じ問題を抱えている、観察者は常に2トランザクションを持っています。でも、私は[[SKPaymentQueue defaultQueue] addPayment:payment]を削除し、それはまだ1つのトランザクションを持っている。だから私は「canMakePayments」

私は[SKPaymentQueue canMakePayments]を削除した後、問題が解決するように見えるが疑われます。なぜあなたはそれを解決するかもしれないのか分かりません。

2
[[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 

このコードは間違っています。複数回使用することはできません。オブザーバーを2回追加すると、1回のトランザクションが2回更新されることがわかります。

+0

あなたは私の時間を節約しました。たくさんありがとうございます... – girish

1

テストしているだけの場合は、個人アカウントからログアウトして、iTunesConnectで新しいテストアカウントを作成してください。

テストユーザーを使用しないと、奇妙なことに失敗します。 APIはほとんど説明がない黒い魔法でいっぱいです。

+0

大きな答えは私の問題を解決しました – Curnelious