iOS In App Purchase(Observer)
In App Purchaseの実装を順に追っていきます。今回は, In App Purchaseの内部処理です。
In App Purchase では, 諸処の処理を, SKPaymentTransactionObserver が面倒を見てくれます。
具体的には, 処理の成功, 処理の失敗,
といったところをObserve 観察して知らせてくれるというものです。App Storeなどとのやり取りは,
処理手順
- 購入ボタンをクリック
- SKProductsRequestでリクエストを発行
- Apple側の処理
- SKPaymentTransactionObserverでAppleの処理を受け取る
- 購入後の処理など
といった具合です。会計処理などはApple側が全部やってくれるので, あとは前後の処理を書いていくのみです。
SKProductsRequestは長くなるので別の部分でやるとして, 今回は会計後の処理を行います。
SKPaymentTransactionObserverの拡張クラスを作成して独自の処理を入れる
まずここからです。
PurchaseObserver.h
@interface PurchaseObserver : NSObject<SKPaymentTransactionObserver> @end
PurchaseObserver.m
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
// In case of restore, invokes multiple times
for ( SKPaymentTransaction *transaction in transactions )
{
switch ( transaction.transactionState )
{
case SKPaymentTransactionStatePurchasing:
// In process
break;
case SKPaymentTransactionStateFailed:
// Fail and cancel
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
// Restore
[self restoreTransaction:transaction];
break;
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
}
}
}
-(void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions
{
// Done
}
-(void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
// All Restore Done
}
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
// Error restore
}
-(void)completeTransaction: (SKPaymentTransaction *)transaction
{
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
// Purchased
}
-(void)failedTransaction: (SKPaymentTransaction *)transaction
{
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
// Failed
switch ([transaction.error code])
{
case SKErrorUnknown:
// Unknown
break;
case SKErrorClientInvalid:
// Client Invalid
break;
case SKErrorPaymentCancelled:
// Canceled
break;
case SKErrorPaymentInvalid:
// Payment Invalid
break;
case SKErrorPaymentNotAllowed:
// Not allowed
break;
default:
break;
}
}
-(void)restoreTransaction: (SKPaymentTransaction *)transaction
{
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
//
}
実際に実装すべきは, paymentQueueとpaymentQueueRestoreCompletedTransactionsFinishedの処理です。
| Method | 説明 |
|---|---|
| -(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions | 処理の経過,もしくは結果がかえってきます |
| -(void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions | 処理が終了したとき,つまりQueueから取り除かれたときの共通処理 |
| -(void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue | リストアすべてが終了した場合 |
| – (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error | リストアがキャンセルされた場合 |
購入の状態により処理
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
ですが, ここに処理の種類に応じて結果がかえってきます。
これは1つの処理を行います。複数の処理を同時に発行している場合それぞれの処理がここに落ちてきます。
| 処理状態 | 説明 |
|---|---|
| SKPaymentTransactionStatePurchasing | 購入中(経過がかえってきます) |
| SKPaymentTransactionStateFailed | 失敗 |
| SKPaymentTransactionStateRestored | リストア成功 |
| SKPaymentTransactionStatePurchased | 購入成功 |
[[SKPaymentQueue defaultQueue] finishTransaction:transaction]
処理の終了後必ず呼びます。
呼ぶと処理がQueueから排除され終了となります。残っていると延々と処理をすることになります。
失敗した理由による場合分け
ここでは-(void)failedTransaction: (SKPaymentTransaction *)transactionで処理をしています。
SKPaymentTransaction には, エラーコードがあるので, 場合分けが可能です。
作成•登録
このクラスをどこで作成するかというと, まあAppDelegateが妥当なところかと思います。
AppDelegate.h
@interface AppDelegate : UIResponder <UIApplicationDelegate> @property (nonatomic, strong) PurchaseObserver *pobserver; @end
AppDelegate.m
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.pobserver = [[PurchaseObserver alloc] init];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self.pobserver];
}
SKPaymentQueue に, observerを登録します。これでPaymentの処理をobserveしてくれます。
その後の処理
購入後の処理は,いろいろありますよね。データベースの変更とかでしょうか。
コンテンツなどのダウンロードでレシート使いたい場合もあるでしょう。
SKPaymentTransaction にはそのような購入情報がありますので, これを処理していきます。

There is One Comment.