Small widget: restore its own intent TYPE (minimal params) for the icon menu
iOS keys the long-press app-icon contextual menu by configuration-intent TYPE, so sharing one intent across kinds collapsed the menu to the first-registered kind (small) — the medium 'FuelBoard Prices' vanished from the icon menu while the + gallery (kind-keyed) still listed both. dafc96f's skeleton fix was never the problem; the extra favourite AppEntity params were. FIX: FuelBoardSmallWidgetConfigurationIntent — a distinct intent TYPE with the IDENTICAL minimal parameter set (fuel/sort/distance only, no AppEntity params). Fresh-widget default-config resolution stays intact; the appex metadata now registers two WidgetConfiguration actions. Verified: build green, 45/45 tests, extract.actionsdata lists both intents, fresh IPA packaged + signed per component.
This commit is contained in:
@@ -76,20 +76,24 @@ struct FuelPriceWidget: Widget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Small widget — exactly ONE station (the first of the configured result).
|
// Small widget — exactly ONE station (the first of the configured result).
|
||||||
// Shares the medium widget's intent: the small intent with extra favourite
|
// Uses its OWN intent TYPE (FuelBoardSmallWidgetConfigurationIntent) with the
|
||||||
// AppEntity params failed fresh-widget default-config resolution at the
|
// IDENTICAL minimal parameter set as the medium intent. iOS keys the
|
||||||
// system level (whole default config failed → no timeline → skeleton; proven
|
// long-press app-icon contextual menu by configuration-intent TYPE, so two
|
||||||
// by an A/B test where a small widget using this intent populated while the
|
// kinds sharing one intent collapsed there to the first-registered kind (the
|
||||||
// custom-intent small widget never even reached makeEntry). Favourites sort
|
// small widget won — medium vanished from the icon menu). Distinct intent
|
||||||
// on the small face shows the cheapest favourite of the chosen fuel.
|
// TYPE, same minimal params: restores both entries in the icon menu AND keeps
|
||||||
|
// fresh-widget default-config resolution working (the skeleton root cause was
|
||||||
|
// the extra favourite AppEntity params, not intent separation — see the
|
||||||
|
// Fresh-widget defaults section). Favourites sort on the small face shows the
|
||||||
|
// cheapest favourite of the chosen fuel.
|
||||||
struct FuelPriceSmallWidget: Widget {
|
struct FuelPriceSmallWidget: Widget {
|
||||||
let kind = "FuelPriceWidgetSmall"
|
let kind = "FuelPriceWidgetSmall"
|
||||||
|
|
||||||
var body: some WidgetConfiguration {
|
var body: some WidgetConfiguration {
|
||||||
AppIntentConfiguration(
|
AppIntentConfiguration(
|
||||||
kind: kind,
|
kind: kind,
|
||||||
intent: FuelBoardWidgetConfigurationIntent.self,
|
intent: FuelBoardSmallWidgetConfigurationIntent.self,
|
||||||
provider: FuelPriceTimelineProvider<FuelBoardWidgetConfigurationIntent>(
|
provider: FuelPriceTimelineProvider<FuelBoardSmallWidgetConfigurationIntent>(
|
||||||
beaconTag: "FuelBoardSmallWidget"
|
beaconTag: "FuelBoardSmallWidget"
|
||||||
)
|
)
|
||||||
) { entry in
|
) { entry in
|
||||||
|
|||||||
@@ -120,3 +120,51 @@ struct FuelBoardWidgetConfigurationIntent: WidgetConfigurationIntent, WidgetConf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The SMALL widget's OWN intent TYPE. iOS keys the long-press app-icon
|
||||||
|
// contextual menu (iOS 18+ "turn icon into a widget") by configuration-intent
|
||||||
|
// TYPE, so two widget kinds sharing one intent collapse there to a single
|
||||||
|
// entry — the first-registered kind. (The + gallery is kind-keyed, which is
|
||||||
|
// why it still lists both.) This intent carries the IDENTICAL minimal
|
||||||
|
// parameter set as the medium intent — fuel/sort/distance only, NO AppEntity
|
||||||
|
// params (the favouriteFuel/favourite AppEntity params were what broke
|
||||||
|
// fresh-widget default-config resolution, not intent separation; see
|
||||||
|
// Fresh-widget defaults). Sharing the generic provider keeps the timeline
|
||||||
|
// logic in one place.
|
||||||
|
struct FuelBoardSmallWidgetConfigurationIntent: WidgetConfigurationIntent, WidgetConfigValues {
|
||||||
|
static var title: LocalizedStringResource = "Fuel & Sort"
|
||||||
|
static var description = IntentDescription("Which fuel, ordering and search radius this widget shows.")
|
||||||
|
|
||||||
|
@Parameter(title: "Fuel", default: .e10)
|
||||||
|
var fuel: WidgetFuel
|
||||||
|
|
||||||
|
@Parameter(title: "Sort by", default: .cheapest)
|
||||||
|
var sort: WidgetSort
|
||||||
|
|
||||||
|
@Parameter(title: "Distance", default: WidgetDistance(id: 5))
|
||||||
|
var distance: WidgetDistance
|
||||||
|
|
||||||
|
/// Edit-Widget UI: same layout as the medium intent — Distance only for
|
||||||
|
/// Cheapest ordering; hidden for Closest and Favourites.
|
||||||
|
static var parameterSummary: some ParameterSummary {
|
||||||
|
When(\.$sort, .equalTo, WidgetSort.cheapest) {
|
||||||
|
Summary("Show \(\.$fuel) by \(\.$sort) within \(\.$distance)") {
|
||||||
|
\.$fuel
|
||||||
|
\.$sort
|
||||||
|
\.$distance
|
||||||
|
}
|
||||||
|
} otherwise: {
|
||||||
|
When(\.$sort, .equalTo, WidgetSort.favourites) {
|
||||||
|
Summary("Show \(\.$fuel) favourites") {
|
||||||
|
\.$fuel
|
||||||
|
\.$sort
|
||||||
|
}
|
||||||
|
} otherwise: {
|
||||||
|
Summary("Show \(\.$fuel) by \(\.$sort)") {
|
||||||
|
\.$fuel
|
||||||
|
\.$sort
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user