2016-10-27 9 views
0

今、次の問題に苦しんでいます。アプリケーションでAppStoreから商品を購入するためのシンプルなIAPManagerを作成しましたが、問題は - 商品を購入しようとすると、アプリケーションはメソッドを呼び出して、その商品を買いたい場合はPurchasedのアラートを表示しますものかどうかアップルストア製品を購入すると、購入時に「購入済み」状態になる

これは、アプリケーションの開始直前に購入しようとしている場合にのみ発生します。私がアプリケーションをリロードするまで、それは再び起こりません。私のIAPManagerコードは次のとおりです。

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

     NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; 
     _receipt = receiptURL.absoluteString; 
     NSLog(@"Receipt = %@", _receipt); 
    } 

    return self; 
} 

- (void)purchaseSmallCreditPackWithCompletion:(IAPManagerBlock)completionBlock failure:(IAPManagerBlock)failureBlock 
{ 
    [self makePurchaseWithId:iap_SmallCreditPack completion:completionBlock failure:failureBlock]; 
} 

- (void)purchaseMiddleCreditPackWithCompletion:(IAPManagerBlock)completionBlock failure:(IAPManagerBlock)failureBlock 
{ 
    [self makePurchaseWithId:iap_MiddleCreditPack completion:completionBlock failure:failureBlock]; 
} 

- (void)purchaseLargeCreditPackWithCompletion:(IAPManagerBlock)completionBlock failure:(IAPManagerBlock)failureBlock 
{ 
    [self makePurchaseWithId:iap_LargeCreditPack completion:completionBlock failure:failureBlock]; 
} 

- (void)makePurchaseWithId:(NSString *)idStr completion:(IAPManagerBlock)completionBlock failure:(IAPManagerBlock)failureBlock 
{ 
    if ([SKPaymentQueue canMakePayments]) { 

     _completionBlock = completionBlock; 
     _failureBlock = failureBlock; 

     SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:idStr]]; 
     productsRequest.delegate = self; 
     [productsRequest start]; 
    } 
    else 
    { 
     NSLog(@"This user can't make any payments"); 
    } 
} 

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response 
{ 
    if (response.products.count == 0) { 
     NSLog(@"There're no any products whatsoever"); 
     return; 
    } 

    SKProduct *product = [response.products firstObject]; 
    [self purchase:product]; 
} 

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

    [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 
    [[SKPaymentQueue defaultQueue] addPayment:payment]; 
} 

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions 
{ 
    SKPaymentTransaction *transaction = [transactions firstObject]; 

    switch (transaction.transactionState) { 
     case SKPaymentTransactionStatePurchasing: 

      NSLog(@"Purchasing %@...", transaction.payment.productIdentifier); 

      break; 
     case SKPaymentTransactionStateFailed: 
     { 
      NSLog(@"Failed to purchase %@", transaction.payment.productIdentifier); 

      if (_failureBlock) { 
       _failureBlock(); 
      } 

      [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
     } 
      break; 
     case SKPaymentTransactionStateRestored: 
     { 
      //just in case, we don't need to restore anything so far 
      if (_completionBlock) { 
       _completionBlock(); 
      } 

      [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
     } 
      break; 
     case SKPaymentTransactionStatePurchased: 
     { 

      NSLog(@"Purchased %@", transaction.description); 
      [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 

      NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; 
      NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL]; 
      NSString *strReceipt = [receiptData base64EncodedStringWithOptions:0]; 
      //NSLog(@"strReceipt = %@", strReceipt); 

     } 
      break; 
     default: 
      break; 
    } 
} 

- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray<SKPaymentTransaction *> *)transactions 
{ 
    NSLog(@"Removed Transactions"); 

    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; 
} 

答えて

1

あなたの問題はオブザーバーと関連していると思います。私が見ているように、あなたは製品を購入しようとするたびにトランザクションオブザーバを追加し、トランザクション(any)がトランザクションキューから削除されたときにトランザクションオブザーバを削除しようとします。

取引が完了せず、アプリが閉鎖された場合、アプリを開いたときにトランザクションの完了に関する通知が届きます。あなたはこの通知を受け取らず、あなたはそれを見逃します。

私は、オブザーバーをinitメソッドに追加することをお勧めします。これは、前に説明した理由でオブザーバーを削除しないでください。また、あなたのアプリケーション(didFinishLaunchingWithOptions :)を開いてトランザクションオブザーバを設定し、トランザクションの遅延通知を受け取るときに、IAPクラスのインスタンスを作成することをお勧めします。

もう1つ...最初のトランザクションだけでなく、トランザクションの配列を管理する必要があります。

あなたは、あなたが完全に正しい。この

for (SKPaymentTransaction *transaction in transactions) { 
    switch (transaction.transactionState) { 
      case SKPaymentTransactionStatePurchased: { 
      [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
      break; 
      } 
      case SKPaymentTransactionStateFailed: 
      [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
      break; 
      case SKPaymentTransactionStateRestored: 
      [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
      break; 
      case SKPaymentTransactionStatePurchasing: 
      break; 
      case SKPaymentTransactionStateDeferred: 
      break; 
      default: 
      break; 
    } 
}; 
+0

のようにそれらに対処するためのforループを作成する必要があります!ありがとうございました! –

関連する問題