# Apple Developer — App Store & TestFlight Guide ## API Key | Field | Value | | --------- | -------------------------------------- | | Key ID | `PPATU9GL73` | | Issuer ID | `1dbc2980-1621-4fb9-940b-e28257e6322c` | | Role | App Manager | | File | `AuthKey_PPATU9GL73.p8` | > **⚠️ The `.p8` file is NOT checked into git** (blocked by secret scanner). It lives at `~/.appstoreconnect/private_keys/AuthKey_PPATU9GL73.p8` on each machine. Copy it manually between machines or re-download from App Store Connect (one-time download only — keep a backup). ### Setup on any machine ```bash mkdir -p ~/.appstoreconnect/private_keys # Copy the .p8 from another machine or your backup cp /path/to/AuthKey_PPATU9GL73.p8 ~/.appstoreconnect/private_keys/ chmod 600 ~/.appstoreconnect/private_keys/AuthKey_PPATU9GL73.p8 ``` --- ## Apple Developer Account | Field | Value | | ----------------- | ------------------------------------------------------------------ | | Team ID | `748N7QPX7J` | | Apple ID | `saravanakumardb1@gmail.com` | | Portal | [developer.apple.com/account](https://developer.apple.com/account) | | App Store Connect | [appstoreconnect.apple.com](https://appstoreconnect.apple.com) | --- ## Registered Apps | Product | Bundle ID | App Store Connect | SKU | Status | | ------------------ | --------------------------------- | ----------------- | ---------- | ------------------------------------------ | | LysnrAI | `com.bytelyst.LysnrAI` | ✅ Created | lysnrai | In TestFlight (build 59) | | ChronoMind | `com.saravana.chronomind` | ❌ Needs creation | chronomind | Bundle ID registered, pending app creation | | ChronoMind Widgets | `com.saravana.chronomind.widgets` | N/A (extension) | — | Bundle ID registered | --- ## App Store Connect — Creating a New App 1. Go to [App Store Connect → My Apps](https://appstoreconnect.apple.com/apps) 2. Click **"+"** → **"New App"** 3. Fill in: - **Platforms:** iOS - **Name:** Product display name (e.g., `ChronoMind`) - **Primary Language:** English (U.S.) - **Bundle ID:** Select from dropdown (must be registered first — see below) - **SKU:** Lowercase product ID (e.g., `chronomind`) - **User Access:** Full Access 4. Click **Create** --- ## Registering a New Bundle ID ### Via API (preferred) ```python import jwt, time, json, urllib.request with open('AuthKey_PPATU9GL73.p8', 'r') as f: key = f.read() token = jwt.encode( {'iss': '1dbc2980-1621-4fb9-940b-e28257e6322c', 'iat': int(time.time()), 'exp': int(time.time()) + 1200, 'aud': 'appstoreconnect-v1'}, key, algorithm='ES256', headers={'kid': 'PPATU9GL73', 'typ': 'JWT'} ) data = json.dumps({'data': {'type': 'bundleIds', 'attributes': { 'identifier': 'com.saravana.PRODUCT', 'name': 'ProductName', 'platform': 'IOS' }}}).encode() req = urllib.request.Request( 'https://api.appstoreconnect.apple.com/v1/bundleIds', data=data, headers={'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'}, method='POST' ) resp = urllib.request.urlopen(req) print(json.loads(resp.read())['data']['id']) ``` ### Via Portal 1. Go to [Certificates, Identifiers & Profiles → Identifiers](https://developer.apple.com/account/resources/identifiers/list) 2. Click **"+"** → **App IDs** → **App** 3. Enter description + bundle ID 4. Enable capabilities (App Groups, Push Notifications, etc.) 5. Click **Register** --- ## TestFlight — Uploading a Build ### Automated (recommended) Each product repo has a `release-testflight.sh` script: ```bash # LysnrAI cd learning_voice_ai_agent/mobile_app/ios # (uses manual pbxproj — see .windsurf/workflows/release-testflight.md) # ChronoMind cd learning_ai_clock/ios bash release-testflight.sh ``` ### Manual CLI ```bash # 1. Archive xcodebuild archive \ -project MyApp.xcodeproj \ -scheme MyApp \ -configuration Release \ -archivePath /tmp/MyApp.xcarchive \ -destination 'generic/platform=iOS' # 2. Export + Upload xcodebuild -exportArchive \ -archivePath /tmp/MyApp.xcarchive \ -exportPath /tmp/MyApp_export \ -exportOptionsPlist ExportOptions.plist \ -allowProvisioningUpdates \ -authenticationKeyPath ~/.appstoreconnect/private_keys/AuthKey_PPATU9GL73.p8 \ -authenticationKeyID PPATU9GL73 \ -authenticationKeyIssuerID 1dbc2980-1621-4fb9-940b-e28257e6322c ``` ### ExportOptions.plist (template) ```xml method app-store-connect teamID 748N7QPX7J destination upload signingStyle automatic uploadSymbols ``` --- ## App Store Submission Checklist Before submitting for App Store review, ensure: ### Required Assets | Asset | Spec | Notes | | ------------------ | ----------------------- | ---------------------------------------- | | App Icon | 1024×1024 PNG | No alpha channel, no rounded corners | | Screenshots (6.7") | 1290×2796 | iPhone 15 Pro Max — required | | Screenshots (6.5") | 1284×2778 | iPhone 14 Plus — required | | Screenshots (5.5") | 1242×2208 | iPhone 8 Plus — optional but recommended | | iPad Screenshots | 2048×2732 | Required if app supports iPad | | App Preview Video | 1920×1080 or device res | Optional, up to 30 seconds | ### Required Metadata | Field | Notes | | ------------------ | ------------------------------------------------ | | App Name | Max 30 characters | | Subtitle | Max 30 characters | | Description | Required, no max (but first 3 lines matter most) | | Keywords | Max 100 characters, comma-separated | | Support URL | Must be a valid, reachable URL | | Privacy Policy URL | **Required** — must be a valid, reachable URL | | Category | Primary + optional secondary | | Age Rating | Answer the questionnaire honestly | | Copyright | e.g., `© 2026 ByteLyst` | ### Required for Review | Requirement | Details | | ---------------------- | --------------------------------------------------------------- | | Privacy Policy URL | Must be publicly accessible | | App Review Information | Contact info (name, phone, email) for reviewer | | Demo Account | If app requires login, provide test credentials | | Notes for Review | Explain any non-obvious features or permissions | | Content Rights | Confirm you have rights to all content | | IDFA Declaration | If using AdSupport framework | | Export Compliance | Encryption usage (most apps: standard encryption = YES, exempt) | ### Privacy & Permissions For each permission your app uses, you must: 1. Add a usage description string in Info.plist (e.g., `NSMicrophoneUsageDescription`) 2. Declare it in App Store Connect → App Privacy Common permissions for ByteLyst apps: | Permission | Info.plist Key | Apps | | ------------------ | ------------------------------------- | ----------------- | | Microphone | `NSMicrophoneUsageDescription` | LysnrAI | | Speech Recognition | `NSSpeechRecognitionUsageDescription` | LysnrAI | | Location | `NSLocationWhenInUseUsageDescription` | PeakPulse | | Health | `NSHealthShareUsageDescription` | PeakPulse, NomGap | | Notifications | `NSUserNotificationsUsageDescription` | All | | Camera | `NSCameraUsageDescription` | MindLyst | ### App Privacy (Data Collection) In App Store Connect → App Privacy, declare: - What data types your app collects - Whether data is linked to user identity - Whether data is used for tracking - Purpose of each data type --- ## TestFlight Beta Testing ### Internal Testing (up to 100 testers) 1. Upload build (see above) 2. Wait ~15-30 min for processing 3. Go to App Store Connect → TestFlight → Internal Testing 4. Add testers by Apple ID email 5. Testers install via TestFlight app ### External Testing (up to 10,000 testers) 1. Create a beta group in TestFlight 2. Add a build to the group 3. Submit for **Beta App Review** (required for external testers) 4. Review takes ~24-48 hours 5. Once approved, distribute via link or email ### Beta App Review Requirements - Same as App Store review but slightly more lenient - Still needs: privacy policy URL, app description, contact info - Crashes or obvious bugs will be rejected --- ## Certificates & Signing | Type | Purpose | Managed By | | ------------------ | ----------------------------- | ------------------------------ | | Apple Development | Debug builds, simulator | Xcode (automatic) | | Apple Distribution | App Store / TestFlight builds | Xcode (automatic with API key) | With `-allowProvisioningUpdates` and the API key, Xcode automatically manages certificates and provisioning profiles. No manual certificate management needed. --- ## Troubleshooting | Error | Fix | | ------------------------------------------- | -------------------------------------------------------- | | `No signing certificate "iOS Distribution"` | Use `-allowProvisioningUpdates` with API key | | `Authentication failed` | Check .p8 key path, Key ID, Issuer ID | | `Error Downloading App Information` | Create app record in App Store Connect first | | `App Groups capability` | Register App Group in developer portal | | `FORBIDDEN_ERROR` on app creation | API key needs Admin role (App Manager can't create apps) | | `Bundle ID not available` | Someone else registered it — use a different one | | `Missing compliance` | Set Export Compliance in App Store Connect | | `Build processing stuck` | Wait up to 1 hour; check email for processing errors |