Under IAP-testning före lansering stötte vi på ett klassiskt men väldigt förvirrande problem:
- Användaren trycker på ”Fortsätt köp”
- Knappen går till läget ”Bearbetar”
- Efter några sekunder går den tillbaka till ”Fortsätt köp”
- Ingen köpbekräftelse från App Store visas
I den här artikeln dokumenterar vi hela felsökningsspåret, nyckelloggar, rotorsak och en praktisk åtgärdsstrategi inför release.
1. Symptom
Produktlistan på köpsidan laddades normalt, men efter tryck på köp:
purchase()anropades- Ingen systemdialog visades
- UI gick till slut tillbaka till ej köpt-läge
Vid första anblick såg det ut som att köpflödet aldrig startade, men loggarna visade något annat.
2. Första kontrollen: körs köpflödet faktiskt?
Vi lade till loggar på alla kritiska punkter i köpflödet:
- Parametrar från knapptryck
- Inträde i
purchaseSelectedProduct()ochguard-grenar - Före/efter
product.purchase() Transaction.updatesrefreshEntitlements()Transaction.currentEntitlementsTransaction.latest(for:)
Resultat:
purchase()returnerade.success- Transaktionsverifiering lyckades och
transaction.finish()kördes också - Men
entitledIDsförblev tom
Det betyder: problemet var inte ”köpet startade inte”, utan ”behörigheter kändes inte igen efter köp”.
3. Avgörande fynd efter djupare analys
Efter mer detaljerad loggning framträdde flera tydliga signaler:
Transaction.currentEntitlementshade iterationsantal0Transaction.latest(for: monthly)hade en giltig post, men den var utgången- Viktigast: före köpet fanns gamla transaktioner i
Transaction.unfinished - Det aktuella
purchase()returnerade en transaktion från en gammal kedja, inte från ett nytt interaktivt köp
Det förklarar varför ingen popup kom:
- StoreKit returnerade först en gammal processbar transaktion (unfinished / historisk kedja)
- Koden avslutade den med
finish() - Förfrågan såg ”lyckad” ut, men gick inte via det nya bekräftelseflödet som användaren förväntar sig
4. Sammanfattning av rotorsak
Det var inte en enskild felpunkt, utan en kombination av två faktorer:
- Unfinished transactions stör köpflödet
- Sandbox-prenumerationskedjan är i utgånget tillstånd (även med
latest transactionär det inte nödvändigtvis en aktiv entitlement)
Slutbeteendet blev: ingen popup, skenbar framgång, tomma behörigheter.
5. Åtgärdsstrategi (verifierad i praktiken)
5.1 Rensa unfinished-transaktioner proaktivt före köp
Vid appstart och före köp: skanna Transaction.unfinished och kör finish() på verifierade transaktioner så att gamla transaktioner inte kapar det nya köpflödet.
5.2 Behåll och stärk diagnostiska loggar (rekommenderas före lansering)
Dessa loggar bör hållas aktiva fram till release:
- Snapshot av
unfinished transaction subscription status(state, renewal info)- Iterationsantal för
currentEntitlements transaction/expiration-detaljer ilatest(for:)
5.3 Använd dubbel kanal för behörighetskontroll (valfri förstärkning)
Om currentEntitlements tillfälligt är tom i vissa miljöer, använd latest(for:) som fallback (med fortsatt validering av aktiv status).
6. IAP-checklista före lansering
- Före varje test: kontrollera prenumerationsstatus för sandbox-kontot (utgånget eller inte)
- Logga antal
unfinishedpå kritiska vägar - Testa tre scenarier: första köp / förnyelse efter utgång / återställ köp
- Kontrollera konsistens mellan
currentEntitlementsochlatest - Om ”ingen popup” uppstår, kontrollera först om en gammal transaktionsväg träffades
7. Slutsats
”Tryck på köp utan popup” betyder inte nödvändigtvis ett UI-problem eller ett timingproblem i anropen.
I StoreKit 2 påverkar transaktionsstatus, unfinished-kö och prenumerationens livscykel slutbeteendet direkt.
Genom att lägga till dessa loggar och städrutiner före lansering kan du minska många IAP-problem som annars är svåra att återskapa i produktion.