Community-maintained Agent Skills for complete Swift and Apple-platform app delivery.
73
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Medium
Suggest reviewing before use
Use this reference for product loading, StoreKit views, custom purchase controls, purchase options, result handling, AppTransaction, and durable delivery. Entitlement reconciliation and subscription state are covered in entitlements-and-subscriptions.md.
| Type | StoreKit case | Product responsibility |
|---|---|---|
| Consumable | .consumable | Deliver and persist quantity outside current entitlements |
| Non-consumable | .nonConsumable | Grant durable ownership after verified transaction |
| Auto-renewable subscription | .autoRenewable | Reconcile access from subscription transaction/status |
| Non-renewing subscription | .nonRenewing | App defines and persists expiration policy |
Keep identifiers centralized and load products from the App Store. Treat missing identifiers as configuration or availability failures, not empty prices to hardcode around.
enum ProductID {
static let premium = "com.example.premium"
static let monthly = "com.example.pro.monthly"
static let yearly = "com.example.pro.yearly"
static let all = [premium, monthly, yearly]
}
let products = try await Product.products(for: ProductID.all)Display displayName, description, and displayPrice. Do not hardcode currency symbols, trial copy, or localized price strings.
Prefer StoreKit views for standard stores and paywalls:
ProductView for one product;StoreView for a product collection;SubscriptionStoreView for auto-renewable options in one subscription group.StoreKit views load localized product data and initiate purchases. Configure restore/redeem controls and subscription policy destinations as required by the product and platform.
SubscriptionStoreView(groupID: subscriptionGroupID)
.subscriptionStoreControlStyle(.prominentPicker)
.storeButton(.visible, for: .restorePurchases)
.subscriptionStorePolicyDestination(url: termsURL, for: .termsOfService)
.subscriptionStorePolicyDestination(url: privacyURL, for: .privacyPolicy)For custom SwiftUI buttons, use PurchaseAction from the environment. Use purchase(confirmIn:options:) for UIKit/AppKit presentation and lower-level product.purchase(options:) when the platform or custom flow requires it. Preserve existing project abstraction when it already applies these contracts correctly.
Handle every result. Verification, durable delivery, and finish order are non-negotiable.
@Environment(\.purchase) private var purchase
func buy(_ product: Product) async throws {
let result = try await purchase(product, options: [
.appAccountToken(accountToken)
])
switch result {
case .success(let verification):
let transaction = try verified(verification)
try await fulfillment.deliver(transaction)
await transaction.finish()
case .pending:
// Ask to Buy or other deferred approval. Don't unlock yet.
purchaseState = .pending
case .userCancelled:
purchaseState = .idle
@unknown default:
purchaseState = .failed(.unsupportedResult)
}
}
func verified<T>(_ result: VerificationResult<T>) throws -> T {
switch result {
case .verified(let value): value
case .unverified(_, let error): throw error
}
}Disable or serialize duplicate purchase attempts according to the UI design. Keep cancellation distinct from an error and pending distinct from success.
.appAccountToken(UUID) associates a stable app account with App Store transactions for reconciliation. Use a random UUID assigned to the account, not an email or other personal identifier..quantity(Int) applies to eligible consumables and must match fulfillment..simulatesAskToBuyInSandbox(true) is a test option, not production business logic.SwiftUI store views can provide options with inAppPurchaseOptions. Use start/completion callbacks for UI state and analytics, but keep verified fulfillment idempotent because the launch transaction listener can observe the same transaction path.
The fulfillment boundary must make duplicate verified transaction delivery safe. Use the transaction/original transaction identifiers appropriate to the product model and store fulfillment state durably before finishing.
Call transaction.finish() only after the content or service is delivered. If delivery fails, preserve enough information to retry and leave the transaction unfinished so Transaction.updates or Transaction.unfinished can recover it.
Consumables require app/server persistence because Transaction.currentEntitlements does not represent consumed balance or delivery history. Never grant balance solely from a local button state.
Use AppTransaction.shared when the business model depends on the app's original purchase, original version, or migration from a paid app. Verify its VerificationResult before using it. Do not use AppTransaction as a replacement for individual In-App Purchase entitlement checks.
let result = try await AppTransaction.shared
guard case .verified(let appTransaction) = result else {
throw PurchaseError.unverifiedAppTransaction
}
let originalVersion = appTransaction.originalAppVersion
let originalPurchaseDate = appTransaction.originalPurchaseDate.tessl-plugin
skills
accessorysetupkit
references
activitykit
adattributionkit
references
alarmkit
references
app-clips
app-intents
app-store-optimization
app-store-review
apple-on-device-ai
appmigrationkit
audioaccessorykit
references
authentication
references
avkit
background-processing
references
browserenginekit
callkit
references
carplay
cloudkit
contacts-framework
references
core-bluetooth
references
core-data
core-motion
references
core-nfc
references
coreml
references
cryptokit
cryptotokenkit
references
debugging-instruments
device-integrity
references
dockkit
energykit
references
eventkit
financekit
references
focus-engine
gamekit
healthkit
references
homekit
references
ios-accessibility
ios-app-workflow
references
ios-ettrace-performance
ios-localization
ios-memgraph-analysis
ios-networking
ios-simulator
references
metrickit
references
musickit
references
natural-language
references
paperkit
references
passkit
references
pdfkit
pencilkit
references
permissionkit
references
photokit
push-notifications
realitykit
references
relevancekit
references
scenekit
sensorkit
speech-recognition
references
spritekit
storekit
swift-api-design-guidelines
swift-architecture
references
swift-charts
swift-codable
references
swift-code-review
swift-concurrency
swift-formatstyle
references
swift-language
swift-security
references
swift-testing
swiftdata
swiftlint
swiftui-animation
swiftui-gestures
references
swiftui-layout-components
swiftui-liquid-glass
references
swiftui-patterns
swiftui-performance
swiftui-responsive-layout
swiftui-uikit-interop
swiftui-webkit
tabletopkit
tipkit
vision-framework
weatherkit
references