This is one of those ‘note to self’ blog posts. I’ve been working on the next round of features for GlowWorm including a desktop widget. The GlowWidget, like every widget ever, needs to share some data with the main app. Widgets are all sandboxed and locked down, so we need to use an App Group to enable sharing between the extension and the main app. This is where it gets weird.

The internet is full of info on how to set up app groups. It starts by going to the developer portal, creating a group and adding it to the app identifier. Groups created in the dev portal are always prefixed with group.. Once you’ve got that set up, you can add the App Group in the capabilities section of the Xcode project. Here’s the rub! For a Mac app, Xcode enforces that the app group begin with the developer’s Team ID which looks something like JQ49SEDXYZ. So… does it start with group. or does it start with JQ49SEDXYZ.?

The key info is summed up in this SO post and sort of in the docs. It turns out that Mac and iOS configs are completely different! The dev portal and the group. prefix is only for iOS. None of that needs to be done for Mac (like nothing at all in the dev portal). On the Mac, you just need to use the Team ID prefix and that’s it. The only setup is in the Capabilities section of Xcode, where you add an app group with your Team ID prefix, bundle ID and whatever suffix you’d like. For a bundle ID of com.example.app, you might make the app group JQ49SEDXYZ.com.example.app.shared.

Now that you’ve got an app group, make sure you’ve added that app group capability to all the relevant targets. For GlowWorm, it needs to be added to the main app as well as the widget. There are a couple of ways you can share data between the two targets now, but initially we’re only interested in sharing UserDefaults. To do that, you need to create an instance of UserDefaults explicitly associated with the app group. Using the example app group we’ve set up, you can create the shared instance with UserDefaults(suiteNamed: "JQ49SEDXYZ.com.example.app.shared").

And with that, we’re in business! Both the main app and the extension can access the data in the shared user defaults. Now we just have to make it look pretty. 🙈