Widget diagnostics: per-intent beacons (keychain slots + relay query)
The single-slot beacon couldn't distinguish small vs medium (last writer wins). Beacon keychain service now embeds the intent type name so small and medium never overwrite each other; the relay GET now carries the intent type + entry state as query params so the access log shows exactly which widget kind ran makeEntry, when, and with what. Diagnostics screen shows SMALL and MEDIUM beacons side by side — a missing SMALL beacon after adding the small widget proves its timeline never reaches the provider (system-level config resolution failure).
This commit is contained in:
@@ -45,13 +45,15 @@ struct SettingsView: View {
|
||||
@State private var debugMode: Bool = FuelStore.loadDebugMode()
|
||||
@State private var versionTapCount = 0
|
||||
@State private var lastVersionTap = Date.distantPast
|
||||
/// Widget diagnostics: the extension's last makeEntry beacon (keychain)
|
||||
/// + the installed-widget inventory from WidgetCenter.
|
||||
@State private var widgetDiagBeacon: String?
|
||||
/// Widget diagnostics: the extension's last makeEntry beacon PER intent
|
||||
/// type (keychain) + the installed-widget inventory from WidgetCenter.
|
||||
@State private var smallWidgetDiag: String?
|
||||
@State private var mediumWidgetDiag: String?
|
||||
@State private var installedWidgets: String = ""
|
||||
|
||||
private func refreshWidgetDiag() {
|
||||
widgetDiagBeacon = FuelStore.loadWidgetDiag()
|
||||
smallWidgetDiag = FuelStore.loadWidgetDiag(intentType: "FuelBoardSmallWidgetConfigurationIntent")
|
||||
mediumWidgetDiag = FuelStore.loadWidgetDiag(intentType: "FuelBoardWidgetConfigurationIntent")
|
||||
WidgetCenter.shared.getCurrentConfigurations { result in
|
||||
let text: String
|
||||
switch result {
|
||||
@@ -139,13 +141,23 @@ struct SettingsView: View {
|
||||
} label: {
|
||||
Label("Refresh widget diagnostics", systemImage: "arrow.clockwise")
|
||||
}
|
||||
if let widgetDiagBeacon {
|
||||
Text(widgetDiagBeacon)
|
||||
if let smallWidgetDiag {
|
||||
Text("SMALL: \(smallWidgetDiag)")
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.secondary)
|
||||
.textSelection(.enabled)
|
||||
} else {
|
||||
Text("No widget beacon yet — add a widget on the home screen, then refresh.")
|
||||
Text("SMALL: no beacon yet")
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
if let mediumWidgetDiag {
|
||||
Text("MEDIUM: \(mediumWidgetDiag)")
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.secondary)
|
||||
.textSelection(.enabled)
|
||||
} else {
|
||||
Text("MEDIUM: no beacon yet")
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
@@ -155,7 +167,7 @@ struct SettingsView: View {
|
||||
} header: {
|
||||
Text("Widget Diagnostics")
|
||||
} footer: {
|
||||
Text("The beacon is written by the widget extension at the end of every timeline entry (keychain, so it survives free-SideStore installs). Installed widgets come from WidgetCenter.")
|
||||
Text("Each beacon is written by the widget extension at the end of every timeline entry for that intent type (keychain, so it survives free-SideStore installs). A missing SMALL beacon after adding the small widget means its timeline never reaches the provider. Installed widgets come from WidgetCenter.")
|
||||
}
|
||||
.onAppear { refreshWidgetDiag() }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user