Native Apps Architecture (Apple-First)
Native Apps Architecture (Apple-First) OpenMates ships a fully native universal app across the Apple ecosystem — iPhone, iPad, Mac, and (later) an independen...
Native Apps Architecture (Apple-First)
OpenMates ships a fully native universal app across the Apple ecosystem — iPhone, iPad, Mac, and (later) an independent Apple Watch app and Apple Vision Pro — built with Swift 6 and SwiftUI. The native app lives in the monorepo under
apple/and shares design tokens from the frontend pipeline.
Why Native, Apple-First
The web app at openmates.org remains the primary surface and gets new
features first. Native apps exist to deliver a polished, high-trust
experience on devices where users expect deep OS integration:
- Local Keychain-backed E2EE key storage; OpenMates never syncs keys through Apple services
- Native push notifications (APNs), Live Activities, Widgets, Shortcuts
- Handoff between iPhone / iPad / Mac
- Face ID / Touch ID for hidden chats and sensitive actions
- Independent Apple Watch usage without a tethered iPhone (long-term goal)
We use SwiftUI as Apple’s unified cross-device UI framework: one Xcode project targets iOS, iPadOS, macOS, watchOS, and visionOS with 70-90% shared code. This gives us multiple high-quality native clients from a single codebase.
Android and other platforms are explicitly out of scope for this phase.
Technology Choices
| Layer | Choice | Notes |
|---|---|---|
| Language | Swift 6 | Strict concurrency, memory safety |
| UI | SwiftUI | Declarative, adapts per platform |
| Persistence | SwiftData | Modern Core Data replacement |
| Networking | URLSession + URLSessionWebSocketTask |
Native WebSockets for phased sync |
| Secrets | Local Keychain only | E2EE key storage for this app install; multi-device sync uses OpenMates key material only |
| Passkeys | ASAuthorizationController |
Native Face ID / Touch ID auth |
| Build | Xcode multiplatform + XcodeGen | project.yml → .xcodeproj |
Repository Layout (Monorepo)
The native app lives in the existing OpenMates monorepo under apple/.
Design tokens are generated from the same YAML sources as the web app
and imported directly into the Xcode project.
OpenMates/
├── apple/ # Xcode project root
│ ├── project.yml # XcodeGen spec (generates .xcodeproj)
│ ├── .gitignore # Excludes .xcodeproj, build artifacts
│ └── OpenMates/
│ ├── Sources/
│ │ ├── App/ # Entry point, RootView, MainAppView
│ │ ├── Core/
│ │ │ ├── Networking/ # APIClient, WebSocketManager
│ │ │ ├── Crypto/ # CryptoManager, KeychainHelper
│ │ │ ├── Persistence/ # SwiftData stores (TODO)
│ │ │ └── Models/ # AuthModels, ChatModels
│ │ ├── Features/
│ │ │ ├── Auth/ # Login flow views + AuthManager
│ │ │ ├── Chat/ # Chat list + chat view
│ │ │ └── Settings/ # Settings view
│ │ └── Shared/
│ │ ├── Components/ # OMButtonStyles, AppIconView
│ │ └── Extensions/ # Data, Color, ThemeManager
│ ├── Resources/ # Info.plist, entitlements
│ ├── iOS/ # iPhone/iPad-specific (future)
│ └── macOS/ # Mac-specific (future)
├── frontend/
│ └── packages/ui/src/tokens/
│ ├── sources/*.yml # Token source of truth
│ └── generated/swift/ # Auto-generated Swift files + xcassets
│ ├── ColorTokens.generated.swift
│ ├── TypographyTokens.generated.swift
│ ├── SpacingTokens.generated.swift
│ ├── GradientTokens.generated.swift
│ ├── IconMapping.generated.swift
│ ├── ComponentTokens.generated.swift
│ ├── Tokens.generated.swift
│ ├── Assets.xcassets/ # 18 theme-aware color sets
│ └── Icons.xcassets/ # 202 custom SVG icons
The .xcodeproj is git-ignored — regenerate with cd apple && xcodegen generate.
Platform-specific code uses #if os(iOS) / #if os(macOS) conditionals.
Design Token Integration
The token pipeline (pnpm --filter @repo/ui build:tokens) generates Swift
outputs alongside CSS and TypeScript from the same YAML sources. The Xcode
project references these generated files directly — no manual copying.
Available in Swift code:
Color.grey0,Color.fontPrimary,Color.buttonPrimary(18 theme-aware)LinearGradient.appAi,.appHealth,.primary(50+ app gradients)Font.omH1through.omMicro(12 typography scales with pt values)CGFloat.spacing4,.radius3,.iconSizeMd(spacing, radii, icon sizes)Image.iconOpenmates,.iconChat,.iconAi(202 custom icons)SFSymbol.bell,.chevronLeft(31 Lucide → SF Symbol mappings)DS.SnippetCard,DS.LoadingText(component primitives)
Rollout Phases
Phase 1: Login + Core Chat (iPhone MVP) — IN PROGRESS
Scope: Login → chat list → single chat → streaming AI responses. Signup links to web app.
Login flow (native SwiftUI):
- Email lookup (
EmailLookupView→/v1/auth/lookup) - Password + 2FA (
PasswordLoginView→/v1/auth/login) - Passkey (
PasskeyLoginView→ASAuthorizationController) - Recovery key (
RecoveryKeyView→/v1/auth/login) - Backup code (
BackupCodeView→/v1/auth/login) - Device verification (
DeviceVerificationView→/v1/auth/2fa/verify/device)
Signup: Opens SFSafariViewController → openmates.org/signup
Chat: NavigationSplitView with sidebar chat list + detail chat view.
Streaming responses via WebSocket. Message bubbles with user/assistant styling.
Payment: Links to web app for credit purchases.
Phase 2: iPad + Mac Polish
Mostly layout — NavigationSplitView adapts automatically. Mac additions:
menu bar commands, keyboard shortcuts (⌘N new chat), window management.
Phase 3: Native Signup (except payment)
Port all 13 signup steps to native SwiftUI. Passkeys will be better natively
(ASAuthorizationController vs WebAuthn JS). Payment step → SFSafariViewController
to web Stripe checkout, or Apple IAP as alternative payment method.
Phase 4: watchOS + visionOS
Standalone watch app with voice-first interface. visionOS when there’s demand.
What Has to Be Ported From the Web App
In rough order of effort:
- E2EE key lifecycle —
ChatKeyManager→ Apple CryptoKit + local Keychain only. OpenMates does not use Apple cloud storage for keys. See core/client-side-encryption.md. - Phased sync protocol — 3-phase WebSocket sync →
URLSessionWebSocketTask. See data/sync.md. - Embed renderers — 30+ embed types → SwiftUI equivalents for top 10,
WKWebViewfallback for the rest. Largest porting effort. - Markdown / message rendering — inline embeds, code blocks, links.
- PII protection — client-side detection + placeholder rendering.
The backend is platform-agnostic and needs no changes.
Development Workflow
- Xcode runs only on macOS. Contributors need a Mac (Apple Silicon recommended).
- Paid Apple Developer Program required for device testing, push, and distribution.
- XcodeGen keeps project config version-controlled:
cd apple && xcodegen generate. - Design tokens auto-update: run
pnpm --filter @repo/ui build:tokensafter editing YAML sources — Swift files regenerate alongside CSS/TS. - Signing & provisioning managed through Xcode GUI and developer.apple.com.
Out of Scope
- Android, Windows, and Linux native clients
- React Native / Flutter / Kotlin Multiplatform
- Catalyst (iPad app running on Mac) — we prefer a true macOS target
- Backend changes specific to native clients
Related Docs
- Web App — current primary client
- Design Tokens — unified token system (web + native)
- Sync — phased WebSocket sync to port
- Client-Side Encryption — E2EE to port
- Master Key Lifecycle — Keychain mapping
- Embeds — embed system to reimplement