iOS Client Architecture
Swift workflows, Auth0 login flow, and device-link session management.
The PlanToCode iOS app is a companion client that connects to linked desktop sessions. It provides mobile access to terminal output, job status, and voice transcription while maintaining the desktop as the primary planning workspace.
iOS app interface
Screenshots of the iOS app showing device linking and terminal view.
Swift Package Structure
The iOS app is organized into Swift packages:
Core
mobile/ios/Core/Business logic and API clients
- WorkflowManager
- APIClient
- MobileSessionManager
- DeviceLinkClient
Security
mobile/ios/Security/Authentication and credential storage
- Auth0Manager
- KeychainHelper
- TokenStore
VibeUI
mobile/ios/VibeUI/SwiftUI components and design system
- TerminalView
- JobListView
- SettingsView
- DeviceLinkView
Auth0 PKCE Integration
The iOS app uses Auth0 with PKCE flow for secure authentication:
Authentication Flow
- User taps Sign In, app generates code verifier and challenge
- ASWebAuthenticationSession opens Auth0 login page
- User authenticates and Auth0 redirects with authorization code
- App exchanges code for tokens using code verifier
- Tokens stored securely in iOS Keychain
Token Management
- Access token used for API requests
- Refresh token stored for silent renewal
- Token refresh triggered before expiry
- Logout clears all tokens from Keychain
Device Linking via WebSocket Relay
iOS connects to desktop sessions through the server's WebSocket relay:
Linking Protocol
- Desktop generates link code and displays QR
- iOS scans QR or enters code manually
- Both connect to /ws/device-link with credentials
- Server validates and establishes relay
- Bidirectional communication enabled
Message Types
- terminal_output: PTY output from desktop terminal
- job_status: Background job status updates
- session_sync: Session state synchronization
- rpc_command: Commands from mobile to desktop
Reconnection Handling
The WebSocket connection handles network interruptions with automatic reconnection, exponential backoff, and session state recovery.
RPC Command Routing
iOS can send commands to the linked desktop:
Supported Commands
send_terminal_input: Send keystrokes to terminalrequest_job_status: Get status of specific jobstart_voice_transcription: Begin recording on mobilesync_session: Request full session state
Implementation
Commands are JSON-RPC messages sent over WebSocket. Desktop validates commands and returns results asynchronously.
Offline Action Queue
Actions performed while disconnected are queued for sync:
Queue Architecture
- Actions stored in local SQLite database
- Queue processed on reconnection
- Conflicts resolved with server timestamps
- Failed actions reported to user
Supported Offline Actions
- Voice transcription recording (stored locally)
- Session notes and annotations
- Preference changes
SQLite Local Storage
iOS uses SQLite for local persistence:
Database Schema
~/Documents/plantocode.sqlite- linked_devices: Desktop connections
- offline_queue: Pending sync actions
- cached_sessions: Recent session data
- transcriptions: Local voice recordings
Migrations
Schema version tracked in user_version pragma. Migrations run on app launch.
Mobile Sessions
MobileSessionManager coordinates session state:
Session Lifecycle
- Load last active session on launch
- Connect to linked desktop if available
- Subscribe to session updates via WebSocket
- Cache session data for offline access
Workflow Entry Points
Key workflows accessible from mobile:
- Terminal monitoring: View output, send input
- Job status: Track background job progress
- Voice capture: Record and transcribe on mobile
- Session browsing: Review plans and history
Region Settings
iOS respects user region preference for API routing:
Region stored in UserDefaults, used to select api-eu.plantocode.com or api-us.plantocode.com for all requests.