Počas IAP testovania pred vydaním sme narazili na typický, no veľmi mätúci problém:
- Používateľ klepne na „Pokračovať v nákupe“
- Tlačidlo prejde do stavu „Spracováva sa“
- Po pár sekundách sa vráti na „Pokračovať v nákupe“
- Nezobrazí sa potvrdzovacie okno nákupu z App Store
V tomto článku dokumentujeme celý postup vyšetrovania, kľúčové logy, root cause a praktickú stratégiu opravy pred release.
1. Symptóm
Zoznam produktov na obrazovke nákupu sa načítaval normálne, ale po kliknutí na kúpu:
- Volalo sa
purchase() - Nezobrazil sa žiadny systémový dialóg
- UI sa nakoniec vrátilo do stavu „nekúpené“
Na prvý pohľad to vyzeralo, že nákupný flow sa vôbec nespúšťa, no logy ukázali iný obraz.
2. Prvá kontrola: prechádza nákupný flow naozaj správne?
Doplnili sme logovanie do všetkých kritických bodov nákupného flow:
- Parametre kliknutia na tlačidlo
- Vstup do
purchaseSelectedProduct()a vetvyguard - Pred/po
product.purchase() Transaction.updatesrefreshEntitlements()Transaction.currentEntitlementsTransaction.latest(for:)
Výsledok:
purchase()vracalo.success- Overenie transakcie prebehlo úspešne a
transaction.finish()sa tiež vykonal - Ale
entitledIDsostalo prázdne
To znamená: problém nebol „nákup sa nespustil“, ale „po nákupe sa nerozpoznali entitlementy“.
3. Kľúčové zistenia po hlbšej analýze
Po rozšírení logov sa objavili rozhodujúce signály:
- Počet iterácií
Transaction.currentEntitlementsbol0 Transaction.latest(for: monthly)obsahoval validný záznam, ale už expirovaný- Dôležitejšie: pred nákupom existovali staré transakcie v
Transaction.unfinished - Aktuálne
purchase()vracalo transakciu zo starého reťazca, nie z nového interaktívneho nákupu
To vysvetľuje, prečo „nevyskočí okno“:
- StoreKit najprv vráti spracovateľnú starú transakciu (unfinished / historický reťazec)
- Kód ju dokončí cez
finish() - Požiadavka vyzerá „úspešne“, ale neprejde novou cestou potvrdenia nákupu, ktorú používateľ očakáva
4. Zhrnutie root cause
Nešlo o jedno zlyhanie, ale o kombináciu dvoch faktorov:
- Unfinished transactions narúšajú nákupný flow
- Sandbox subscription reťazec je v expirovanom stave (aj pri
latest transactionto nemusí byť aktívny entitlement)
Finálne správanie: bez pop-up okna, zdanlivý úspech, prázdne entitlementy.
5. Stratégia opravy (overená v praxi)
5.1 Proaktívne čistenie unfinished transactions pred nákupom
Pri štarte aplikácie a pred nákupom prejdite Transaction.unfinished a na verified transakciách vykonajte finish(), aby staré transakcie neprebrali nový nákupný flow.
5.2 Zachovať a posilniť diagnostické logy (odporúčané pred vydaním)
Tieto logy sa oplatí ponechať zapnuté až do release:
- Snapshot
unfinished transaction subscription status(state, renewal info)- Počet iterácií
currentEntitlements - Detaily
transaction/expirationzlatest(for:)
5.3 Dvojkanálové overenie entitlementov (voliteľné spevnenie)
Ak je v niektorých prostrediach currentEntitlements dočasne prázdne, použite latest(for:) ako fallback (stále však validujte aktívny stav).
6. IAP checklist pred vydaním
- Pred každým testom overte stav predplatného sandbox účtu (či je expirované)
- Logujte počet
unfinishedna kritických cestách - Otestujte tri scenáre: prvý nákup / obnovenie po expirácii / obnova nákupov
- Skontrolujte konzistentnosť medzi
currentEntitlementsalatest - Pri „bez pop-up okna“ najprv overte, či nebol zasiahnutý starý transakčný flow
7. Záver
„Kliknem kúpiť, ale bez pop-up okna“ nemusí znamenať UI problém ani problém načasovania volania.
V StoreKit 2 stav transakcií, unfinished fronta a životný cyklus predplatného priamo ovplyvňujú finálne správanie.
Doplnenie týchto logov a čistiacich krokov pred vydaním výrazne znižuje počet IAP problémov, ktoré sa v produkcii ťažko reprodukujú.