2012年7月9日月曜日

iOS: In App Purchase、Restore処理のハマりポイント

先日、バージョンアップのためにSubmitしていたPuppet Camがリジェクトされてしまいました。

理由は、In App PurchaseでNon-Consumableなアイテムを購入したお客様に対して、別デバイスなどからリストアできるように、リストアボタンが用意されていないというものでした。

リストア機能は、再度、購入ボタンを押してもらえれば、2重課金にならずに済むようになってはいるのですが、お客様にとっては2重課金されないかな?と不安に思うのはもっともなので、このリジェクトは致し方無いです。

ただし同様の実装でも、リジェクトされる場合とされない場合があり、この辺りの審査はいつも微妙です。

今回は、リストアボタン実装中に、ひとつハマりポイントを見つけたので書いておきます。



リストア処理の概要

過去に購入したNon-Consumableアイテムのリストアは、以下のメソッドで行います。
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
addPaymentメソッドで、購入プロダクトをキューに与えた時と同様、非同期でトランザクション結果を受け取ります。
トランザクション結果は、以下のデリゲートメソッドで受け取ります。
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions;
リストアに成功したトランザクションステータスは、
SKPaymentTransactionStatePurchasedではなく、
SKPaymentTransactionStateRestoredになります。

リストア完了コールバックの注意点

注意したいのは、このupdatedTransactionsメソッドが呼ばれた後、リストアが成功か失敗かによって、以下のメソッドどちらかがコールバックされることです。
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue;
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error;
言い換えると、上記のメソッドがコールバックされるまで、全購入済みプロダクトのリストアは終了していないということになります。推測ですが、再度、updatedTransactionsメソッドがコールされる場合もあるかもしれませんので、注意しておきたいところです。

という訳で、updatedTransactionsの処理の中で、決め打ちでリストア処理を終了してはいけません。
updatedTransactionsの中で、
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
としていると、上記どちらかのコールバックが受け取れなくなってしまいます。

コールバックを受け取らないと、どうなるのでしょうか?
実はしっかり残っていました。僕の環境でテストした結果、次回課金処理テストをした時に、ひょっこり前回分のコールバックがされました。
これは頭が混乱します。

デバッグの際には注意して下さい。

関連記事

0 件のコメント:

コメントを投稿

Related Posts Plugin for WordPress, Blogger...