目次
概要
アプリ内サブスクリプションのロジックを修正したら、購入フローを実際に目で確認したくなります。しかし、実機とサンドボックスアカウントを用意するのは手間がかかり、シミュレーターでそのまま実行すると商品の取得から失敗したり、Apple アカウントのログイン画面が表示されたりします。
Xcode の StoreKit Configuration ファイル を使うと、App Store に接続せずにローカルで疑似ストアを動かせます。商品の取得、購入シート、購入の復元がすべてシミュレーター内で動作し、購入しても実際には課金されません。
このブログでは、Flutter アプリ(in_app_purchase パッケージ)の自動更新サブスクリプションをこの方法でテストした過程を整理します。
シミュレーターで確認できることとできないこと
まず範囲をはっきりさせておきます。StoreKit Configuration ファイルで作った取引は、Apple ではなく Xcode がローカルで署名 します。そのため、アプリがレシートを自前のサーバーに送って Apple に検証する構成の場合、サーバー検証は通りません。
確認できること
- 商品情報の取得と価格の表示
- 購入シートの表示、購入のキャンセル、ローカルでの購入成功
- 購入の復元(
restorePurchases())の呼び出しとその結果(サブスクリプションがない場合の案内など) - アプリ起動時にバックグラウンドで復元を呼び出しても、ダイアログやログイン画面が表示されないか
確認できないこと
- サーバー検証を通過した後のフロー(サブスクライバーとしての表示、再インストール後の自動復旧など)
- 実際の App Store アカウント・サンドボックス環境での動作
後者は実機とサンドボックスアカウントで別途確認する必要があります。
StoreKit Configuration ファイルを作成する
Flutter プロジェクトの ios/Runner.xcworkspace を Xcode で開きます。メニューから File › New › File from Template… を選び、検索欄に storekit と入力すると StoreKit Configuration File テンプレートが表示されます。

Next を押すと、ファイル名と保存場所を決めます。このとき、次の 2 点を確認します。
- Sync this file with an app in App Store Connect: チェックすると、App Store Connect に登録済みの商品を取り込みます。Xcode に開発者アカウントでログインしている必要があります。このブログではチェックせず、商品を直接追加しました。
- Targets:
Runnerターゲットは チェックを外します。このファイルはテスト用の設定なので、アプリバンドルに含める必要はありません。
サブスクリプション商品を追加する
作成した .storekit ファイルを開き、エディター左下の + ボタンから Add Auto-Renewable Subscription を選びます。サブスクリプショングループ名を決めると、グループ内にサブスクリプション商品が 1 つ作られます。

右側で次の項目を入力します。
| 項目 | 値 |
|---|---|
| Reference Name | 管理用の名前(例: Monthly) |
| Product ID | アプリのコードで取得する商品 ID と 完全に同じ値 |
| Subscription Duration | 更新周期(例: 1 Month) |
| Price | 表示する価格(例: 3.00) |
スクリーンショットの product.id は例の値です。ここには、アプリが InAppPurchase.instance.queryProductDetails() で取得する実際の商品 ID を入力します。値が異なると商品の取得結果が空になり、購入画面を開けません。
スキームに設定する
メニューから Product › Scheme › Edit Scheme… を開き、左側で Run を選んで Options タブに移動します。StoreKit Configuration のドロップダウンから、先ほど作成したファイルを選択します。

ファイル名が 赤い文字 で表示される場合は、Xcode がそのパスでファイルを見つけられていません。この状態で実行すると設定が適用されず、シミュレーターが実際のストアに接続しようとするため、Apple アカウントのログイン画面が表示されることがあります。下の 注意点 を参考にファイルをプロジェクトに追加してから、もう一度選択します。
実行して確認する
シミュレーターを選び、Xcode の ▶ ボタンでアプリを実行します。このブログでは Xcode から実行して確認しました。
アプリで購入ボタンを押すと、Xcode と表示された購入確認シートが表示されます。ログイン画面ではなくこのシートが表示されれば、StoreKit Configuration が正しく適用されています。シートには「For testing purposes only. You will not be charged…」という文言も表示されます。

