◉RORK LABJP
●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…
Articles/Dev Tools
⬡ Dev Tools/2026-05-25Intermediate

Implementation Notes: Adding StoreKit 2 In-App Purchases to a Rork iOS App

Notes from grafting StoreKit 2 in-app purchases onto Swift/SwiftUI code generated by Rork, drawing on the StoreKit 1-to-2 migration done across a 50M-cumulative-download wallpaper-app portfolio. Covers ProductID design, transaction verification, paywall UI, and production gotchas.

rork59rork-max40storekit-2in-app-purchase3ios12swiftui11indie-developer

✦ Premium Article

A Rork-generated iOS app boots, navigates, and renders cleanly — but the paid feature gate is often left as a placeholder with a comment that says "implement purchase here." Apps that need IAP to ship will sit at this exact line until somebody writes the StoreKit code, and I have watched more than one indie developer abandon a near-finished app at this step.

I am Masaki Hirokawa. I have been a solo iOS/Android developer since 2014, with roughly 50 million cumulative downloads across a wallpaper-app portfolio (Beautiful Wallpapers, Ukiyo-e Wallpapers, Cool Wallpapers, Illustration Wallpapers, Dolice Wallpapers), and I also run four Lab sites and two blog sites in parallel. I migrated all five apps from StoreKit 1 to StoreKit 2 in 2025, so when I started adding IAP to Rork-generated apps the work was familiar.

These are notes from that grafting work. Aimed at developers with a working Rork-generated app blocked on IAP, or those looking for a StoreKit 2 example that matches Rork's code shape (Apple's official samples assume a different file structure).

Why You End Up Bolting StoreKit 2 onto Rork Code

Rork scaffolds the SwiftUI skeleton of an app, but it deliberately leaves IAP as placeholders. The reason is structural: IAP requires App Store Connect setup (ProductID creation, tax form submission, banking, contract acceptance) to even test, and Rork cannot validate against that side.

A typical Rork-generated app looks like:

MyApp/
├── MyAppApp.swift           ← @main entry
├── ContentView.swift        ← root view
├── Views/
│   ├── WallpaperView.swift  ← feature view
│   └── PremiumGateView.swift ← "implement purchase" placeholder
├── Models/
│   ├── WallpaperItem.swift
│   └── PurchaseManager.swift ← body is TODO
└── Resources/
    └── Assets.xcassets

PurchaseManager.swift is empty, and your job is to fill it with StoreKit 2 logic. The SwiftUI base makes this pleasant — StoreKit 2 integrates naturally without the StoreKit 1 ceremony of forcing SKProductsRequestDelegate through SwiftUI's lifecycle.

Having just migrated five wallpaper apps from StoreKit 1 to 2, the Rork grafting felt like rerunning that migration on a clean canvas. If you are coming to StoreKit 2 fresh, expect a small learning curve. This guide is written for that audience and covers the whole loop end to end.

App Store Connect Prep — The Real Bottleneck

Before any code, App Store Connect needs setup. This is where I see most indie developers stall.

First, complete the IAP contract and tax forms in App Store Connect. Without them IAP does not work in sandbox or production. Fill the entire "Tax, Banking, and Trade Representative Contact Information" section.

Second, decide a ProductID naming convention and create the products. My convention:

{bundle_id}.{type}.{label}

Examples:
- com.dolice.wallpaper.consumable.pack_50      (consumable)
- com.dolice.wallpaper.nonconsumable.premium    (non-consumable)
- com.dolice.wallpaper.subscription.monthly     (monthly sub)
- com.dolice.wallpaper.subscription.yearly      (yearly sub)

Pick a convention before you create anything. If app #1 has premium_full and app #2 has unlock_all, your shared code grows branches. Standardizing upfront is a practical recommendation for indie operations.

Third, the same ProductID is used in sandbox and production. Apple sandbox testing and production purchases share the ID, so changing it later is structurally hard. Choose carefully on day one.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦Concrete implementation steps and a folder layout for grafting StoreKit 2 onto the Swift/SwiftUI code Rork generates — full working code included.
✦ProductID design and transaction-verification pitfalls learned from migrating a 50M-download wallpaper-app portfolio from StoreKit 1 to StoreKit 2.
✦A practical decision matrix for choosing between plain StoreKit 2 and RevenueCat at indie scale, with the financial and operational cutover points spelled out.
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

⬡ Dev Tools2026-05-20
Fixing 0x8badf00d Watchdog Kills That Wipe Out Rork Apps at Launch
Your Rork iOS app dies right after launch on real devices, but never on your bench. Crashlytics shows exception code 0x8badf00d. Here is how to read the exact watchdog budget out of the crash log and rearrange your launch path so it stops.
⟐ Business2026-04-28
Monetizing SwiftUI Native Apps Built with Rork Max — From App Store Approval to Subscription Revenue
How to take SwiftUI code generated by Rork Max through App Store review and add StoreKit 2 subscriptions, with working code and the items review actually checks.
⬡ Dev Tools2026-04-24
When Your Rork App Binary Tops 150MB: 5 Causes to Isolate and a Step-by-Step Slim-Down Plan
My Rork-built app archived at 180MB and App Store Connect stopped me cold. Here is how I broke the bloat into 5 measurable causes and got it down to 69MB — including the three cuts that backfired.