# iOS (Capacitor) Ship the CRA web build as an iOS app via [Capacitor](https://capacitorjs.com/) WKWebView. One codebase: `llm-fe/` → web + Android + iOS. **Build & Xcode steps:** [`ios/README.md`](ios/README.md). Prerequisites already merged: JWT-only auth (#22), WebSocket lifecycle (#23), HashRouter (#24), Android Capacitor scaffolding (#20). ## Prerequisites - **macOS** with **Xcode** 15+ (CI runners are Linux — iOS builds are **manual** on a Mac until a hosted macOS runner is added) - **Node.js 20** (matches CI; Capacitor **7.x**) - **CocoaPods** (`sudo gem install cocoapods` or Homebrew `pod`) - Apple Developer Program membership for device / TestFlight / App Store signing (simulator debug runs without a paid membership using automatic signing) ## One-time / day-to-day ```bash cd llm-fe npm ci npm run build:mobile # .env.mobile → CRA build → cap sync (android + ios) npm run ios:open # opens ios/App/App.xcworkspace in Xcode ``` Or sync only after an existing `build/`: ```bash npm run ios:sync ``` **Always open the `.xcworkspace`**, not the `.xcodeproj` (CocoaPods). ## Environment Same as Android — see [`ANDROID.md`](ANDROID.md) § Environment. | File | Purpose | |------|---------| | `.env.mobile` | Endpoints baked into the **mobile** bundle (`build:mobile`) | | `.env.mobile.local` | Optional gitignored override | Default `.env.mobile` points at production (`chatbackend.aimloperations.com`). WebView origin is `capacitor://localhost`. Backend CORS/CSRF already trusts it (`chat_backend` `CAPACITOR_WEBVIEW_ORIGINS`). Auth is header JWT — no cookies. ## Versioning In Xcode target **App** → General, or `ios/App/App.xcodeproj/project.pbxproj`: | Field | Xcode / build setting | Align with | |-------|----------------------|------------| | Version | `MARKETING_VERSION` (`CFBundleShortVersionString`) | `package.json` `version` + Android `versionName` (currently `0.1.0`) | | Build | `CURRENT_PROJECT_VERSION` (`CFBundleVersion`) | Android `versionCode` (integer; **must increase** every TestFlight / App Store upload) | ## Icons / splash Source art in `llm-fe/assets/` (same as Android): - `icon.png` / `splash.png` / `splash-dark.png` Regenerate iOS + Android densities: ```bash npm run assets:generate ``` ## Signing **Never commit certificates, profiles, or `.p12` files.** 1. Xcode → Signing & Capabilities → Team (Automatic for debug / internal). 2. Bundle ID: **`ai.hesychia.chat`** (matches Android `applicationId` / Capacitor `appId`). 3. For distribution: App Store Connect app, distribution cert, provisioning profile — keep credentials outside the repo (password manager / CI secrets later). ## Manual QA checklist On **simulator and physical iPhone**: - [ ] Login / logout / password reset - [ ] Chat streaming + markdown / code blocks (selection + copy) - [ ] Charts (`recharts`) - [ ] Dark / light theme - [ ] Keyboard does not cover compose input; notch / Dynamic Island / home indicator OK - [ ] No rubber-band overscroll on chat shell - [ ] Background → resume keeps or reconnects WebSocket (`appStateChange` + visibility) - [ ] Cellular ↔ Wi‑Fi switch reconnects socket - [ ] Airplane mode → restore reconnects ## TestFlight / App Store (follow-on) Out of band (not automated here; separate deploy tickets): 1. Apple Developer Program + App ID `ai.hesychia.chat` 2. Privacy policy URL + App Privacy questionnaire 3. In-app account deletion if sign-up is offered (guideline) 4. Enough native shell value that review does not reject as 4.2 “repackaged website” 5. Archive → Upload → TestFlight internal → App Store Push notifications, offline cache, Sign in with Apple — out of scope for this wrap. ## Related issues - [#21](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/21) — this iOS wrap - [#20](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/20) — Android scaffolding - [#22](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/22) / [#23](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/23) / [#24](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/24) — auth / WS / routing