field_ios

In-the-field app for Radroots on iOS
git clone https://radroots.dev/git/field_ios.git
Log | Files | Refs | LICENSE

commit 45b2e978a75c4169c9db07a483357d0019cb1036
parent fef4d58901aab7548697ac4d8fe9244ca0d3b172
Author: triesap <tyson@radroots.org>
Date:   Fri, 12 Jun 2026 00:34:00 -0700

app: polish diagnostics and bundle posture

- move raw runtime metadata behind debug Settings diagnostics

- keep normal Today UI focused on relay posture

- set the Release bundle id while preserving the local Debug id

Diffstat:
MRadroots/Config/Debug.xcconfig | 1+
MRadroots/Views/HomeView.swift | 6+-----
MRadroots/Views/SettingsView.swift | 42++++++++++++++++++++++++++++++++++++++++++
MRadroots/radroots.xcconfig | 2+-
4 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/Radroots/Config/Debug.xcconfig b/Radroots/Config/Debug.xcconfig @@ -1,6 +1,7 @@ #include "Base.xcconfig" RADROOTS_FIELD_IOS_RUNTIME_MODE = localhost-dev +PRODUCT_BUNDLE_IDENTIFIER = dev.local.radroots RADROOTS_FIELD_IOS_LOGGING_STDOUT = true RADROOTS_FIELD_IOS_LOGGING_FILTER = debug RADROOTS_FIELD_IOS_LOGGING_FILE_ENABLED = false diff --git a/Radroots/Views/HomeView.swift b/Radroots/Views/HomeView.swift @@ -72,7 +72,7 @@ private struct TodayView: View { FieldActionRow(title: "Compliance Note", subtitle: "Reserve audit-ready notes for the current workflow.", systemImage: "checkmark.seal.fill") } - Section("Diagnostics") { + Section("Relay") { RelayMetricRow(label: "Connected", systemImage: "dot.radiowaves.left.and.right", value: app.relayConnectedCount) RelayMetricRow(label: "Connecting", systemImage: "antenna.radiowaves.left.and.right", value: app.relayConnectingCount) if let last = app.relayLastError { @@ -80,10 +80,6 @@ private struct TodayView: View { .foregroundStyle(.red) .font(.footnote) } - Text(app.infoJSONString) - .font(.footnote.monospaced()) - .textSelection(.enabled) - .lineLimit(8) } } .listStyle(.insetGrouped) diff --git a/Radroots/Views/SettingsView.swift b/Radroots/Views/SettingsView.swift @@ -33,6 +33,17 @@ struct SettingsView: View { } } + if diagnosticsAvailable { + Section("Operator") { + NavigationLink { + RuntimeDiagnosticsView() + } label: { + Label("Diagnostics", systemImage: "stethoscope") + } + .accessibilityIdentifier("field_ios.settings.diagnostics") + } + } + Section("Trade") { if let rhi = TradeSettings.rhiPubkeyOptional { CopyRow(title: "RHI Pubkey", value: rhi) @@ -80,6 +91,10 @@ struct SettingsView: View { .accessibilityIdentifier("field_ios.settings") } + private var diagnosticsAvailable: Bool { + BuildConfig.string(.runtimeMode) != "production" + } + private func resetIdentity() { resetError = nil Task { @@ -91,3 +106,30 @@ struct SettingsView: View { } } } + +private struct RuntimeDiagnosticsView: View { + @EnvironmentObject private var app: AppState + + var body: some View { + List { + Section("Relay") { + LabeledContent("Connected", value: "\(app.relayConnectedCount)") + LabeledContent("Connecting", value: "\(app.relayConnectingCount)") + if let relayLastError = app.relayLastError { + Text(relayLastError) + .foregroundStyle(.red) + .font(.footnote) + } + } + + Section("Runtime Metadata") { + Text(app.infoJSONString.isEmpty ? "No runtime metadata available." : app.infoJSONString) + .font(.footnote.monospaced()) + .textSelection(.enabled) + } + } + .listStyle(.insetGrouped) + .inlineNavigationTitle("Diagnostics") + .accessibilityIdentifier("field_ios.diagnostics") + } +} diff --git a/Radroots/radroots.xcconfig b/Radroots/radroots.xcconfig @@ -1,3 +1,3 @@ -PRODUCT_BUNDLE_IDENTIFIER = dev.local.radroots +PRODUCT_BUNDLE_IDENTIFIER = org.radroots.field-ios #include? "radroots.git.xcconfig"