ShopKit — Hardening Checklist
1. Functional correctness
- Sign in with Apple works end-to-end on first install and after sign-out
- Auth token survives app relaunch (Keychain)
- 401 from API triggers a one-time refresh; second 401 signs out
- Paywall shows accurate pricing in all supported locales
- Free trial offer is shown only to eligible users
- Restore Purchases works for users on a new device
- Subscription state machine handles billing retry + grace period correctly
-
Refund of a transaction surfaces as
.revokedand gates Pro content
2. Security
-
Auth token in Keychain with
.userPresenceaccess control - No tokens in UserDefaults or files
- TLS pinning enforced for all API hosts
-
No third-party analytics or trackers (verify
Package.resolved) -
Info.plistATS exceptions: zero -
No
printof token, headers, or response bodies -
os_loguses%{private}@for any user-attached values - No force-unwraps; SwiftLint enforces
3. StoreKit / billing
-
All
Transactionvalues verified via.verifiedcase before granting entitlement - Sandbox test for: purchase, cancel during trial, refund, upgrade/downgrade
-
Transaction.updatesis consumed for the app’s lifetime (no missed updates) -
manageSubscriptionsSheetopens correctly from Settings - Server-side validation path documented (App Store Server API) even if not implemented
- Promo offer eligibility checked against Apple’s rules
4. Privacy
- Privacy Nutrition Label: Identifier (User ID), Usage Data, Purchases (App Functionality, linked to user, NOT used for tracking)
-
PrivacyInfo.xcprivacylists every accessed API category with required reasons - No tracking SDKs, no AdServices integration
- Sign in with Apple email is the only user identifier; hashed before being stored on the server
5. Performance
- Cold launch < 1.5 s
- Paywall display < 500 ms after tap
- API request average latency < 400 ms on LTE
- No retain cycles (Instruments → Leaks)
- Subscription state change reflected in UI < 2 s
6. CI/CD
- PR build + test passes consistently (no flake)
- Merge to main → TestFlight build appears within 30 min
- Build numbers auto-incremented
- Match-managed certificates working without manual intervention
- Slack notification on successful deploy
7. App Store Review readiness
- Demo Sign in with Apple sandbox account in Review notes
- Sandbox StoreKit test account in Review notes
- Subscription terms in paywall match Apple’s requirements (auto-renewal text, length, cancel-anytime)
- Restore Purchases button visible (Apple Review will reject without)
- Privacy policy and terms of use URLs live
- Compelling screenshots showing the paywall, content, and a feature
- No mention of Stripe, PayPal, or external purchases (would trigger rejection)
8. Documentation
- GitHub README with green CI badge, screenshots, architecture diagram
- CONTRIBUTING.md documenting how to run the backend locally
- ADRs reflect shipped build
- Interview talking points rehearsed
- App Store URL on portfolio