WidgetBundle with ControlWidget does not work on iOS 17

I'm trying to add a ControlWidget to my WidgetBundle like this:

struct MyWidgets: WidgetBundle {

  var body: some Widget {
    if #available(iOSApplicationExtension 18.0, *) {
      LauncherControl()
    }

    MyLiveActivityWidget()
    HomeScreenWidget()
    LockScreenWidget()
  }

This works exactly as expected on iOS 18. However on iOS 17 my app seems to have no widgets at all.

The workaround described here (https://www.avanderlee.com/swiftui/variable-widgetbundle-configuration/) does not work either since WidgetBundleBuilder.buildBlock does not accept ControlWidget as an argument.

What is the correct way to include a Control widget conditionally on iOS 18?

Answered by ekurutepe in 795557022

The following seems to work on both iOS 17 and iOS 18

  var body: some Widget {
    if #available(iOSApplicationExtension 18.0, *) {
      return iOS18Widgets
    } else {
      return iOS17Widgets
    }
  }

  @WidgetBundleBuilder
  var iOS17Widgets: some Widget {
    LiveActivityWidget()
    HomeScreenWidget()
    LockScreenWidget()
  }

  @available(iOSApplicationExtension 18.0, *)
  @WidgetBundleBuilder
  var iOS18Widgets: some Widget {
    LauncherControl()
    LiveActivityWidget()
    HomeScreenWidget()
    LockScreenWidget()
  }
Accepted Answer

The following seems to work on both iOS 17 and iOS 18

  var body: some Widget {
    if #available(iOSApplicationExtension 18.0, *) {
      return iOS18Widgets
    } else {
      return iOS17Widgets
    }
  }

  @WidgetBundleBuilder
  var iOS17Widgets: some Widget {
    LiveActivityWidget()
    HomeScreenWidget()
    LockScreenWidget()
  }

  @available(iOSApplicationExtension 18.0, *)
  @WidgetBundleBuilder
  var iOS18Widgets: some Widget {
    LauncherControl()
    LiveActivityWidget()
    HomeScreenWidget()
    LockScreenWidget()
  }
WidgetBundle with ControlWidget does not work on iOS 17
 
 
Q