Sep 8 2020 9:00 AM
Update (September 29, 2020): With Xcode 12.2 beta 2, Apple has added an official template to create macOS Intents extensions.
One of the most exciting additions to iOS 14, WidgetKit is also available on macOS Big Sur, where it replaces the legacy “Today extensions”. Widgets created with WidgetKit can be configured by the user in a system UI which is configured by an intent definition in Xcode.
I’m not really a fan of Apple’s choice of using intents as a way to configure widgets, but I must admit that intent definitions are quite powerful and flexible. When it came time to create a Big Sur widget for AirBuddy 2.0 (in beta at the time of writing), I wanted to let the user pick which devices should show up there, given that the space is fairly limited.
In order for that to work, I would have to provide dynamic values for the widget configuration UI, which the docs say should be done through an intents extension. That’s where I ran into a bit of an issue.
All of the documentation with regards to configuring widgets was written specifically for iOS — or Mac Catalyst — apps, but AirBuddy is an AppKit Mac app. To provide dynamic options for a configurable widget, the app that hosts the widget must also include an intents extension, but if you go into Xcode’s File > New > Target menu, there is no intents extension template for the Mac. If you try to create a target using the template from the iOS tab, it won’t let you embed it in your Mac app.
At first, I thought this was maybe something that was simply not supported on the Mac, but then I noticed that many of the builtin apps (such as Reminders) include dynamic configuration options for their new widgets. Looking at the bundle for the Reminders app on Big Sur, I could see that it includes an intents extension plug in, and it’s not a Catalyst app, so it’s definitely possible.
Then I remembered that it’s possible to create custom templates for Xcode, something that I used previously for one of my articles. So I took the iOS intents extension template from Xcode, duplicated it, did some tweaks, and it actually worked!
You can download the custom template here. To enable it, just copy the
xctemplate folder into
~/Library/Developer/Xcode/Templates/Custom, then restart Xcode. After doing that, you’ll be able to select “Mac Intents Extension” from the “Other” tab when creating a new target.
There is a sample project on my Github which includes a configurable widget with dynamic options provided by an intents extension.
The above solution does work, but there are some things to keep in mind. First, you must enable sandboxing for the widget target. It’s not enabled by default from the template, but the widget won’t work if it’s not sandboxed.
Something else worth pointing out is that I don’t know if this would be an issue when submitting the app to the Mac App Store. I suspect it wouldn’t, but since I haven’t submitted a Mac app to the store with this setup, I can’t say for sure.
And just in case there's someone from Apple reading this, check out FB8651868 😇.
I hope you’ve found this article useful. If you have anything to say, feel free to reach out on Twitter.