App Group is an iOS mechanism that creates a shared container for data exchange between an app and its extensions. Without it, each process (main app, widget, share extension) runs in an isolated sandbox and has no access to the data of a neighboring component. According to Apple Developer Documentation, 2026, App Group solves this problem through a single group identifier specified in entitlements. It is a fundamental tool for creating a consistent user experience in the iOS ecosystem.
Key Takeaways
App Group is an iOS operating system mechanism that provides a shared storage area for multiple processes from the same developer. Without it, each extension works in its own sandbox and cannot read data written by another component. App Group solves this isolation by creating a directory on the file system accessible to all processes with the correct entitlements.
The group identifier starts with the prefix group. and is specified in the project's entitlements file. In Xcode, this identifier is added via Capabilities — the system automatically includes it in the app's signature. Once configured, all group members get access to the shared directory at Library/Application Support/ inside the container.
According to Apple WWDC 2020 Session 10026, App Group covers three key scenarios: syncing settings via NSUserDefaults, sharing files via FileManager, and shared Core Data with a single store. Each scenario only requires specifying the group identifier in the corresponding API.
iOS creates the shared container the first time any process with the com.apple.security.application-groups entitlement runs. Physically, the container is located in a system directory — its path differs from the main app sandbox and extensions, but all authorized processes have read and write permissions.
Apple ensures security for App Group through a combination of team ID and code signing. A process not signed with the same developer certificate cannot access the group container. This prevents data leaks between apps from different developers.
The identifier format is: group.<team-id>.<name>. For example, group.ABC123DEFG.widget-data. You can create multiple groups on one device, each with its own set of members. A single app can belong to several App Groups simultaneously — this is useful for separating data of different extensions.
// Get the App Group container URL
guard let containerURL = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.com.example.widget")
else { return }
// Create a file in the shared container
let fileURL = containerURL.appendingPathComponent("shared.data")
try "Hello from main app".write(to: fileURL, atomically: true, encoding: .utf8)
FileManager provides the containerURL(forSecurityApplicationGroupIdentifier:) method, which returns the URL of the shared directory. It is important to call this method separately in each process — the path is physically the same, but each process sees it through its own security lens.
Enabling App Group in Xcode starts with Capabilities — the App Groups toggle adds the entitlement to the project. Apple Developer Portal also requires that the app identifier includes this capability. Without it, code signing will not work on a real device.
Open your project in Xcode, select the app target, and go to the Signing & Capabilities tab. Click + and choose App Groups. Create or select an existing group. Repeat the same steps for each extension that needs access to the shared container. All participants must use the same group identifier.
After enabling Capabilities, Xcode automatically creates an .entitlements file with the com.apple.security.application-groups key and an array of identifiers. Make sure all necessary extensions have this file with the correct team ID in the group identifier.
<!-- Example entitlements file -->
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.example.shared</string>
</array>
If your project has multiple extensions (Today Widget, Share Extension, Notification Service), each must have its own entitlements file with the same group. Missing entitlements on any target is a common reason why an extension cannot see shared data.
The simplest way to sync data between an app and its extensions is UserDefaults with a suite name. Instead of the standard UserDefaults.standard, you create an instance with the App Group identifier, and all processes read the same settings.
According to Apple Human Interface Guidelines, this mechanism is suitable for syncing state: selected theme, favorites, onboarding flags. However, it is not intended for large data volumes or concurrent write operations — use files or Core Data for that.
// Write to UserDefaults App Group (main app)
let defaults = UserDefaults(suiteName: "group.com.example.shared")
defaults?.set(true, forKey: "isDarkMode")
defaults?.synchronize()
// Read from UserDefaults App Group (widget extension)
let sharedDefaults = UserDefaults(suiteName: "group.com.example.shared")
let isDark = sharedDefaults?.bool(forKey: "isDarkMode") ?? false
Note: the UserDefaults instance with suiteName is created separately in each process but reads from the same plist file in the shared container. The synchronize() method guarantees immediate disk write — in iOS 13+ it can be omitted as the system syncs data periodically.
For more complex scenarios, App Group provides access to a shared file system. Any file created in the container directory is accessible to all group processes. This enables a shared Core Data database, image cache, or temporary files.
To use a shared Core Data store, create an NSPersistentContainer with the .sqlite file URL located in the App Group directory. Make sure only one process writes to the database at a time — concurrent writes can corrupt data. A typical architecture: the main app writes, extensions read.
// Setup Core Data with App Group container
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "SharedModel")
guard let appGroupURL = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.com.example.shared")
else { return container }
let storeURL = appGroupURL.appendingPathComponent("SharedModel.sqlite")
container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: storeURL)]
container.loadPersistentStores { _, error in
if let error = error { fatalError(error.localizedDescription) }
}
return container
}()
An alternative approach is a file-based image cache. NSCache lives only in memory, but through App Group you can save cached images to disk in the shared directory. The widget extension can access the same files and display up-to-date data without additional network downloads.
| Scenario | Recommended API | Data Size |
|---|---|---|
| Settings and Flags | UserDefaults suiteName | up to 1 KB |
| Image Cache | FileManager + NSCache | up to 100 MB |
| Structured Data | Core Data store | up to 500 MB |
| Temp Files | FileManager temporary | up to 50 MB |
When working with shared files, keep in mind that the system may terminate the extension at any time. Use NSFileCoordinator to coordinate access and avoid data corruption when multiple processes write simultaneously.
Frequently Asked Questions
App Group is an iOS mechanism that creates a shared container for storing data between an app and its extensions. It allows processes with the same group identifier to exchange files, UserDefaults settings, and Core Data through a single directory on the file system.
Open the target Capabilities in Xcode, enable App Groups, and add an identifier in the format group.*. Then repeat the same steps for each extension that needs access to the shared container. Make sure all participants use the same group identifier.
All types of iOS extensions support App Group: Today Widget (widget extension), Share Extension, Notification Service Extension, Custom Keyboard, and others. Each extension must have a separate entitlements file with the same group identifier as the main app.
Yes, but only if the apps are signed with the same developer certificate and have the same team ID. Apple guarantees security through code signing: two apps from different developers cannot access the same container even with an identical group identifier.
Use UserDefaults with suite name for small settings, FileManager for files, and Core Data for structured data. All these APIs work with the App Group directory — just specify the group identifier during initialization. For Core Data, make sure the store URL points to the shared directory.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also