はじめてのRevenueCat - (2) ダッシュボードでの設定と実装

前回の記事「[はじめてのRevenueCat - (1) SDK稼働確認に必要なApp Store Connectでの対応](https://qiita.com/maktag/items/072a137e73be49a7456f)」の内容までの手順が終わっている前提で、RevenueCat側の管理画面での設定とSDK実装をまとめます。
Paywallの表示をアプリ内で行うところまでを解説します。

## RevenueCat での設定手順

### 1. Projectの作成

Projectには複数のAppが追加が可能で、課金・サブスクリプションの管理が行えます。Collaboratorsとして、自分以外の人にも管理画面へのアクセス権限を与えることもProject単位で可能です。

### 2. Appの追加

ProjectにAppを追加します。ここで、前回の記事で取得している以下の情報を入れてAppを追加します。
- App Bundle ID
- App Store Connect App-Specific Shared Secret
- In-app purchase key configuration
    - P8 key file (`SubscriptionKey_XXXXXXXXXX.p8`)
    - Issuer ID
- App Store Connect API 
    - P8 key file (`AuthKey_XXXXXXXXXX.p8`)
    - Issuer ID
    - Vendor Number

### 3. Productsの登録

Productsを登録しますが、自分で入力しなくても、AppStore Connectに設定してあるサブスクリプションをImportできるので、非常に楽です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73759/18e567ac-d8ad-17c1-583e-59fcacd736bc.png)

### 4. Entitlementの登録

Entitlementを作成し、先ほどインポートしたProductsを紐付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73759/16d78ae0-04d9-f850-85e2-8bcb81533e86.png)

Entitlementとは、料金プランのレベルのようなものです。Netflixでいうと「スタンダード」「プレミアム」という区分けと同じものと考えるのがわかりやすいかと思います。

### 5. Offeringの設定

Offeringを設定し、PackageとしてProductsを紐づけます。
Packageが「年払い」「月払い」などの単位でProductsをまとめたものになります。例えば、iOS版/Android版の両方を持つアプリの場合には、Productも2つに分かれてしまうので、これをPackageとしてまとめています。
このPackageをOfferingとしてまとめることで、Paywallで扱いたいサブスクリプション／課金一覧となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73759/33a5697f-9a53-2a19-6d5a-4d05dab2f7c2.png)

### 6. Paywallsの作成
Paywallsを作り、 Offeringを紐づけたのち、Paywallの設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73759/01a93bf8-e4a9-8a32-d004-b65d1009a94d.png)

設定方法の詳細はこちらにガイドがあります。
[Creating Paywalls](https://www.revenuecat.com/docs/tools/paywalls/creating-paywalls)

## Xcodeでの実装手順

ここまで準備されていれば、Xcodeでの実装自体は難しくありません。

### 1. Swift UIでRevenue Cat SDKをインストール
Swift Package Managerでインストールする場合、`Files > Add Package Dependencies...` の画面で、`https://github.com/RevenueCat/purchases-ios-spm.git` で検索し、出てきた`purchases-ios-spm`を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73759/5eda3699-eb9a-65e5-afce-fd395635d78d.png)

そうすると、4つのPackage Productsが表示されますが、`RevenueCat` と `RevenueCatUI` のみターゲットに追加し、`Add Package`をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73759/d425e834-27ab-8dda-e2f3-4eb2cc6d8a24.png)


### 2. SDKの初期化

`didFinishLaunchingWithOptions`の中など、アプリの最初の方で、1度だけRevenueCat SDKの初期化処理を実装します。

```
Purchases.logLevel = .debug
Purchases.configure(withAPIKey: <my_api_key>, appUserID: <app_user_id>)
```
<my_api_key>には、RevenueCatのProject内の「API keys」で生成したキーを指定します。
<app_user_id>は任意で、ユーザーログイン後などでユーザーのIDが取得できている場合にはユーザーIDを指定します。`Purchases.shared.logIn(<my_app_user_id>) `で後でユーザーIDを連携する方法もあります。

また、RevenueCatのメソッドを呼び出すSwiftファイルでは、RevenueCat, RevenueCatUIのインポートも行います。

```
import RevenueCat
import RevenueCatUI
```

### 3. Paywall表示の実装

Paywallを表示させたい箇所で、呼び出し処理を実装します。

SwiftUIの場合、大きく分けて下記のような2つの呼び出し方があるようです。

#### (1) Viewに対するモディファイアとしてpresentPaywallIfNeededを追加
```
ContentView()
    .onAppear {
        fetchCustomerInfo()
    }
    .presentPaywallIfNeeded( //show Subscription page
            requiredEntitlementIdentifier: "pro",
            purchaseCompleted: { customerInfo in
                    print("Purchase completed: \(customerInfo.entitlements)")
            },
            restoreCompleted: { customerInfo in
                    // Paywall will be dismissed automatically if "pro" is now active.
                    print("Purchases restored: \(customerInfo.entitlements)")
             }
    )
```

`requiredEntitlementIdentifier`はEntitlement作成時に指定したIDになります。

#### (2) sheetとしてPaywallViewを表示
```
struct App: View {
    @State
    var displayPaywall = false

    var body: some View {
        ContentView()
            .sheet(isPresented: self.$displayPaywall) {
                PaywallView(displayCloseButton: true)
            }
    }
```

この場合には`displayPaywall`が`true`が代入されたタイミングで、Paywallが表示されるイメージになります。

![Simulator Screenshot2 - iPhone 15 Pro Max - 2024-09-18 at 02.12.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73759/520ad6c0-a5e4-2928-7bf4-ab57e4c7452d.png)

## 補足
今回参加したハッカソンの要件で、無料利用期間を設定することというものがあり、AppStore Connect上でお試しオファー（Introductory Offers）で対応しました。
オファーコードや、プロモーションオファーで対応するつもりだったのですが、RevenueCatの標準のPaywallの実装だと[現状対応していない](https://community.revenuecat.com/sdks-51/including-promotional-offers-in-revenuecatui-pre-built-paywall-4113)ようです。


## 参考記事
[RevenueCat Document - SDK QuickStart](https://www.revenuecat.com/docs/getting-started/quickstart)
[RevenueCatに入門してみた その1 | ドキュメントを眺める Part1](https://www.memory-lovers.blog/entry/2024/04/22/072359)