Parity with the Android client: drop the "Allow self-signed certificate" escape hatch. The app now performs system TLS trust only — a self-signed appliance must have its CA installed on the device (MDM/profile). A code-only public-key pinning policy remains (no UI). - ServerTrustEvaluator: remove ServerTrustPolicy.allowSelfSignedForHost and its challenge handler; keep .system (default) and .pinPublicKeySHA256. - SettingsView: remove the self-signed toggle/state/prefill; makeConfig uses the default .system policy. - MCMSConnection / APIConfiguration: update usage-sketch + doc comments. - README / GUI-NOTES / MCMS_API.md: document system-trust-only; self-signed boxes need their CA installed on the device. - Add CHANGELOG.md for this session, flagged for the Android port. Note: configs previously persisted with the self-signed policy fail to decode and reset to defaults (one-time re-entry of the server URL). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
76 lines
3.3 KiB
Markdown
76 lines
3.3 KiB
Markdown
# MCMS Mobile — GUI scaffold notes
|
|
|
|
The SwiftUI layer sits on top of the networking core from the kickoff brief. It's
|
|
a working skeleton you run against a live MCMS box, then refine.
|
|
|
|
## Layout
|
|
|
|
```
|
|
App/ MCMSMobileApp (@main), RootView routing, AppEnvironment
|
|
UI/ Shared components (badges, count tiles, load/error states, LoadPhase)
|
|
Features/
|
|
Settings/ Connection config + test (direct or proxy; system TLS trust only)
|
|
Login/ Email/password, Keychain prefill
|
|
Dashboard/ Device + alarm counts (VM + View)
|
|
ONUList/ Searchable ONU list (VM + View)
|
|
ONUDetail/ Stats / Config / Alarms / Logs tabs + Reset op (VM + View)
|
|
```
|
|
|
|
Flow: `RootView` shows **Settings** until a connection is configured, then
|
|
**Login**, then the main **TabView**. `AppEnvironment` owns the `MCMSConnection`,
|
|
persists the (non-secret) `APIConfiguration` to `UserDefaults`, and keeps
|
|
credentials in the Keychain.
|
|
|
|
## Putting it in Xcode
|
|
|
|
1. New iOS App (SwiftUI lifecycle), **deployment target iOS 17.0+**, built with
|
|
**Xcode 26 (iOS 26 SDK)**. The 26 SDK is required for App Store / TestFlight
|
|
submission and makes standard components adopt the Liquid Glass look on iOS 26
|
|
devices automatically — no code and no opt-out flag needed; the UI here is stock.
|
|
2. Delete the template `ContentView.swift` and the generated `App` struct — this
|
|
scaffold provides its own `@main` in `App/MCMSMobileApp.swift`.
|
|
3. Add the whole `MCMSMobile/` tree (networking core + this GUI). One module,
|
|
no external dependencies.
|
|
|
|
The view models use the `@Observable` macro and views use `@State`/`@Environment`
|
|
(iOS 17+). If you ever need to drop below iOS 17, revert those to
|
|
`ObservableObject`/`@Published` + `@StateObject`/`@EnvironmentObject` and
|
|
reinstate a `ContentUnavailableView` shim.
|
|
|
|
## App Transport Security (the gotcha)
|
|
|
|
TLS uses **system trust only** — there is no self-signed bypass. (Historical note:
|
|
an earlier build had a `ServerTrustEvaluator` self-signed toggle; it was removed for
|
|
parity with Android.) ATS is separate and can still block the connection:
|
|
|
|
- **HTTPS to a self-signed host:** the connection FAILS unless the host's CA is
|
|
installed on the device (MDM/configuration profile). Keep TLS 1.2+.
|
|
- **Plain HTTP** (no TLS) or weak TLS: ATS blocks it by default. Add a *scoped*
|
|
exception for your host in Info.plist rather than a blanket allow:
|
|
|
|
```xml
|
|
<key>NSAppTransportSecurity</key>
|
|
<dict>
|
|
<key>NSExceptionDomains</key>
|
|
<dict>
|
|
<key>10.2.10.29</key>
|
|
<dict>
|
|
<key>NSExceptionAllowsInsecureHTTPLoads</key><true/>
|
|
<key>NSIncludesSubdomains</key><false/>
|
|
</dict>
|
|
</dict>
|
|
</dict>
|
|
```
|
|
|
|
Avoid `NSAllowsArbitraryLoads`. Behind a proxy with a real cert, you need none of
|
|
this and should set the trust policy to `.system`.
|
|
|
|
## Known TODOs carried from the core
|
|
|
|
- Confirm `/api/v1` vs `/v1` and the `databases/selection` body key.
|
|
- The Mongo-document field accessors (ONU state/parent OLT, alarm severity/time,
|
|
stat counter keys) are best-effort guesses marked `// TODO` — pin them to the
|
|
real `openapi.json` and a live response. The Config tab's `JSONTreeView` shows
|
|
the full raw document, which helps you discover the true field paths quickly.
|
|
- Stats tab lists the latest sample's numeric counters; wire a chosen counter
|
|
into Swift Charts once the keys are known.
|