
StoreKit 2を使ってアプリ内課金を行う際、Product.purchase() メソッドの戻り値として登場するのが PurchaseResult です。
この PurchaseResult は、ユーザーが課金操作を行った結果を表す列挙型(enum)で、成功・キャンセル・保留など、結果の種類を的確に表現してくれます。
この記事では PurchaseResult の基本的な意味や種類、それぞれの使い分けや注意点、活用のポイントをわかりやすく解説します。
PurchaseResultとは?
PurchaseResult は StoreKit 2 において、Product.purchase() メソッドの戻り値として使われる列挙型(enum)です。
この値を確認することで、課金が成功したのか、ユーザーがキャンセルしたのか、それとも購入が保留状態にあるのかなど、ユーザーのアクション結果を安全に判断することができます。
定義と種類
PurchaseResult は以下のようなケースを持つ enum です。
|
1 2 3 4 5 |
enum PurchaseResult { case success(VerificationResult<Transaction>) case userCancelled case pending } |
| ケース名 | 意味 | 処理のポイント |
|---|---|---|
| success(VerificationResult) | App Storeが購入応答を返した | .verified の場合のみ処理を進める |
| userCancelled | ユーザーが購入をキャンセル | 何もしなくてよい |
| pending | 購入が承認待ちで保留中 | 機能を反映せず、承認を待つ |
それぞれのケースについて詳しく見ていきましょう。
success(VerificationResult)
課金が一見成功したように見える場合に返されます。
しかし、このsuccessは単にApp Storeから購入結果を取得したという意味。
実際に購入できているかは、この中に入っている VerificationResult<Transaction> を使って、本当に正当な購入かどうかを検証する必要があります。
|
1 2 3 4 5 6 7 8 9 10 11 |
switch result { case .success(let verification): switch verification { case .verified(let transaction): // 正常な購入として処理する await transaction.finish() case .unverified(_, let error): // 不正な可能性あり → 機能をアンロックしない print("検証失敗: \(error)") } |
繰り返しになりますが、.success はあくまで「App Storeからレスポンスが返ってきた」という意味であり、必ずしも信頼できる購入とは限らない点が重要です。
ちなみにsuccess(let verification) はenum のケースに含まれている「関連値(associated value)」を取り出している書き方 です。
.success というケースには、追加で VerificationResult<Transaction> という値が入っており、let verification で、その中身を変数として受け取っている、という流れです
userCancelled
ユーザーが購入確認ダイアログで「キャンセル」を選んだ場合に返されます。
この場合は何も購入処理は行われておらず、アプリ側でも特に処理をする必要はありません。
ただし、ログを残しておくことでユーザー行動の分析に役立つこともあります。
|
1 2 3 |
case .userCancelled: print("ユーザーが購入をキャンセルしました") |
pending
購入が保留状態の場合に返されます。
たとえば、ペアレンタルコントロールが設定されていて承認待ちの場合や、ファミリー共有の支払い承認が必要なケースが該当します。
この状態ではまだ購入は確定していないため、アプリ側で即座に機能をアンロックすることは避けるべきです。
|
1 2 3 |
case .pending: print("購入が保留中です。承認をお待ちください。") |
活用シーン
PurchaseResult は以下のような場面で活躍します。
- 課金成功後に機能をアンロックする(.success + .verified の確認)
- キャンセル時にUI上で通知する
- ペンディング時に注意喚起のメッセージを表示する
- ログやエラートラッキングに課金結果を記録する
特に、StoreKit 2では非同期処理と組み合わせて使うのが基本です。
注意点
StoreKit を使った購入処理では、トランザクションの状態ごとに適切な対応を取る必要があります。特に以下のポイントは重要です。
.successの中に含まれるVerificationResultは必ず確認する
→ 検証に失敗した場合は、不正な購入や改ざんの可能性があるため処理を中止します。.pendingは購入未成立の状態
→ 保留中のため、アイテムをすぐに付与したり機能を解放したりしてはいけません。.userCancelledはユーザーが自分でキャンセルした状態
→ アプリ側で特別な処理は不要ですが、エラーメッセージを出すのではなく、静かに終了させるとユーザー体験を損ないません。
購入処理は、「成功かどうか」だけでなく「検証」「保留」「キャンセル」など複数のケースを想定して分岐処理を用意しておくことが重要です。
まとめ
PurchaseResult はアプリ内課金の処理結果を表す重要な値です。
ケースごとの意味とポイントを理解することで、安全で快適な課金体験を実現できます。
| ケース名 | 意味 | 処理のポイント |
|---|---|---|
| success(VerificationResult) | App Storeが購入応答を返した | .verified の場合のみ処理を進める |
| userCancelled | ユーザーが購入をキャンセル | 何もしなくてよい |
| pending | 購入が承認待ちで保留中 | 機能を反映せず、承認を待つ |
PurchaseResult を正しく理解して扱うことで、アプリ内課金の信頼性やユーザー体験を大きく向上させることができます。
StoreKit 2を使う際は、この戻り値を丁寧にハンドリングすることが重要です。

