Skip to content

feat: 自前のペイウォールと RevenueCat Paywalls のペイウォールを切り替えられるようにする - #4

Merged
taniguchi-kyoichi merged 2 commits into
mainfrom
feat/paywall-mode
Sep 27, 2026
Merged

taniguchi-kyoichi merged 2 commits into
mainfrom
feat/paywall-mode

Conversation

@taniguchi-kyoichi

Copy link
Copy Markdown
Contributor

概要

アプリが、自前のペイウォール(SubscriptionUI の PaywallView など)と、RevenueCat のダッシュボードで作ったペイウォール(RevenueCatUI)を切り替えられるようにする。

変更

  • 新しいプロダクト SubscriptionRevenueCatUI。RevenueCatUI に依存するのはこのプロダクトだけ
    • RevenueCatPaywallView(offering:displayCloseButton:onEntitled:onError:onDismiss:)
    • PaywallContainer(mode:onEntitled:onError:onDismiss:custom:):どちらのペイウォールも同じ一か所から出す
    • RevenueCatPaywallError.offeringNotFound(String?)
  • SubscriptionUI に追加(RevenueCatUI に依存しない)
    • PaywallMode:.custom / .revenueCat(offering:) / .automatic(offering:)、current を指す .revenueCat / .automatic
    • PaywallMode.choice(for: PaywallOfferingLookup) -> PaywallChoice:判定の純粋関数
    • PaywallHandlers:onEntitled / onError / onDismiss
  • RevenueCat SDK の下限を 5.19.0 に上げる(Offering.hasPaywall が入ったバージョン)

判定

mode hasPaywall noPaywall offeringMissing unavailable
.custom 自前 自前 自前 自前
.revenueCat RevenueCat RevenueCat 自前 自前
.automatic RevenueCat 自前 自前 自前

unavailable は、環境に SubscriptionUseCase が無い・Purchases.isConfigured が false・offering の読み込みに失敗した、のいずれか。Purchases.shared は未設定だと落ちるので、先に isConfigured を見る。

包み方(chrome)

コンテナはどちらにも枠を付けない。自前のペイウォールは custom クロージャの中で NavigationStack と閉じるボタンまで付けて返し、RevenueCat のペイウォールは自分の閉じるボタンで表示する。これで閉じるボタンが二重にならない。

権利の判定

RevenueCat のペイウォールで購入・復元が終わったら、RevenueCatUI が渡す CustomerInfo ではなく SubscriptionUseCase.checkSubscriptionStatus() に問い合わせる。設定した entitlement で判定でき、EntitlementCache も更新される。何も見つからなかった復元では onEntitled を呼ばない。

確認

  • swift build / swift test(XCTest 37 件、Swift Testing 13 件)
  • xcodebuild -scheme Subscription-Package -destination 'generic/platform=iOS Simulator' build
  • scripts/compute-next-version.sh --baseline 2.0.0 → bump=minor next=2.1.0 removed=0 added=31

タグ・リリースはしない。

🤖 Generated with Claude Code

https://claude.ai/code/session_01ESWEc4G3nTqzvj9XAFZJeV

taniguchi-kyoichi and others added 2 commits September 27, 2026 12:57
- RevenueCatUI に依存するプロダクト SubscriptionRevenueCatUI を足す。
  RevenueCatPaywallView と、どちらのペイウォールも同じ一か所から出す PaywallContainer を持つ。
  Subscription と SubscriptionUI は RevenueCatUI に依存しないまま
- SubscriptionUI に PaywallMode(.custom / .revenueCat(offering:) / .automatic(offering:))と
  判定の純粋関数 PaywallMode.choice(for:) を置く。RevenueCat 側で出せない理由があれば自前に戻す
- 購入・復元のあとは CustomerInfo ではなく SubscriptionUseCase に権利を問い合わせる。
  設定した entitlement で判定し、EntitlementCache も更新される
- PaywallHandlers で、どちらのペイウォールでも onEntitled / onError / onDismiss を同じ形で受け取る
- Offering.hasPaywall を使うため、RevenueCat SDK の下限を 5.19.0 に上げる

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ESWEc4G3nTqzvj9XAFZJeV
関連値つきの case と同じ名前の static プロパティが並ぶと、型を明示しない
`PaywallMode.automatic` が ambiguous になっていた。PaywallMode を struct にし、
`.custom` / `.revenueCat` / `.automatic` を static let、offering を指定する形を
static func にする。型名から書く形と型を明示した代入の両方をテストで確認する。

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ESWEc4G3nTqzvj9XAFZJeV
@taniguchi-kyoichi
taniguchi-kyoichi marked this pull request as ready for review September 27, 2026 05:06
@taniguchi-kyoichi
taniguchi-kyoichi merged commit dedabfb into main Sep 27, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant