有料からフリーミアムへの移行問題
有料アプリをフリーミアムに切り替えるのはよくあるビジネス上の判断ですが、公平性の課題が伴います。すでにアプリに対して支払ったユーザーが、突然機能を失ったり、再度支払いを求められたりすべきではありません。StoreKitのAppTransaction APIはこの問題をきれいに解決します。
AppTransactionで購入履歴を確認する
鍵となるのはAppTransaction.sharedで、アプリの元のトランザクションに関する情報を提供します。具体的には、originalAppVersionがユーザーが元々ダウンロードしたアプリのバージョンを教えてくれます。そのバージョンが有料版だった場合、ユーザーはすでに支払い済みであることがわかります。
import StoreKit
func shouldGrantFullAccess() async -> Bool {
do {
let result = try await AppTransaction.shared
if case .verified(let transaction) = result {
let originalVersion = transaction.originalAppVersion
// Version "2.0" was when the app went freemium
if originalVersion.compare("2.0", options: .numeric) == .orderedAscending {
return true // User purchased before freemium transition
}
}
} catch {
// Handle verification failure
}
return false
}ロジックはシンプルです:ユーザーのoriginalAppVersionをフリーミアムに切り替えたバージョンと比較します。元のバージョンが切り替え前のものであれば、自動的にフルアクセスを付与します。
重要な詳細
originalAppVersionは、元の購入時(無料アプリの場合はダウンロード時)のCFBundleShortVersionStringの値に対応します。移行ポイントとなるバージョン番号を正確に把握しておく必要があります。
このアプローチにはサーバーインフラもマイグレーションコードも不要です。StoreKitがApp Storeのレシートチェーンを通じて検証を処理するため、チェックは改ざん耐性があります。Appleはこのパターンをビジネスモデル移行のためのオリジナルAPIで文書化しています。
TestFlightおよびSimulatorのテストでは、originalAppVersionは代わりにCFBundleVersion(ビルド番号)を返すため、テストケースをそれに応じて計画してください。
