通行証 · HALL PASS DOCS · PLAY

iOS — first TestFlight build, on the Mac

For the first physical iPhone 16 install and Safari/app performance comparison, start with IPHONE-PERFORMANCE.md. Xcode can install directly before TestFlight is configured. The recorder is available in both runtimes under Options → System → Performance test.

The iOS project is generated and pre-configured in this repo; the only things that need a Mac are signing, archiving and uploading. Budget an hour the first time, ten minutes after that.

Before Xcode (App Store Connect, once)

  1. App ID. developer.apple.com → Certificates, Identifiers & Profiles → Identifiers → "+" → App IDs → App. Bundle ID com.verybad.hallpass (explicit). Capabilities: tick In-App Purchase. (Push Notifications later, when OneSignal has keys.)
  2. App record. appstoreconnect.apple.com → Apps → "+" → New App. Platform iOS, name HALL PASS, primary language English (U.S.), bundle ID from step 1, SKU hallpass.
  3. Paid Applications agreement. Agreements, Tax and Banking. Until this is Active, in-app purchases do not work even in sandbox, and the store inside the app will say it did not answer.
  4. In-app purchases (Monetization → In-App Purchases): supporter (non-consumable), boost_7d, boost_30d (consumables). Names, descriptions and a screenshot each are required before review, not before TestFlight.
  5. Sandbox tester (Users and Access → Sandbox): one account you can sign into on the test phone, so purchases charge nothing.

On the Mac

git pull
npm ci
npm run ios:prepare        # production build, complete runtime assets, Capacitor sync
npm run ios:open           # opens ios/App/App.xcodeproj in Xcode

In Xcode:

  1. Select the App target → Signing & Capabilities → Team: your Apple Developer team. Automatic signing. Bundle id is already com.verybad.hallpass.
  2. "+ Capability" → In-App Purchase.
  3. Product → Destination → Any iOS Device (arm64).
  4. Product → Archive. First archive resolves SwiftPM packages (Capacitor, AdMob, OneSignal, RevenueCat, the local ad-tracker plugin); expect a few minutes.
  5. Organizer opens on success → Distribute App → App Store Connect → Upload. Accept the defaults. The export-compliance question is already answered in Info.plist (ITSAppUsesNonExemptEncryption = false), so it should not ask.
  6. appstoreconnect.apple.com → the app → TestFlight. The build appears after processing (5–20 min). Add Internal Testing → a group with yourself and friends who are App Store Connect users. No review, no minimum count. External testers need a one-time Beta App Review (a day or so).

Testers install the TestFlight app, accept the invite, and get every new build automatically.

What is already set in the project

If the archive fails

Keys to paste when you have them

src/services.js: revenuecat.ios (appl_…), admob.ios.app + the two unit ids (and the same app id in ios/App/App/Info.plist under GADApplicationIdentifier), onesignal.appId. Rebuild, npx cap sync ios, archive, upload.

Before submitting for App Store review (not needed for TestFlight)

Screenshots for 6.9" and 6.5" iPhones (and iPad if kept), the App Privacy answers from store/LISTING.md, the privacy URL hallpass.cc/privacy, age rating questionnaire, review notes that say ads are AdMob and purchases are via RevenueCat with a sandbox account provided. Set admob.testing = false with real unit ids first.

HALL PASS by Very Bad Games · Solo Developer Chris Sands · All documentation