I've implemented my widget configuration like so in my app that supports iOS 17+
@main
struct MyWidget: Widget {
let kind: String = "MyWidget"
var body: some WidgetConfiguration {
if #available(iOS 18.0, *) {
AppIntentConfiguration(kind: kind, intent: MyIntent.self, provider: Provider()) { entry in
MyEntryView(entry: entry)
}
.configurationDisplayName("Display Name")
.description("Description")
.promptsForUserConfiguration()
} else {
AppIntentConfiguration(kind: kind, intent: MyIntent.self, provider: Provider()) { entry in
MyEntryView(entry: entry)
}
.configurationDisplayName("Display Name")
.description("Description")
}
}
}
This results in a compile-time error
Branches have mismatching types 'some WidgetConfiguration' (result of 'Self.promptsForUserConfiguration()') and 'some WidgetConfiguration' (result of 'Self.description')
How are you supposed to use this when you can't change the deployment target to iOS 18?
You can create two different Widget
s and move the availability check up to the body
of your WidgetBundle
.
WidgetBundle
if you don't have one already@main
from your Widget
if you did not have a WidgetBundle
Widget
and rename it@available(iOS 18.0, *)
to the widget that contains .promptsForUserConfiguration()
@main
struct MyAppWidgetBundle: WidgetBundle {
var body: some Widget {
if #available(iOS 18.0, *) {
return MyWidget()
} else {
return MyLegacyWidget()
}
}
}
@available(iOS 18.0, *)
struct MyWidget: Widget {
let kind: String = "MyWidget"
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: kind, intent: MyIntent.self, provider: Provider()) { entry in
MyEntryView(entry: entry)
}
.configurationDisplayName("Display Name")
.description("Description")
.promptsForUserConfiguration()
}
}
struct MyLegacyWidget: Widget {
let kind: String = "MyWidget"
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: kind, intent: MyIntent.self, provider: Provider()) { entry in
MyEntryView(entry: entry)
}
.configurationDisplayName("Display Name")
.description("Description")
}
}