Das Problem beim Wechsel von kostenpflichtig zu Freemium
Eine bezahlte App auf Freemium umzustellen ist eine gängige Geschäftsentscheidung, bringt aber eine Fairness-Herausforderung mit sich: Nutzer, die bereits für die App bezahlt haben, sollten nicht plötzlich Features verlieren oder erneut zur Kasse gebeten werden. StoreKits AppTransaction API löst das sauber.
AppTransaction zur Überprüfung der Kaufhistorie verwenden
Der Schlüssel ist AppTransaction.shared, das Informationen über die ursprüngliche Transaktion deiner App liefert. Genauer gesagt sagt dir originalAppVersion, welche Version der App der Nutzer ursprünglich heruntergeladen hat. Wenn diese Version eine bezahlte Version war, weißt du, dass der Nutzer bereits bezahlt hat.
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
}Die Logik ist unkompliziert: Vergleiche die originalAppVersion des Nutzers mit der Version, bei der du den Freemium-Wechsel vorgenommen hast. Wenn die ursprüngliche Version vor der Änderung liegt, gewähre automatisch vollen Zugriff.
Wichtige Details
Die originalAppVersion entspricht dem CFBundleShortVersionString-Wert zum Zeitpunkt des ursprünglichen Kaufs (oder Downloads bei kostenlosen Apps). Stelle sicher, dass du genau weißt, welche Versionsnummer deinen Übergangspunkt markiert.
Dieser Ansatz erfordert keine Server-Infrastruktur und keinen Migrationscode. StoreKit übernimmt die Verifizierung über die App Store Receipt Chain, sodass die Prüfung manipulationssicher ist. Apple dokumentiert dieses Muster in der Original-API für Geschäftsmodell-Migration.
Für TestFlight- und Simulator-Tests gibt originalAppVersion stattdessen die CFBundleVersion (Build-Nummer) zurück, plane deine Testfälle also entsprechend.
