Files
chat_web_app/llm-fe/IOS.md
T
westfarn 5c70bb4b2d
Unit Tests / test (pull_request) Successful in 11s
closess #22
2026-08-03 14:12:23 -05:00

4.1 KiB
Raw Blame History

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 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

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.

  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 ↔ WiFi 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.

  • #21 — this iOS wrap
  • #20 — Android scaffolding
  • #22 / #23 / #24 — auth / WS / routing