2016-10-27 1 views
0

바로 지금 다음 문제로 고민하고 있습니다. 내 응용 프로그램에서 AppStore에서 물건을 구입하기 위해 간단한 IAPManager를 만들었지 만 문제는 - 제품을 구입하려고 할 때 응용 프로그램에서 updatedTransactions 메서드를 사용하여 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 클래스의 인스턴스를 만들어 트랜잭션 관찰자를 설정하고 이러한 트랜잭션 지연 알림을 받도록 제안합니다.

한 가지 더 ... 첫 번째 트랜잭션뿐만 아니라 일련의 트랜잭션을 관리해야합니다.

당신은 당신은 완전히 맞아이

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

처럼 처리하는 루프를 작성해야합니다! 고맙습니다! –

관련 문제