112 lines
4.1 KiB
Markdown
112 lines
4.1 KiB
Markdown
# 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
|