iPhone などの iOSアプリにおいて、StoreKit 2を用いたリストア(復元)処理の検証に関して、筆者の体験を紹介する。
筆者のマシン | |
---|---|
Mac | mac mini (M1, 2020) |
OS | Monterey バージョン 12.4 |
XCode | バージョン 13.4.1 |
Swift | バージョン 5.6.1 |
ここでは次の手順で説明する。
- はじめに
- リストア(復元)ボタンの追加
- TestFlightでの検証
- App Storeで公開・動作確認
はじめに
iOSアプリの App内課金処理を StoreKit 2 で実装してApp Store の審査に提出した際、リストア(復元)のボタンを設置していないと言う理由で、Review での却下(Reject)を受けた。
理由は「Guideline 3.1.1 – Business – Payments – In-App Purchase」で、メッセージを日本語に訳すと、大まかには次のとおり。
余談だが、下記をざっと読んだ感じでは、私にはその必要性は認識できなかった。
・In-App Purchase Programming Guide の “Restoring Purchase Products” section
筆者が審査に提出したアプリは、起動時に最新の購入状況を読み込むものであったが、Rejectメッセージには次のステップが明記されていた。
内容を日本語に訳すと、大まかには次のとおり。
つまり、起動時に自動的に最新の購入アイテムを復元していても、明示的な”Restore”ボタンなどを設置することが求められた。
確かに、Implementing a store in your app using the StoreKit APIからDLできるサンプルアプリには、購入したアイテムを復元するための明示的なボタン「Restore Puchases」がある。
リストア(復元)ボタンの追加
rejectされたアプリにはアイテム購入画面があるのだが、その画面の下部の方に、「購入情報の復元(リストア)」と言うボタンを設けた。
そして、そのボタンがタップされたときの処理として、上記サンプルアプリのコードおよび AppStore.sync()のAPI を参考にして次の処理を追加した。
AppStore.sync()
// 加えて、この後ろに、最新の購入済みのアイテムを反映した画面を表示する処理を実装
TestFlightでの検証
動作確認のために、TestFlightへアプリをアップロードし、手元の2台の実機で動作の確認を行った。
流れは次のとおり。
- 実機AとBで、アイテム購入画面を表示させておく
- この時、いずれのアイテム購入画面でも、アイテムは未購入の状態である
- 実機Aにて、SandBoxテストユーザAでアイテムを購入する
- 筆者のアプリでは購入後に画面が更新され、購入済みであることが分かるようにしている。この時実機Aでは、期待していたように購入済みの画面となった
- 実機B(アイテム購入画面では、未購入の状態が表示されている)で、「購入情報の復元(リストア)」ボタンをタップする
- 認証ダイアログに従い、SandBoxテストユーザAで認証した
- 期待する結果は、購入済みのアイテムを反映した画面となることだった。しかし、画面の見た目は変化なし
ここで、APIの説明や先のサンプルアプリのコードを確認したが、実装に不足な点は見当たらなかった。
試しに、AppStore.sync()のエラーをcatchした際のログを画面に表示するようにして、TestFlightへアップして検証した。
上記3の「購入情報の復元(リストア)」ボタンをタップでは下記エラーが出ていることがわかった。
// 日本語では「リクエストを完了できません。」
TestFlight版アプリではSandBoxユーザを用いて検証したが、ネットでは一部挙動が怪しいと言う記事もあったので、本番のApp Storeでは動くと言う前提で、やむを得ず審査に提出をした。
ちなみに、上記3の後、実機Bで購入(復元ではない)を操作すると、認証後に「すでに購入済みです。無料で入手できます」と言う旨のメッセージが出て、購入済みであることが反映された。
App Storeで公開・動作確認
審査が通過したので、App Storeからリリース版をDLし、TestFlight版アプリで検証した上記操作を試した(この時は自分のApple IDで課金アイテムを購入)。
- 実機AとBで、アイテム購入画面を表示させておく
- この時、いずれのアイテム購入画面でも、アイテムは未購入の状態である
- 実機Aにて、アイテムを購入する(勿論、自分のApple IDで)
- この時実機Aでは、期待していたように購入済みの画面となった
- 実機Bで、「購入情報の復元(リストア)」ボタンをタップする
- 認証ダイアログに従い、自分のApple IDで認証した
- 期待の通り、画面が更新され、購入済みの画面となった
これらより、AppStore.sync()を呼び出すことにより、本番の App Store では適切に復元(リストア)できることが確認できた。
TestFlight検証時がたまたま良くなかったのか、SandBoxテストユーザではリストア検証できない仕様なのかは分からなかったが、
StoreKit2 でのリストア処理はAppStore.sync()で問題なし!と言うことが分かった。
以上