5

I want to add an extra large widget as supported family for iOS 15 in my application.

The simplified code for WidgetConfiguration is as follows:

    var body: some WidgetConfiguration {
        IntentConfiguration(
            kind: "Widget",
            intent: SelectProjectIntent.self,
            provider: Provider()
        ) {
            entry in
            ProgressWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("Title")
        .description("Description")
        .supportedFamilies([.systemSmall, .systemMedium, .systemLarge, .systemExtraLarge])
    }

Obviously I can't just simply add extra Large because the following error appears: 'systemExtraLarge' is only available in application extensions for iOS 15.0 or newer

But doing a quick and simple availability checking suggested by XCode I get an error and several warnings. Here is the code:

    var body: some WidgetConfiguration {
        
        if #available(iOSApplicationExtension 15.0, *) {
            
            IntentConfiguration(
                kind: "Widget",
                intent: SelectProjectIntent.self,
                provider: Provider()
            ) {
                entry in
                ProgressWidgetEntryView(entry: entry)
            }
            .configurationDisplayName("Title")
            .description("Description")
            .supportedFamilies([.systemSmall, .systemMedium, .systemLarge, .systemExtraLarge])
            
        } else {
            
            IntentConfiguration(
                kind: "Widget",
                intent: SelectProjectIntent.self,
                provider: Provider()
            ) {
                entry in
                ProgressWidgetEntryView(entry: entry)
            }
            .configurationDisplayName("Title")
            .description("Description")
            .supportedFamilies([.systemSmall, .systemMedium, .systemLarge])
        }
    }

The error is: Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type.

And the two warnings: Result of call to 'supportedFamilies' is unused.

Could someone please explain to me why I am getting this error and how could I fix it so that I can keep the widgets for iOS 14 and add systemExtraLarge for iOS 15?

I'm using XCode Version 13.0 beta 5 on a macOS Monterey Version 12.0 beta (21A5304g)

Thanks in advance.

Tomeu Mascó
  • 319
  • 2
  • 11

1 Answers1

15

When you create a View, it's var body is marked as a @ViewBuilder. That allows you to provide multiple child views and use conditionals (learn more). Unfortunately that doesn’t work for the body of a Widget because there is no such thing as a WidgetConfigurationBuilder, so you can only return a single WidgetConfiguration from Widget’s body.

To solve your problem, take the if-else out of the Widget's body. One way to do that is to move it to a property, like so:

struct MyWidget: Widget {
    
    private let supportedFamilies:[WidgetFamily] = {
        if #available(iOSApplicationExtension 15.0, *) {
            return [.systemSmall, .systemMedium, .systemLarge, .systemExtraLarge]
        } else {
            return [.systemSmall, .systemMedium, .systemLarge]
        }
    }()
    
    var body: some WidgetConfiguration {
        IntentConfiguration(
            kind: "Widget",
            intent: SelectProjectIntent.self,
            provider: Provider()
        ) {
            entry in
            ProgressWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("Title")
        .description("Description")
        .supportedFamilies(supportedFamilies)
    }
}
Adam
  • 4,405
  • 16
  • 23
  • Oohh, of course!! Thanks a lot! I didn't know about @ViewBuilder or how it works. Now I understand it. Thanks for the explanation! – Tomeu Mascó Aug 19 '21 at 07:48
  • Thanks this works. Actually, I tried to add extra large widget for iPhone but its specifically only for iPad alone. `Widgets can be small, medium, large, and — on iPad only —extra large.` – Sathish Kumar Gurunathan Sep 14 '21 at 06:46
  • What about getting error code Type 'WidgetFamily' has no member 'systemExtraLarge'. I am running the latest version of Xcode 13 from the App Store so it should be supported. It used to work with previous betas of Xcode but not this latest one, it's as if the property doesn't exist as far as its concerned. https://ibb.co/KzcZP4V – CristianMoisei Sep 21 '21 at 19:27
  • 1
    @CristianMoisei It does not appear to me in the autocomplete either. But if you write it, it does not give problems. Although notice that in the image you are trying to add it in the wrong part of the if. Maybe it was all a little oversight. Could it be that you use macCatalyst? I got the same error. Adding the following code fixed: #if targetEnvironment(macCatalyst) #else (your extra large code here) #endif – Tomeu Mascó Sep 22 '21 at 09:16
  • 1
    Good point @TomeuMascó, thank you – CristianMoisei Sep 22 '21 at 13:36