Subscribe を押すと、[Environment: Xcode] と書かれた完了通知が表示されます。

このほかに、今回確認したシナリオは次のとおりです。
- アプリ起動時のサイレント復元: アプリを初めて起動して数秒待っても、ダイアログやログイン画面が表示されない。シミュレーターでアプリを削除して再度実行すれば、再インストールの状況も作れる。
- 購入のキャンセル: 購入確認シートを閉じても、エラーなく元の画面に戻る。
- ユーザーによる購入の復元: サブスクリプションがない状態で「購入の復元」を押すと、サブスクリプションがない旨の案内が表示される。
- 購入後のサーバー検証: ローカルでの購入は成功するが、サーバー検証を通過できないため、アプリはサブスクライバーに切り替わらない。前述の制限のとおり。
Manage Transactions で取引を扱う
アプリの実行中に Debug › StoreKit › Manage Transactions… を開くと、シミュレーターで発生した取引の一覧を確認できます。

ここで取引を選んで削除したり、返金処理したりできます。テストを最初からやり直したいときは、取引を削除すると「一度も購入していないユーザー」の状態に戻ります。
取引の横に ⚠ アイコンが付いている場合、選択すると次のメッセージが表示されます。
This transaction has not been finished by calling finish()
アプリがまだ取引を完了していないという意味です。in_app_purchase では、completePurchase() を呼び出すことで iOS 側の finish() が呼ばれます。サーバー検証が終わった後に completePurchase() を呼び出すアプリの場合、検証が終わるまではこのように未完了のまま残ります。完了していない取引は、次回の起動時に iOS がアプリへ再度届けます。
注意点
ファイルのパスが赤い文字のとき
スキームファイル(.xcscheme)を手で編集してパスを入れると、パスの書き方が合わずに赤い文字になることがあります。その場合は、Xcode 左側の Project Navigator で Runner フォルダを右クリックして Add Files to “Runner”… を選ぶか、Finder から .storekit ファイルを Runner フォルダにドラッグ&ドロップしてプロジェクトに追加します。その後、スキームの StoreKit Configuration でファイルを選び直すと、通常の色に戻ります。
意図しない変更が発生することがある
ファイルを Xcode で追加すると、次の変更が一緒に発生することがあります。
- 追加時のオプションによっては、ファイルがプロジェクトフォルダに コピー される。
- Xcode がそのファイルを git の コミット対象に自動で追加 する。
- ターゲットのチェックが入っていると、
.storekitファイルがアプリバンドルのリソースに含まれ、project.pbxprojが変更される。このとき Xcode がプロジェクトファイルの形式(objectVersionなど)まで一緒に変えることもある。
ローカルのテスト用設定をチームのリポジトリに上げたくない場合は、テストが終わった後に git status で変更を確認し、元に戻します。
git status --short
git checkout -- ios/Runner.xcodeproj/project.pbxproj
git checkout -- ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
逆にチームで共有したい場合は、ターゲットのチェックを外した状態で .storekit ファイルとスキームの変更をコミットしておく方法もあります。
まとめ
- StoreKit Configuration ファイルを作り、アプリと同じ商品 ID でサブスクリプション商品を追加する。
- Edit Scheme › Run › Options の StoreKit Configuration に設定する。赤い文字ならファイルを見つけられていない。
- 購入シートに Xcode と表示されれば、ローカルストアで動作している。
- 商品の取得、購入・キャンセル、購入の復元、起動時のバックグラウンド復元はシミュレーターで確認できる。
- 取引が Xcode の署名なので、サーバーでのレシート検証は通らない。その後のフローは実機とサンドボックスアカウントで確認する。
- Manage Transactions で取引を削除・返金して状態を戻せる。⚠ の表示は
finish()がまだ呼ばれていない取引である。
私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!
アプリ広報
Dekuが開発したアプリを使ってみてください。Dekuが開発したアプリはFlutterで開発されています。興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。