Ship iOS app by wrapping the web build with Capacitor #21

Closed
opened 2026-07-26 04:52:01 -07:00 by westfarn · 1 comment
Owner

Goal

Publish an iOS app for chat.aimloperations.com that runs the existing CRA build inside a Capacitor WKWebView, sharing the llm-fe/ codebase with web and Android.

Depends on

#20 (Android) — the shared Capacitor scaffolding lands there: capacitor.config.ts, webDir: build, mobile env handling, auth/CORS fixes, and router changes. This ticket adds the ios/ platform on top of that.

Approach

cd llm-fe
npm i @capacitor/ios
npm run build && npx cap add ios && npx cap sync ios
npx cap open ios

Requires macOS with Xcode plus CocoaPods; note that our CI runners are Linux, so iOS builds are manual (or need a Mac/hosted mac runner) until we decide otherwise.

Scope

  • Add @capacitor/ios, commit the generated ios/ project, gitignore Pods/build artifacts.
  • Bundle identifier com.aimloperations.chat, matching display name and version/build numbering with Android.
  • Confirm backend access from WKWebView: the app origin is capacitor://localhost by default, so backend CORS/CSRF trusted origins must accept it (chat_backend change). WKWebView is stricter than Android about third-party cookies, so header-based JWT is likely required rather than cookie CSRF.
  • Verify the wss:// chat socket survives suspend/resume and cellular-to-WiFi switches; iOS kills sockets on background more aggressively than Android.
  • Safe-area insets (notch/Dynamic Island/home indicator), keyboard avoidance, and disabling rubber-band overscroll so the MUI chat layout looks native.
  • App icon set + launch screen via @capacitor/assets; light and dark variants.
  • Manual QA on a physical iPhone and simulator: login, password reset, chat streaming, markdown/code blocks, recharts charts, theme switching, text selection/copy in code blocks.
  • Signing: Apple Developer Program membership, App ID, provisioning profiles, distribution certificate. Keep credentials out of the repo.
  • TestFlight internal build, then App Store submission.
  • App Review readiness: privacy policy URL, App Privacy questionnaire, account-deletion path (Apple requires in-app account deletion if the app supports sign-up), and enough native value that it is not rejected as a repackaged website under guideline 4.2.

Out of scope

Push notifications, offline caching, Sign in with Apple, and other native-only features. Follow-ups after the wrapper ships.

## Goal Publish an iOS app for chat.aimloperations.com that runs the existing CRA build inside a Capacitor WKWebView, sharing the `llm-fe/` codebase with web and Android. ## Depends on #20 (Android) — the shared Capacitor scaffolding lands there: `capacitor.config.ts`, `webDir: build`, mobile env handling, auth/CORS fixes, and router changes. This ticket adds the `ios/` platform on top of that. ## Approach ```bash cd llm-fe npm i @capacitor/ios npm run build && npx cap add ios && npx cap sync ios npx cap open ios ``` Requires macOS with Xcode plus CocoaPods; note that our CI runners are Linux, so iOS builds are manual (or need a Mac/hosted mac runner) until we decide otherwise. ## Scope - [ ] Add `@capacitor/ios`, commit the generated `ios/` project, gitignore Pods/build artifacts. - [ ] Bundle identifier `com.aimloperations.chat`, matching display name and version/build numbering with Android. - [ ] Confirm backend access from WKWebView: the app origin is `capacitor://localhost` by default, so backend CORS/CSRF trusted origins must accept it (`chat_backend` change). WKWebView is stricter than Android about third-party cookies, so header-based JWT is likely required rather than cookie CSRF. - [ ] Verify the `wss://` chat socket survives suspend/resume and cellular-to-WiFi switches; iOS kills sockets on background more aggressively than Android. - [ ] Safe-area insets (notch/Dynamic Island/home indicator), keyboard avoidance, and disabling rubber-band overscroll so the MUI chat layout looks native. - [ ] App icon set + launch screen via `@capacitor/assets`; light and dark variants. - [ ] Manual QA on a physical iPhone and simulator: login, password reset, chat streaming, markdown/code blocks, `recharts` charts, theme switching, text selection/copy in code blocks. - [ ] Signing: Apple Developer Program membership, App ID, provisioning profiles, distribution certificate. Keep credentials out of the repo. - [ ] TestFlight internal build, then App Store submission. - [ ] App Review readiness: privacy policy URL, App Privacy questionnaire, account-deletion path (Apple requires in-app account deletion if the app supports sign-up), and enough native value that it is not rejected as a repackaged website under guideline 4.2. ## Out of scope Push notifications, offline caching, Sign in with Apple, and other native-only features. Follow-ups after the wrapper ships.
westfarn added a new dependency 2026-07-26 04:55:51 -07:00
Author
Owner

Set as Gitea issue dependencies (Dependencies panel in the sidebar):

  • #22 auth from a Capacitor WebView origin (JWT-only, CORS/CSRF for capacitor://localhost)
  • #23 chat WebSocket resilience across background/resume and network switches
  • #24 routing from a file-served bundle (React Router 6 under Capacitor)
  • #20 Android wrapper, which lands the shared Capacitor scaffolding this ticket builds on

Gitea will block closing this issue until all four are closed.

Set as Gitea issue dependencies (Dependencies panel in the sidebar): - #22 auth from a Capacitor WebView origin (JWT-only, CORS/CSRF for `capacitor://localhost`) - #23 chat WebSocket resilience across background/resume and network switches - #24 routing from a file-served bundle (React Router 6 under Capacitor) - #20 Android wrapper, which lands the shared Capacitor scaffolding this ticket builds on Gitea will block closing this issue until all four are closed.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Reference: ai_ml_operations/chat_web_app#21