[AppStore][Swift] Receipt の Local Validation

以前にも Receipt の on-device(local) での validation 方法を説明しましたが、もっと便利なライブラリがありましたので、紹介します

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Monterery beta 4
  • Xcode 13 beta3
  • iOS 15 beta

In-App Purchase の receipt

In-App Purchase を実装すると、Receipt の Validation について自前で実装する必要が発生します。

自分で実装するのは、大変なので、以前は、Swifty Local Receipt Validator というものを紹介しました。

きちんと動作したのですが、自分で OpenSSL のライブラリを組み込んだり、Apple の Certification をとってきたりで少し手間がかかりました。

その時の紹介記事はこちら
[SwiftyStoreKit] SwiftyStoreKit覚書(レシピValidate編)[SwiftyStoreKit] SwiftyStoreKit覚書(レシピValidate編)

すべてお任せで用意されているライブラリを見つけたので紹介します。

注意 その1
Apple の Certificatin 等を、言われるがままに 本来の場所以外から入手して使うことは非常に危険です。念の為 Apple の提供するものと置き換えて使うのがおすすめです。
注意 その2
Crack 対策を行いたいならば、リソースとして保持しているファイルのチェック等も必要になってきます。Crack 対策をどこまでやるかは、別途 判断が必要です。

TPInAppReceipt

こちらの TPInAppReceipt というライブラリが便利です。

すでに、OpenSSL のライブラリや Apple の certification ファイルも組み込まれています。念の為含まれているものを、確認の上、使うようにしてください。

Receipt の確認方法

Receipt の取得

TPInAppReceipt 内部で自動取得はしないので、自分で取得する必要があります。


        let receiptRefreshRequest = SKReceiptRefreshRequest()
        self.receiptRefreshRequest = receiptRefreshRequest
        receiptRefreshRequest.delegate = self
        receiptRefreshRequest.start()

上記のようにすると、Receipt 更新完了時に、Delegate の requestDidFinish が呼び出されますので、そのタイミングで Receipt の Validation を行い、その結果に応じてアプリの状態を更新します。

Receipt の確認

TPInAppReceipt を使用すると、非常にシンプルに処理できます。verity をコールするだけです。


        do {
            // (1)            
            let receipt = try InAppReceipt.localReceipt()
            // (2)
            try receipt.verify()
            // (3)
            for purchase in receipt.purchases {
                // check past purchase
            }
        // (4)
        } catch IARError.validationFailed(reason: .hashValidation) {
            print("hashValidation error")
          // Do smth
        } catch IARError.validationFailed(reason: .bundleIdentifierVerification) {
            print("bundleIdentifierVerification error")
          // Do smth
        } catch IARError.validationFailed(reason: .signatureValidation) {
            print("signatureValidation error")
          // Do smth
        } catch {
            print("error")
        }
コード解説
  1. ローカルにある Receipt を取得します
  2. Receipt を Validation します
  3. (必要に応じて) Receipt に含まれる 購入履歴をチェックします
  4. Validation 結果に応じた Exception を処理します。

その後にやるべきこと

receipt の中の purchases というプロパティに、TPInAppReceipt で定義されている InAppPurchase という購入履歴が保存されています。

この購入履歴をチェックすることで、過去に購入済みかどうかや 期間が切れているかどうか 等をチェックすることが可能となります。

まとめ:Receipt の Validation

Receipt の Validation
  • TPInAppReceipt を使うと、verify メソッド1つでチェックできる
  • Receipt は、自分で取得してこなければならない
  • あくまで Receipt の Validation なので、その後の処理の実装は必要

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です