iOSアプリ内課金での
非消耗型プロダクトが複数あるときの実装について、質問です。
ネット上や書籍での実例は、調べた限りプロダクトが「広告非表示機能」といった一つの場合の実装ばかりで
実際は他のプロダクトも販売することになると思いますが
一つのプロダクトを選択し購入しようとすると、すべてのプロダクトに対し購入処理が走ってしまって困っております。
###現状
私の認識では、まずプロダクト一覧を取得するためviewDidLoadなどで以下を実装。
(一覧で表示するための価格を、ローカルでの価格表示とするため直書きでなく以下から取得しています)
lang
1SKProductsRequest *productRequest; 2NSSet *productIds = [NSSet setWithObjects:kPurchasedProductAdVisible, kPurchasedProductSendCSV, nil]; 3productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIds]; 4productRequest.delegate = self; 5[_productRequest start];
上記メソッドを呼ぶことで、以下が走る
lang
1- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response 2{ 3//ここでプロダクト情報を取得し保持しておく 4 for (SKProduct *product in response.products) { 5 if([product.productIdentifier isEqualToString:@"com.companyName.AppName.productA"]){ 6 productA = product; 7 } 8 if([product.productIdentifier isEqualToString:@"com.companyName.AppName.productB"]){ 9 productB = product; 10 } 11 } 12//また、ここでテーブルなどにプロダクト情報を表示(価格はNSNumberFormatterと通しているとする) 13cellA.textLabel.text = @"productA"; 14cellA.detailTextLabel.text = [numberFormatter stringFromNumber:productA.price]; 15 16//また、以下をどこで呼ぶかが曖昧でしたが、ひとまずここで呼んでいます 17[[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 18}
そして、実際に各プロダクトを購入する
TableViewCell上に乗せたボタンをクリックするとして、以下メソッドを実装
lang
1- (void)clickedProductA 2{ 3 if([self canMakePurchases]){//購入が機能制限されていないかチェック 4 //プロダクトを指定してaddPaymentに渡す 5 SKPayment *payment = [SKPayment paymentWithProduct:productA]; 6 [[SKPaymentQueue defaultQueue] addPayment:payment]; 7 } 8}
上記でaddPaymentすると、下記が呼ばれる
lang
1- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions 2{ 3 for (SKPaymentTransaction *tr in transactions) { 4 switch (tr.transactionState) { 5 case SKPaymentTransactionStatePurchasing: 6 //処理中 7 break; 8 case SKPaymentTransactionStatePurchased: 9 //購入成功 10 [self success:tr]; 11 [queue finishTransaction:tr]; 12 break; 13 case SKPaymentTransactionStateFailed: 14 //エラー 15 16 break; 17 case SKPaymentTransactionStateRestored: 18 //リストア完了 19 [queue finishTransaction:tr]; 20 break; 21 } 22 } 23}
上記、トランザクションが呼ばれ、購入成功時にsuccessというメソッドを呼ぶようにしており
プロダクトを判別して、UserDefaultsなどに購入済みであるフラグを保存しています
lang
1- (void)success:(SKPaymentTransaction*)transaction 2{ 3 if ([transaction.payment.productIdentifier isEqualToString:@"com.companyName.AppName.productA"]) { 4 [[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"productA"]; 5 }else if([transaction.payment.productIdentifier isEqualToString:@"com.companyName.AppName.productB"]){ 6 [[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"productB"]; 7 } 8}
そして、すべてのトランザクションが終了したらオブザーバを削除
lang
1- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions 2{ 3 [[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; 4 5}
###挙動
上記にて、productAを購入するボタンをタップし、「producAを購入しますか?」というアラートが表示され、その後
Apple IDのパスワードを入力します。すると
すぐ後に「producBを購入しますか?」というアラートが表示されてしまいます。
おそらく上記で実装しているコードの認識が間違っているのですが、
お分かりの方がおりましたら、間違いの箇所をご指摘いただけませんでしょうか。
宜しくお願い致します。
あなたの回答
tips
プレビュー