4.1 KiB
iOS (Capacitor)
Ship the CRA web build as an iOS app via Capacitor
WKWebView. One codebase: llm-fe/ → web + Android + iOS.
Build & Xcode steps: 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 cocoapodsor Homebrewpod) - 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
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/:
npm run ios:sync
Always open the .xcworkspace, not the .xcodeproj (CocoaPods).
Environment
Same as Android — see 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:
npm run assets:generate
Signing
Never commit certificates, profiles, or .p12 files.
- Xcode → Signing & Capabilities → Team (Automatic for debug / internal).
- Bundle ID:
ai.hesychia.chat(matches AndroidapplicationId/ CapacitorappId). - 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):
- Apple Developer Program + App ID
ai.hesychia.chat - Privacy policy URL + App Privacy questionnaire
- In-app account deletion if sign-up is offered (guideline)
- Enough native shell value that review does not reject as 4.2 “repackaged website”
- Archive → Upload → TestFlight internal → App Store
Push notifications, offline cache, Sign in with Apple — out of scope for this wrap.