Widget in iOS 17 Xcode beta errors

In Xcode 15, we got improvements on widgets, which also change A LOT how we handle them in code, we need to take care now of:

Live action, animations, Time Lines & App Intents

If you download the Widgets example from Apple, you’ll see that it won’t compile in Xcode 15 Beta 2 after create the Widget Target. This will create a boiler plate code, that sadly doesn’t compile with the previews.

The first change we need to do is to add  a container background:

.containerBackground(for: .widget)

https://developer.apple.com/documentation/swiftui/view/containerbackground(_:for:)

You can use this extension that someone put on Apple Forums:

extension View {
    func widgetBackground(_ color: Color) -> some View {
        if #available(iOSApplicationExtension 17.0, macOSApplicationExtension 14.0, *) {
            return  containerBackground(color, for: .widget)
        } else {
            return background(color)
        }
    }
}

Use it like:

AvatarView(entry.character)
            .widgetBackground(.white)

The second change is about how previews work now:

struct EmojiRangerWidget_Previews: PreviewProvider {

   static var previews: some View {
      AvatarView(.panda)
        .widgetBackground(.white)
        .previewContext(WidgetPreviewContext(family: .systemSmall))
   }
}

See that we’re using the .widgetBackground

But now, with the Preview macro, there’s another way to use them, basically we need to use the Entries:

#Preview(as: .systemSmall) {
    EmojiRangerWidget()
} timeline: {
    SimpleEntry(date: .now,
                character: .panda)
}

But, this will yell an error and won’t let you run the app:

-[INIntent _initWithIdentifier:backingStore:schema:error:] Missing backing store for Intent: {xxx-xxx-xxx some ID} (N/A - N/A)

To fix this, we need to add In our Entry  the configuration intent and our detail character detail model

struct SimpleEntry: TimelineEntry {
    let date: Date
    let configuration: ConfigurationAppIntent
    let character: CharacterDetail
}

The result will now compile in our preview. Check the result:

#Preview(as: .systemSmall) {
    EmojiRangerWidget()
} timeline: {
    SimpleEntry(date: .now,
                configuration: ConfigurationAppIntent(),
                character: .panda)
}

And that’s it. I still see the error mentioned above, but at least is working

In new betas, from the number 5, this is fixed, but I wanted to leave the solution here, because it was a challenge!!!!

Check the WWDC23 videos for more information

Video: https://developer.apple.com/videos/play/wwdc2023/10028/?time=233

This allows it to show up in all the new supported locations on the Mac and iPad.

 

Sofia Swidarowicz

I'm an iOS Software Engineer mostly. Known as phynet in the internez. I'm me, full of memory failure and lovely karma.

 

Leave a Reply

Your email address will not be published. Required fields are marked *