I'm trying to create two widgets, widget A and B. Currently A and B are very similar so they share the same Intent and Intent Timeline Provider. I use the Intent Configuration interface to set a parameter, in this example lets say its the background tint. On one of the widgets, widget A, I want to also set another String enum parameter (for a timescale), but I don't want this option to be there for widget B as it's not relevant. I'm aware of some of the options for configuring the ParameterSummary, but none that let me pass in or inject the "kind" string (or widget ID) of the widget that's being modified.
I'll try to provide some code for examples. My Widget Definition (targeting >= iOS 17)
struct WidgetA: Widget {
// I'd like to access this parameter within the intent
let kind: String = "WidgetA"
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: kind, intent: WidgetIntent.self, provider: IntentTimelineProvider()) { entry in
WidgetView(data: entry)
}
.configurationDisplayName("Widget A")
.description("A widget.")
.supportedFamilies([.systemMedium, .systemLarge])
}
}
struct WidgetB: Widget {
let kind: String = "WidgetB"
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: kind, intent: WidgetIntent.self, provider: IntentTimelineProvider()) { entry in
WidgetView(data: entry)
}
.configurationDisplayName("Widget B")
.description("B widget.")
.supportedFamilies([.systemMedium, .systemLarge])
}
}
struct IntentTimelineProvider: AppIntentTimelineProvider {
typealias Entry = WidgetIntentTimelineEntry
typealias Intent = WidgetIntent
........
}
struct WidgetIntent: AppIntent, WidgetConfigurationIntent {
// This intent allows configuration of the widget background
// This intent also allows for the widget to display interactive buttons for changing the Trend Type
static var title: LocalizedStringResource = "Widget Configuration"
static var description = IntentDescription("Description.")
static var isDiscoverable: Bool { return false}
init() {}
init(trend:String) {
self.trend = trend
}
// Used for implementing interactive Widget
func perform() async throws -> some IntentResult {
print("WidgetIntent perform \(trend)")
#if os(iOS)
WidgetState.setState(type: trend)
#endif
return .result()
}
@Parameter(title: "Trend Type", default: "Trend")
var trend:String
// I only want to show this parameter for Widget A and not Widget B
@Parameter(title: "Trend Timescale", default: .week)
var timescale: TimescaleTypeAppEnum?
@Parameter(title: "Background Tint", default: BackgroundTintTypeAppEnum.none)
var backgroundTint: BackgroundTintTypeAppEnum?
static var parameterSummary: some ParameterSummary {
// Summary("Test Info") {
// \.$timescale
// \.$backgroundTint
// }
// An example of a configurable widget parameter summary, but not based of kind/ID string
When(\.$backgroundTint, .equalTo, BackgroundTintTypeAppEnum.none) {
Summary("Test Info") {
\.$timescale
\.$backgroundTint
}
} otherwise : {
Summary("Test Info") {
\.$backgroundTint
}
}
}
}
enum TimescaleTypeAppEnum: String, AppEnum {
case week
case fortnight
static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Trend Timescale")
static var caseDisplayRepresentations: [Self: DisplayRepresentation] = [
.week: "Past Week",
.fortnight: "Past Fortnight"
]
}
enum BackgroundTintTypeAppEnum: String, AppEnum {
case blue
case none
static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Background Tint")
static var caseDisplayRepresentations: [Self: DisplayRepresentation] = [
.none: "None (Default)",
.blue: "Blue"
]
}
I know I could achieve what I'm after by having a separate Intent and separate IntentTimelineProvider for each widget. But this all seems unnessecary for just a simple optional parameter based on what widget its configuring.... unless I'm missing the point about Intents, Widgets or something!
I've done a fair bit of other searching but can't find an answer to this overall scenario.
Many thanks for any help.