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.