Devadex

ProKit — StoreKit 2 Monetisation for iOS & macOS

gumroad   $29.00   by ralfster12
32d old

Every indie iOS and macOS developer has written this code before.Transaction.currentEntitlements. Product loading with error handling. Trial state management. Restore logic. Transaction listener running for the app's lifetime. Status hydration on launch so the UI doesn't flicker on the first frame.It's not hard code. It's just the same code, every single time.ProKit is that layer — extracted, tested, and ready to drop into your next project in two steps.What ProKit handles ✅ Free trial — local (simple) or StoreKit-backed ($0.00 non-consumable, reinstall-proof) ✅ Lifetime non-consumable purchase ✅ Auto-renewable subscriptions (yearly, monthly, any interval) ✅ Any combination of the above — you pick what your app offers ✅ Restore purchases ✅ Transaction listener running from app launch ✅ First-frame status hydration — no gate flicker on launch The trial most developers don't know aboutThe standard approach — write a start date to UserDefaults — has a hole: delete the app, reinstall, trial resets.ProKit supports a better strategy: a $0.00 non-consumable that Apple records against the user's Apple ID. Even after uninstall and reinstall, Transaction.currentEntitlements returns the trial transaction. Not eligible again.You create one free product in App Store Connect, pass its ID as trialProductID, and ProKit handles the rest.Flexible product modelPass only what your app needs:// Lifetime + 14-day trial ProStore( lifetimeProductID: "com.app.lifetime", trialProductID: "com.app.trial", trialDays: 14, udPrefix: "app" ) // Subscriptions only (yearly + monthly) ProStore( subscriptionProductIDs: ["com.app.yearly", "com.app.monthly"], trialProductID: "com.app.trial", trialDays: 7, udPrefix: "app" ) // Everything, branded "Premium" ProStore( lifetimeProductID: "com.app.lifetime", subscriptionProductIDs: ["com.app.yearly"], trialProductID: "com.app.trial", trialDays: 14, udPrefix: "app", accessName: "Premium" ) Setup in 3 steps1 — Configure for your app:swift extension ProStore { static var myApp: ProStore { ProStore( lifetimeProductID: "com.company.myapp.lifetime", trialProductID: "com.company.myapp.trial", trialDays: 14, udPrefix: "myapp" ) } }2 — Inject at root:@State private var store = ProStore.myApp WindowGroup { ContentView().environment(store) }3 — Gate any feature:@Environment(ProStore.self) private var store Button("Open Feature") { if store.status.isPro { open() } else { showPaywall = true } }ProStatus — one enum drives everythingswitch store.status { case .free: showPaywall = true case .trial(let days): showBanner("\(days) days left") case .subscribed(let renewsDate): showAccount(renewsDate: renewsDate) case .lifetime: open() } Or just use store.status.isPro for a simple boolean gate.Zero UI — by designProKit ships no views. Paywalls are too brand-specific to generalise, and UI belongs in your platform target — not in a shared package. You get the logic layer; you write the views.Technical detailsPlatforms iOS 17+ · macOS 14+Swift 5.9+Architecture. @Observable · @MainActor · StoreKit 2 · async/awaitDependencies. NoneUI None — pure logicWhat's included Full Swift Package source (ProStatus.swift + ProStore.swift) README.md with complete API reference and setup guide Unit tests for ProStatus All future 1.x updates How to installDownload, unzip, and add to Xcode as a local Swift Package:File → Add Package Dependencies… → Add Local… → select the ProKit folder.No GitHub account. No remote URL. Full setup guide is in README.md.LicenceSingle-developer licence. Use in unlimited personal and commercial apps. Redistribution or resale of the source is not permitted.Saves 4–6 hours on the first app. Pays back faster on every app after that.

Get it → ralfster12.gumroad.com

Found on Devadex — the discovery index for independent software the big search engines bury. More from gumroad.

Report this listing