
storekit
by johnrogers
A collection of agents and skills to aid in the planning, implementation, documentation and testing of Swift/TCA code.
SKILL.md
name: storekit description: Use when implementing in-app purchases, StoreKit 2 subscriptions, consumables, non-consumables, or transaction handling. Covers testing-first workflow with .storekit configuration, StoreManager architecture, and transaction verification.
StoreKit
StoreKit 2 patterns for implementing in-app purchases with async/await APIs, automatic verification, and SwiftUI integration.
Reference Loading Guide
ALWAYS load reference files if there is even a small chance the content may be required. It's better to have the context than to miss a pattern or make a mistake.
| Reference | Load When |
|---|---|
| Getting Started | Setting up .storekit configuration file, testing-first workflow |
| Products | Loading products, product types, purchasing with Product.purchase() |
| Subscriptions | Auto-renewable subscriptions, subscription groups, offers, renewal tracking |
| Transactions | Transaction listener, verification, finishing transactions, restore purchases |
| StoreKit Views | ProductView, SubscriptionStoreView, SubscriptionOfferView in SwiftUI |
Core Workflow
- Create
.storekitconfiguration file first (before any code) - Test purchases locally in Xcode simulator
- Implement centralized
StoreManagerwith@MainActor - Set up
Transaction.updateslistener at app launch - Display products with
ProductViewor custom UI - Always call
transaction.finish()after granting entitlements
Essential Architecture
@MainActor
final class StoreManager: ObservableObject {
@Published private(set) var products: [Product] = []
@Published private(set) var purchasedProductIDs: Set<String> = []
private var transactionListener: Task<Void, Never>?
init() {
transactionListener = listenForTransactions()
Task { await loadProducts() }
}
}
Common Mistakes
-
Missing
.finish()calls on transactions — Forgetting to calltransaction.finish()after granting entitlements causes transactions to never complete. The user won't see their purchase reflected. Always callfinish(). -
Unsafe StoreManager state — Shared
StoreManagerwithout@MainActorcan have race conditions. Multiple async tasks can update@Publishedproperties concurrently, corrupting state. Use@MainActorfor thread safety. -
No transaction listener at app launch — Not setting up
Transaction.updateslistener means app crashes or misses refunded/canceled purchases. Listen for transactions immediately in@main, not when user taps purchase button. -
Hardcoded product IDs — Hardcoded IDs make testing and localization hard. Use configuration files or environment variables for product IDs. Same applies to prices (fetch from App Store, don't hardcode).
-
Ignoring verification failures — App Store verification fails silently sometimes. Not checking verification status means accepting unverified transactions (security risk). Always verify before granting entitlements.
スコア
総合スコア
リポジトリの品質指標に基づく評価
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
レビュー
レビュー機能は近日公開予定です