iOS mobile client
Native Swift + SwiftUI app in ios-app/.
Auth and API
| Mechanism | Detail |
|---|---|
| REST | Same /api/* routes as web (server.ts, lib/walletTransportRoutes.ts) |
| Session | Cookie omnitrack.sid via HTTPCookieStorage + persisted cookie lines in UserDefaults |
| Realtime | Socket.io /socket.io (session cookie in extraHeaders; no Bearer JWT) |
| Client header | X-OmniTrack-Client: ios |
| Routing | GET /api/routing/drive via RoutingRepository / OsrmClient.swift |
Wallet / Mollie
POST /api/wallet/top-up/mollie accepts optional body field redirectUrl (base deep link, e.g. omnitransitiq://wallet). Server appends ?walletIntent=<id>.
Fallback when header is ios and no redirectUrl: env MOBILE_WALLET_REDIRECT_SCHEME (default omnitransitiq://wallet).
Checkout opens in SFSafariViewController; return via URL scheme registered in Info.plist.
Roles and UI (native iOS)
| Role | Shell |
|---|---|
driver | Modern sidebar sheet (DriverShell.swift), default Home |
| Others | Home default + OmniSidebarModern sheet (DashboardShell.swift) |
Post-login chrome (Android parity):
OmniSidebarModern+OmniAppTopBarinCommonUI.swift- Thin SF Symbol icons via
OmniIcons.swift HomeScreen.swift— stats + quick actionsRoutePlannerScreen.swift+NavigationMode.swift— in-app navigation (no Apple Maps redirect)- Map — Carto Positron Light
Resources/map-style.json
Nav visibility follows the same rules as web (src/App.tsx) and Android (Authz.swift).
i18n
Locales in ios-app/OmniTrack/Resources/locales/, synced from src/locales/*.json via ios-app/scripts/sync-locales.mjs. Home keys: dashboard.home*; navigation: nav.*.
Local dev
docker compose upon host (port 3000)- Simulator:
http://localhost:3000in login advanced settings - Physical device: Mac LAN IP
Project generation
Xcode project is generated from ios-app/project.yml via XcodeGen:
cd ios-app && xcodegen generate && open OmniTrack.xcodeproj
App Store compliance
| Requirement | Implementation |
|---|---|
| Privacy manifest | OmniTrack/PrivacyInfo.xcprivacy |
| In-app privacy + deletion URLs | OmniSidebarModern in CommonUI.swift |
| Account deletion | DELETE /api/auth/me via AppViewModel.deleteMyAccount() |
| Encryption declaration | ITSAppUsesNonExemptEncryption = false |
| Usage descriptions | Location (map + in-app navigation), photo library, camera in Info.plist |
| Release demo logins hidden | AppConfig.hideDemoLogins (#if DEBUG) |
| Review account | demo@demo.be / test123! — see APP-STORE-SETUP.md |
CI
Optional workflow: .github/workflows/ios-app.yml (macOS + xcodebuild).
References
ios-app/README.md- Android twin:
mobile-android.md