# PON Go — iOS Native iOS app for Ciena **MCMS 6.2 PON Manager** basics on the go — dashboard, ONU and OLT browsing/diagnostics, firmware updates, resets. SwiftUI + URLSession, no external dependencies. Sibling of the Android app (`../mcms_android`); the REST behaviour and field paths are identical and documented in [`MCMS_API.md`](MCMS_API.md). App name **PON Go** (Xcode project/target is currently `SVO_MCMS`). ## ⚠️ Source layout — read this first This folder holds the **canonical flat Swift sources** (plus docs, the app icon, and the dev-guide PDFs). The actual **Xcode project lives elsewhere** (`~/Documents/mcms_ios_xcode/run/SVO_MCMS/`); the workflow so far has been to **copy changed `.swift` files into the Xcode project** and build there. For a clean git repo, **consolidate**: move these `.swift` files + `Assets.xcassets/` into the Xcode project directory, make *that* the iOS repo (with `docs/MCMS_API.md` and the PDFs alongside), and drop the copy-sync dance. Until then, this folder is the source of truth — edit here, copy into Xcode. ## Build (Xcode) - **Xcode 26 (iOS 26 SDK)**, deployment target **iOS 17+**. New iOS App (SwiftUI lifecycle); delete the template `ContentView.swift` / generated `App` struct (this scaffold provides its own `@main` in `MCMSMobileApp.swift`). - **Build Settings → Default Actor Isolation → `nonisolated`.** Xcode 26 defaults this to MainActor, which makes the pure-data types (`APIQuery.empty`, `JSONValue: Equatable`, …) emit ~8 main-actor warnings (errors under Swift 6 mode). The code is designed nonisolated-by-default; only UI/stateful classes are explicitly `@MainActor`. - **App name / icon:** set the target's **Display Name → "PON Go"**, and drag `Assets.xcassets/AppIcon.appiconset` into the project's asset catalog (replacing the existing AppIcon). - **App Transport Security:** the app uses **system TLS trust only** — there is no self-signed bypass (parity with the Android client). A self-signed appliance must have its CA installed on the device (MDM/configuration profile); otherwise the connection fails with `APIError.serverTrust`. For plain **HTTP** hosts, add a *scoped* `NSAppTransportSecurity` → `NSExceptionDomains` entry for that host in Info.plist — never `NSAllowsArbitraryLoads`. ## Verify off-device (no iOS SDK needed) The networking core + `AppEnvironment` + view models import only Foundation/Observation, so they typecheck against the macOS SDK: ``` swiftc -typecheck -sdk "$(xcrun --show-sdk-path)" \ /tmp/loadphase_stub.swift ``` Add a one-line stub for `LoadPhase` (it lives in the SwiftUI `Components.swift`): `enum LoadPhase: Equatable { case idle, loading, loaded; case failed(String) }`. Target every run: **0 errors, 0 warnings**. SwiftUI views that use iOS-only APIs can't be compiled this way — validate those with isolated snippets or in Xcode. ## Layout ``` App: MCMSMobileApp (@main), RootView routing, AppEnvironment Networking: APIConfiguration, MCMSConnection, APIClient, APIEnvelope (JSONValue), APIError, APIQuery, MCMSEndpoint, SessionStore, ServerTrustEvaluator, KeychainStore, MongoTimestamp, Format Models: DeviceModels, AuthModels, Firmware Repos: AuthRepository, ONURepository, DeviceRepositories UI: Components, Login/Settings/Dashboard/ONUList/ONUDetail/OLTList/ OLTDetail views + view models, ResetConfirmSheet, FirmwareUpdateSheet, DashboardDrilldownViews Docs: MCMS_API.md (field guide), the two 323-1961-30x dev-guide PDFs ``` See [`HANDOFF.md`](HANDOFF.md) for architecture, the API gotchas, and status. `GUI-NOTES.md` is early scaffold notes (historical — superseded by this README).