Bundle ID → IAP products → RevenueCat keys → Screenshots → Live
$99/year covers both iOS and macOS distribution. Requires an Apple ID. Organizations also need a D-U-N-S number — allow up to a week for verification.
Max 30 characters. Must be unique across the App Store (iOS and Mac share the same namespace). Search apps.apple.com before committing — the name cannot change post-publish without a new version.
Reverse-domain format: com.DOMAIN.appname. Use an Explicit App ID — not a wildcard — because In-App Purchases require it. Enable In-App Purchases capability here. For a Mac Catalyst app, this is the same Bundle ID as your iOS app. For a native macOS app, register a separate Bundle ID (e.g. com.DOMAIN.appname-mac) or reuse the same one if shipping as a universal purchase.
New App → select platform (iOS, macOS, or both) → choose your Bundle ID → enter an SKU (internal-only string, e.g. APPNAME-001). You can create a single App Store Connect record that ships on both iOS and macOS if using Mac Catalyst or universal purchase. Native macOS apps get their own separate record.
Two paths for shipping a Mac app:
Xcode → Target → Signing & Capabilities → Bundle Identifier. Must match exactly what you registered in step 1.3. For a Mac Catalyst target, Xcode may append .macos automatically — verify it matches your registered ID.
Signing & Capabilities → Team → select your developer account. Enable Automatically manage signing. For projects with both iOS and macOS targets, set the team on each target separately.
Signing & Capabilities → + Capability → search "In-App Purchase" → add it. For a multi-target project (iOS + macOS), add this capability to each target that will present purchases.
Required for all Mac App Store submissions. Signing & Capabilities → + Capability → App Sandbox. Configure the minimum entitlements your app actually needs (network access, file access, etc.). Overly broad entitlements can trigger review rejection.
Required for Mac App Store and notarization. Signing & Capabilities → + Capability → Hardened Runtime. If your app uses JIT, DYLD injection, unsigned memory, or Apple Events, add the appropriate exceptions. Most SwiftUI apps need no exceptions.
General → Deployment → macOS. Set the minimum version your app supports. RevenueCat SDK requires macOS 10.13+. Older targets may restrict which StoreKit 2 APIs are available — SK2 requires macOS 12+.
File → New → StoreKit Configuration File. Define your products here to test purchase flows locally before App Store Connect products are approved. Set it in each scheme: Run → Options → StoreKit Configuration.
File → Add Package Dependencies → paste the URL below → add the RevenueCat library to every target that needs it (iOS target, macOS target, or both).
For a Mac Catalyst app, the same @main App struct runs on both platforms. For separate targets, initialize in each target's entry point using its own RevenueCat API key from step 5.2.
In-App Purchases covers non-consumables and consumables. Subscriptions covers auto-renewable tiers. These live under the same app record — both platforms share the same IAP products when using Universal Purchase.
All auto-renewable subscriptions must belong to a group. A user can hold only one active subscription per group — this is how upgrade/downgrade logic works. Group name is shown in system dialogs.
Repeat for every tier (Monthly, Annual, Lifetime, etc.):
com.DOMAIN.appname.pro_annualApple requires a screenshot showing exactly where and how the purchase appears in your app. One required per product. For review only — never shown to customers.
Under each subscription product: Add Introductory Offer → Free Trial, Pay Up Front, or Pay As You Go → set duration and eligibility. RevenueCat manages trial eligibility server-side automatically.
Products are reviewed independently from the app binary. Status: Missing Metadata → Ready to Submit → Waiting for Review → Approved. Usually approved with the first app submission but can be submitted standalone.
Provide at minimum one large iPhone set. The 6.9″ set covers all newer iPhones when no device-specific sets are provided.
Mac screenshots are landscape. Provide at least one required size. Shots should show the app window in its natural state — no simulated hardware overlays needed.
15–30 seconds of real screen recording. Autoplays in search results — worth doing if motion demonstrates value.
Sign up → New Project → name it after your app. A single project holds multiple platforms (iOS, macOS, Android) sharing entitlements and subscriber data.
Project Settings → Apps → Add App. Add one entry per platform:
For Mac Catalyst (same Bundle ID as iOS), you can use the same API key. For a separate native macOS target, add it as a separate app.
Allows RevenueCat to verify receipts server-to-server. In App Store Connect: Users and Access → Integrations → In-App Purchase tab (separate from the regular API Keys tab).
.p8 private key · Key ID (10-char) · Issuer ID (UUID)RevenueCat Dashboard → each app → App Store Connect section → paste Key ID and Issuer ID, upload the .p8. Do this for both your iOS and macOS RevenueCat app entries if they are separate.
Entitlements are feature-unlock gates (e.g. pro). Multiple products at different prices all map to the same entitlement. Create entitlements → attach every product that grants access.
pro — this string is checked in Swift to gate featuresOfferings are named bundles of packages shown on your paywall. The Current offering is fetched by default. Offerings can be changed remotely without an app update. Create separate offerings per platform if your Mac and iOS paywalls differ.
Supply a single 1024 × 1024 px PNG in App Store Connect. Xcode generates all device sizes from the AppIcon asset catalog. No alpha channel. No pre-applied rounded corners.
100 characters total, comma-separated, no spaces around commas. Don't repeat words in the name or subtitle. Don't use competitor names. Keywords apply per-platform for Mac vs iOS listings.
Complete the content questionnaire. Most utility apps land at 4+. Answer honestly — Apple cross-checks at review. Must be completed separately for each platform listing if separate app records.
Declare every data type your app and its SDKs collect. RevenueCat collects Purchase History, User ID, and Device ID — all must be declared. Check RevenueCat's privacy manifest for the full required list.
App Store Connect → your app → App Store → [version] → drag screenshots into each device-size slot. iOS and macOS screenshots are uploaded in separate sections even for Universal Purchase apps.
Version (CFBundleShortVersionString) is user-facing, e.g. 1.0.0. Build (CFBundleVersion) must increment with every upload. Set both on every target before archiving.
Set scheme destination to Any iOS Device (arm64) — not Simulator. Product → Archive → Xcode Organizer opens automatically.
Set scheme destination to My Mac (for Mac Catalyst: "My Mac (Designed for iPad)" or "My Mac"). Product → Archive. A macOS archive produces a .xcarchive containing a .app bundle.
Organizer → select archive → Validate App. Catches entitlement mismatches, missing privacy manifests, and binary issues before upload. For macOS, validation also checks Hardened Runtime and sandbox entitlements.
Organizer → Distribute App → App Store Connect → Upload. For macOS, Xcode also notarizes the binary with Apple automatically during this step. Allow 10–30 min for processing.
Build appears in TestFlight → Internal Groups after processing. Up to 100 internal testers (must be in your developer account). No review needed. Confirm RevenueCat sandbox purchases work end-to-end here before submitting.
Mac apps also use TestFlight since macOS 12. The build appears separately under the macOS platform in TestFlight. Internal testers install via the TestFlight Mac app. External Mac beta requires a review (same as iOS external beta).
App Store Connect → your app → App Store → [version] → Build → + → select build. Then fill Review Information:
Click Add for Review → confirm. Status: Waiting for Review. First submissions: 1–3 business days. Mac apps go through the same review pipeline as iOS — no separate Mac reviewer queue.
Manually Release This Version lets you control go-live timing after approval — useful for coordinating marketing. After release, confirm RevenueCat S2S notifications are firing in production and real-purchase entitlement grants work on both platforms.