A/B test: from-scratch minimal small widget (proven medium intent)
Temporary FuelBoardTestSmallWidget kind: a small-face widget driven by the PROVEN medium intent (fuel/sort/distance only — no favourite params, no dependency, no custom entity query), registered first in the gallery. Isolates small SIZE vs small INTENT: if it populates while FuelPriceSmallWidget skeletons, the small intent's extra machinery is the culprit; if it also skeletons, the failure is small-family/system-level. Provider gains a beaconTag so the test widget's beacons are distinguishable in the relay log and keychain slots. Removed once the root cause is confirmed.
This commit is contained in:
@@ -85,6 +85,35 @@ struct FuelPriceSmallWidget: Widget {
|
||||
}
|
||||
}
|
||||
|
||||
// A/B TEST widget (temporary): a from-scratch SMALL widget driven by the
|
||||
// PROVEN medium intent — no favourite params, no dependency, no custom
|
||||
// query. If this populates while FuelPriceSmallWidget skeletons, the small
|
||||
// SIZE is fine and the small intent's extra machinery is the culprit. If it
|
||||
// ALSO skeletons, the failure is at the small-family/system level. Removed
|
||||
// once the root cause is confirmed.
|
||||
struct FuelBoardTestSmallWidget: Widget {
|
||||
let kind = "FuelBoardTestSmallWidget"
|
||||
|
||||
var body: some WidgetConfiguration {
|
||||
AppIntentConfiguration(
|
||||
kind: kind,
|
||||
intent: FuelBoardWidgetConfigurationIntent.self,
|
||||
provider: FuelPriceTimelineProvider<FuelBoardWidgetConfigurationIntent>(
|
||||
beaconTag: "FuelBoardTestSmallWidget"
|
||||
)
|
||||
) { entry in
|
||||
FuelPriceWidgetView(entry: entry)
|
||||
.containerBackground(for: .widget) {
|
||||
Color(.systemBackground)
|
||||
}
|
||||
}
|
||||
.configurationDisplayName("FuelBoard Small Test")
|
||||
.description("A/B test: minimal small widget using the proven medium intent.")
|
||||
.supportedFamilies([.systemSmall])
|
||||
.disfavoredLocations([.carPlay], for: [.systemSmall])
|
||||
}
|
||||
}
|
||||
|
||||
struct FuelPriceEntry: TimelineEntry {
|
||||
let date: Date
|
||||
let stations: [FuelStation] // already filtered + sorted per config
|
||||
@@ -99,6 +128,12 @@ struct FuelPriceEntry: TimelineEntry {
|
||||
struct FuelPriceTimelineProvider<Configuration: WidgetConfigurationIntent & WidgetConfigValues>: AppIntentTimelineProvider {
|
||||
typealias Intent = Configuration
|
||||
|
||||
/// Diagnostics beacon tag: empty → derive from the intent type name. A
|
||||
/// widget kind that shares an intent (the A/B test small widget reuses the
|
||||
/// medium intent) passes an explicit tag so its beacons stay
|
||||
/// distinguishable in the relay log and keychain slots.
|
||||
var beaconTag: String = ""
|
||||
|
||||
func placeholder(in context: Context) -> FuelPriceEntry {
|
||||
let unit = FuelStore.loadDistanceUnit()
|
||||
let sample = SampleFuelProvider.sampleStations
|
||||
@@ -128,7 +163,7 @@ struct FuelPriceTimelineProvider<Configuration: WidgetConfigurationIntent & Widg
|
||||
|
||||
private func makeEntry(configuration: Configuration) async -> FuelPriceEntry {
|
||||
let entry = await makeEntryCore(configuration: configuration)
|
||||
Self.writeDiagBeacon(entry: entry)
|
||||
writeDiagBeacon(entry: entry)
|
||||
return entry
|
||||
}
|
||||
|
||||
@@ -137,8 +172,8 @@ struct FuelPriceTimelineProvider<Configuration: WidgetConfigurationIntent & Widg
|
||||
/// access log records that a widget timeline actually ran in the
|
||||
/// extension and what it produced. Deliberately outside the timeline
|
||||
/// result — can never affect rendering.
|
||||
private static func writeDiagBeacon(entry: FuelPriceEntry) {
|
||||
let intentType = String(describing: Configuration.self)
|
||||
private func writeDiagBeacon(entry: FuelPriceEntry) {
|
||||
let intentType = beaconTag.isEmpty ? String(describing: Configuration.self) : beaconTag
|
||||
let first = entry.stations.first
|
||||
let json = """
|
||||
{"intent":"\(intentType)","source":"\(entry.locationSource)",\
|
||||
|
||||
Reference in New Issue
Block a user