docs: add research docs for iOS app, Mac desktop, plugin security
- iOS: Capacitor vs WKWebView vs React Native WebView analysis - Mac: Tauri v2 vs Electron comparison with menu bar app patterns - Plugins: Signature validation, sandboxed iframes, permission system Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
290aa047d7
commit
4ac18cedb6
@@ -0,0 +1,113 @@
|
||||
# iOS App Research — AIUI
|
||||
|
||||
## Overview
|
||||
|
||||
Three approaches for shipping AIUI (Vue 3 + Vite SPA) as an iOS app.
|
||||
|
||||
## Approach 1: Capacitor (Recommended)
|
||||
|
||||
Capacitor wraps the Vite build output (`dist/`) in a native iOS Xcode project. The web app runs inside WKWebView with a JavaScript bridge to native device APIs.
|
||||
|
||||
```bash
|
||||
pnpm add @capacitor/core @capacitor/cli @capacitor/ios
|
||||
npx cap init && npx cap add ios
|
||||
pnpm build && npx cap sync
|
||||
npx cap open ios # opens Xcode
|
||||
```
|
||||
|
||||
**Pros:**
|
||||
- Near-zero code changes to existing Vue 3 app — one codebase for web + iOS + Android
|
||||
- Large, mature plugin ecosystem (camera, biometrics, push, geolocation, haptics)
|
||||
- Hot reload during dev via `npx cap run ios --livereload`
|
||||
- OTA live updates possible via Capgo, bypassing App Store review for JS changes
|
||||
- `@capacitor/push-notifications` wraps APNs natively
|
||||
|
||||
**Cons:**
|
||||
- Service workers do NOT work in WKWebView on iOS (capacitor:// protocol breaks SW registration)
|
||||
- Performance ceiling is WebKit JS engine (not V8)
|
||||
- Each iOS SDK bump requires Capacitor + plugin updates
|
||||
|
||||
**Push Notifications:** Full support via `@capacitor/push-notifications` (APNs). Production-grade.
|
||||
|
||||
**Offline:** Entire app bundle ships inside .ipa — available offline. Dynamic data must use `@capacitor/preferences` or local SQLite. Workbox/SW caching does not work.
|
||||
|
||||
**Performance:** Modern WKWebView uses Nitro JS engine (same as Safari). For a chat UI like AIUI, indistinguishable from Safari. GPU-accelerated CSS transforms work well.
|
||||
|
||||
## Approach 2: Custom WKWebView Swift Wrapper
|
||||
|
||||
Write a native Swift/SwiftUI app embedding WKWebView. Use `WKScriptMessageHandler` for JS↔Swift communication.
|
||||
|
||||
**Pros:**
|
||||
- Maximum native control — own the shell, native navigation, gestures
|
||||
- Can implement App Clips, Share Extensions, Widgets alongside web content
|
||||
- Full access to all iOS APIs at the native layer
|
||||
|
||||
**Cons:**
|
||||
- Requires Swift knowledge — adds second language + build system
|
||||
- JS↔Swift bridge must be hand-written for every integration
|
||||
- No structured plugin community; each integration is bespoke
|
||||
- More setup friction vs Capacitor
|
||||
|
||||
**Push/Offline/Performance:** Same as Capacitor (all use WKWebView). More manual setup.
|
||||
|
||||
## Approach 3: React Native WebView
|
||||
|
||||
Create a React Native app with `react-native-webview` rendering the Vite build output.
|
||||
|
||||
**Pros:**
|
||||
- RN has deep native API access and large ecosystem
|
||||
- Surrounding shell can be fully native
|
||||
|
||||
**Cons:**
|
||||
- Two separate tech stacks (Vue + RN) — highest maintenance burden
|
||||
- No code sharing between Vue app and RN shell
|
||||
- Performance often worse (full RN runtime + WebView engine)
|
||||
- RN's own breaking changes cadence adds risk
|
||||
|
||||
**Verdict:** Only justified if an existing RN app is already in production.
|
||||
|
||||
## App Store Risk: Guideline 4.2
|
||||
|
||||
Apple's Guideline 4.2 (Minimum Functionality) is the primary risk for all webview-based apps. Apps that pass share these traits:
|
||||
- Native tab bar or navigation (not web-based menus)
|
||||
- At least one native API integration (push, biometrics, camera, Apple Pay)
|
||||
- Offline functionality beyond what a browser bookmark offers
|
||||
- UI formatted for iOS, not a desktop website in a phone frame
|
||||
|
||||
For AIUI: the chat interface, push notifications, and offline message history constitute sufficient native functionality.
|
||||
|
||||
## Service Workers in WKWebView
|
||||
|
||||
**SWs do not run inside WKWebView** — this is a fundamental WebKit limitation, not framework-specific. The correct offline strategy for all three approaches: ship assets in app bundle + implement dynamic caching via native storage APIs.
|
||||
|
||||
## Deep Linking
|
||||
|
||||
All three support iOS Universal Links via AASA file + Associated Domains capability:
|
||||
- **Capacitor:** `@capacitor/app` `appUrlOpen` event → Vue Router
|
||||
- **Custom WKWebView:** `AppDelegate.application(_:continue:...)` → JS evaluation
|
||||
- **RN:** React Navigation linking config → WebView `postMessage`
|
||||
|
||||
## Comparison
|
||||
|
||||
| Dimension | Capacitor | Custom WKWebView | RN WebView |
|
||||
|---|---|---|---|
|
||||
| Vue code reuse | 100% | 100% | 100% |
|
||||
| Native shell effort | Low | High | Very high |
|
||||
| Push notifications | First-class | Manual APNs | Via RN layer |
|
||||
| App Store risk | Moderate* | Moderate* | Moderate* |
|
||||
| Performance | Good | Good | Adequate |
|
||||
| Maintenance burden | Low-moderate | High | Very high |
|
||||
| Team fit (web-first) | Best | Poor | Poor |
|
||||
|
||||
*All face identical Guideline 4.2 scrutiny — framework choice is irrelevant to reviewers.
|
||||
|
||||
## Concrete Next Steps
|
||||
|
||||
1. Add `@capacitor/core`, `@capacitor/cli`, `@capacitor/ios` to `packages/app`
|
||||
2. Set Vite `base: './'` for the Capacitor build config
|
||||
3. Disable PWA service worker for native builds (partially done already)
|
||||
4. Add `@capacitor/push-notifications` for APNs
|
||||
5. Implement native splash screen and app icon
|
||||
6. Test on iOS Simulator via `npx cap run ios`
|
||||
7. Set up Apple Developer account + code signing
|
||||
8. Submit TestFlight build for internal testing
|
||||
Reference in New Issue
Block a user