Skip to main content

App Groups Helper

The withAppGroups helper function provides an easy way to add iOS App Groups entitlements to your Expo app. This is useful when you need to share data between your main app and app extensions (like notification extensions, widgets, etc.).

What are App Groups?

App Groups allow multiple apps or app extensions from the same developer to share data using:

  • Shared UserDefaults: UserDefaults(suiteName: "group.identifier")
  • Shared file containers
  • Inter-process communication

Installation

The withAppGroups helper is exported from @appmaker-xyz/expo-plugins:

const { withAppGroups } = require('@appmaker-xyz/expo-plugins');

Usage

Basic Usage (Default)

By default, withAppGroups creates an app group with the identifier group.${bundleIdentifier}:

const { withAppGroups } = require('@appmaker-xyz/expo-plugins');

module.exports = function(config) {
// Adds app groups to main app + all extension targets
// Group identifier: group.com.example.myapp
config = withAppGroups(config);

return config;
};

Custom Suffix

You can provide a custom suffix to create a more specific app group:

const { withAppGroups } = require('@appmaker-xyz/expo-plugins');

module.exports = function(config) {
// Adds app group: group.com.example.myapp.notifications
config = withAppGroups(config, { groups: 'notifications' });

return config;
};

Full Custom Identifier

You can provide a complete app group identifier (must start with group.):

const { withAppGroups } = require('@appmaker-xyz/expo-plugins');

module.exports = function(config) {
// Adds app group: group.custom.identifier
config = withAppGroups(config, { groups: 'group.custom.identifier' });

return config;
};

Multiple App Groups

You can add multiple app groups by passing an array:

const { withAppGroups } = require('@appmaker-xyz/expo-plugins');

module.exports = function(config) {
// Adds multiple app groups:
// - group.com.example.myapp.notifications
// - group.com.example.myapp.analytics
// - group.custom.shared
config = withAppGroups(config, {
groups: ['notifications', 'analytics', 'group.custom.shared']
});

return config;
};

What Gets Modified

The withAppGroups helper modifies entitlements for all targets:

  1. Main app (AppmakerRuntime.entitlements)
  2. Notification Service Extension (AppmakerPushServiceExtension.entitlements)
  3. Notification Content Extension (AppmakerPushContentExtension.entitlements)

All targets receive the same app group identifiers, allowing them to share data.

Before

<!-- Main app entitlements -->
<dict>
<key>aps-environment</key>
<string>development</string>
</dict>

<!-- Extension entitlements -->
<dict>
</dict>

After

<!-- Main app entitlements -->
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.security.application-groups</key>
<array>
<string>group.xyz.appmaker.runtime</string>
</array>
</dict>

<!-- Extension entitlements -->
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.xyz.appmaker.runtime</string>
</array>
</dict>

Complete Example

Here's a complete example of a plugin that uses app groups:

/**
* Example: Analytics Plugin with App Groups
* File: packages/plugins/my-analytics/app.plugin.js
*/

const { withAppGroups } = require('@appmaker-xyz/expo-plugins');

const withMyAnalytics = (config) => {
// Add app groups for sharing analytics data between main app and extensions
config = withAppGroups(config, { groups: 'analytics' });

// ... rest of your plugin configuration

return config;
};

module.exports = withMyAnalytics;

Using Shared Data in Swift

Once app groups are configured, you can access shared data in your Swift code:

// In your main app or extension
let sharedDefaults = UserDefaults(suiteName: "group.xyz.appmaker.runtime")
sharedDefaults?.set("some value", forKey: "sharedKey")

// Read in another target
let value = sharedDefaults?.string(forKey: "sharedKey")

Notes

  • App groups are opt-in and not added by default
  • The helper automatically handles all targets (main app + extensions)
  • App group identifiers must match exactly across all targets
  • You need to configure the same app groups in Apple Developer Console and provisioning profiles
  • The withAppGroups helper only modifies entitlements files - you still need proper provisioning profiles

Migration from Old System

Previously, app groups were added automatically by the firebase-notifications plugin. This has been changed to an opt-in system. If your plugin needs app groups:

Before:

// App groups were added automatically

After:

const { withAppGroups } = require('@appmaker-xyz/expo-plugins');

module.exports = function(config) {
config = withAppGroups(config);
// ... rest of plugin
return config;
};

TypeScript Support

The helper includes full TypeScript type definitions:

import { withAppGroups, WithAppGroupsOptions } from '@appmaker-xyz/expo-plugins';

const options: WithAppGroupsOptions = {
groups: ['notifications', 'analytics']
};

config = withAppGroups(config, options);