StoreKit 2 hat In-App-Käufe von einem Delegate-Labyrinth in ein paar Zeilen asynchrones Swift verwandelt. Das ist das Setup, das wir in unseren eigenen Apps nutzen: eine kleine Store-Klasse, eine Paywall und eine Handvoll Regeln, die App Review zufriedenstellen.
1. Produkte anlegen
Legen Sie in App Store Connect eine Abo-Gruppe an und fügen Sie Ihre Pläne hinzu, zum Beispiel monatlich und jährlich. Notieren Sie die Produkt-IDs. Für lokale Tests fügen Sie in Xcode eine StoreKit Configuration File mit denselben IDs hinzu und wählen sie in Ihrem Scheme aus. Dann können Sie im Simulator ohne Sandbox-Konto kaufen, verlängern und kündigen.
2. Ein Store für die ganze App
import StoreKit
@MainActor
final class Store: ObservableObject {
@Published private(set) var products: [Product] = []
@Published private(set) var isPro = false
private let ids = ["com.example.pro.monthly", "com.example.pro.yearly"]
private var updates: Task<Void, Never>?
init() {
// Renewals, refunds and purchases made on other devices arrive here.
updates = Task { [weak self] in
for await result in Transaction.updates {
await self?.handle(result)
}
}
Task {
await loadProducts()
await refreshEntitlements()
}
}
func loadProducts() async {
do {
products = try await Product.products(for: ids).sorted { $0.price < $1.price }
} catch {
print("Could not load products: \(error)")
}
}
func buy(_ product: Product) async throws {
switch try await product.purchase() {
case .success(let result):
await handle(result)
case .userCancelled, .pending:
break
@unknown default:
break
}
}
func restore() async {
try? await AppStore.sync()
await refreshEntitlements()
}
func refreshEntitlements() async {
var active = false
for await result in Transaction.currentEntitlements {
if case .verified(let transaction) = result, transaction.revocationDate == nil {
active = true
}
}
isPro = active
}
private func handle(_ result: VerificationResult<Transaction>) async {
guard case .verified(let transaction) = result else { return }
await transaction.finish()
await refreshEntitlements()
}
}
Erstellen Sie ihn einmal, etwa als @StateObject in Ihrer App, und reichen Sie ihn mit .environmentObject weiter. Beginnen Sie so früh wie möglich, Transaction.updates zu beobachten; sonst können Käufe verloren gehen, die außerhalb der App abgeschlossen wurden.
3. Warum die Prüfung wichtig ist
Jede Transaktion kommt in einem VerificationResult. StoreKit prüft Apples Signatur auf dem Gerät; .verified bedeutet also, dass der Kauf echt ist. Schalten Sie Inhalte nur für geprüfte Transaktionen frei und rufen Sie nach der Auslieferung immer finish() auf.
4. Eine Paywall in wenigen Zeilen
Ab iOS 17 liefert SubscriptionStoreView eine vollständige, App-Review-freundliche Paywall:
SubscriptionStoreView(groupID: "YOUR_GROUP_ID") {
VStack(spacing: 8) {
Text("Go Pro").font(.largeTitle.bold())
Text("Unlimited exports and every template.")
}
}
.storeButton(.visible, for: .restorePurchases)
Wenn Sie Ihre eigene gestalten, zeigen Sie Preis und Zeitraum jedes Plans mit product.displayPrice, verlinken Sie Nutzungsbedingungen und Datenschutz und fügen Sie einen Wiederherstellen-Button hinzu.
5. Gratis-Testphasen und Einführungsangebote
Einführungsangebote richten Sie in App Store Connect ein. Damit „Gratis testen“ nur Menschen sehen, die es nutzen können, prüfen Sie zuerst die Berechtigung:
let eligible = await product.subscription?.isEligibleForIntroOffer ?? false
6. Was App Review bei einer Paywall prüft
- Preis und Abrechnungszeitraum sind vor dem Kauf klar
- Dauer der Gratis-Testphase und was danach passiert
- Ein funktionierender Button zum Wiederherstellen von Käufen
- Links zu Nutzungsbedingungen und Datenschutzerklärung
- Keine Dark Patterns, etwa ein versteckter Schließen-Button
Den Rest behandelt unsere Liste der häufigsten App-Store-Ablehnungen.
7. Serverseitig, wenn nötig
Für eine App auf einem Gerät reichen Berechtigungen auf dem Gerät aus. Melden sich Nutzer auf mehreren Plattformen an oder brauchen Sie Umsatzdaten, ergänzen Sie Ihr Backend um App Store Server Notifications V2, damit Ihr Server von Verlängerungen und Erstattungen erfährt, sobald sie passieren.
Häufige Fragen
Brauche ich mit StoreKit 2 noch eine Belegprüfung?
Nicht auf dem Gerät: StoreKit 2 prüft signierte Transaktionen für Sie. Ein Server ist nur nötig, wenn Sie Berechtigungen plattform- oder kontoübergreifend teilen.
Wie teste ich Abos, ohne zu bezahlen?
Nutzen Sie für lokale Tests eine StoreKit Configuration File in Xcode, für End-to-End-Tests ein Sandbox-Konto oder TestFlight. Sandbox-Verlängerungen laufen in beschleunigtem Takt.
Was ist die Mindestversion von iOS für StoreKit 2?
StoreKit 2 funktioniert ab iOS 15. SubscriptionStoreView und die anderen Verkaufsansichten brauchen iOS 17.
Wie viel behält Apple von Abonnements ein?
Standardmäßig 30 %, 15 % für Mitglieder des Small Business Program und 15 % auf ein Abo nach dem ersten Jahr des Abonnenten.