App Group — це механізм iOS, який створює спільний контейнер для обміну даними між застосунком та його розширеннями. Без нього кожен процес (основний застосунок, віджет, розширення Share) працює в ізольованому пісочниці та не має доступу до даних сусіднього компонента. За даними Apple Developer Documentation, 2026, App Group вирішує цю проблему через єдиний ідентифікатор групи, який вказується в entitlements. Це фундаментальний інструмент для створення узгодженого користувацького досвіду в екосистемі iOS.
Головне
App Group — це механізм операційної системи iOS, який надає спільну область зберігання для кількох процесів одного розробника. Без нього кожне розширення працює у власному пісочниці та не може прочитати дані, які записав інший компонент. App Group вирішує цю ізоляцію, створюючи директорію у файловій системі, доступну всім процесам із коректними entitlements.
Ідентифікатор групи починається з префікса group. і вказується у файлі entitlements проєкту. У Xcode цей ідентифікатор додається через Capabilities — система автоматично включає його в підпис застосунку. Після налаштування всі учасники групи отримують доступ до спільної директорії за шляхом Library/Application Support/ усередині контейнера.
За даними Apple WWDC 2020 Session 10026, App Group покриває три ключові сценарії: синхронізація налаштувань через NSUserDefaults, спільний доступ до файлів через FileManager та спільне використання Core Data з єдиним сховищем. Для кожного сценарію потрібно лише вказати ідентифікатор групи у відповідному API.
iOS створює спільний контейнер при першому запуску будь-якого процесу, який має entitlement com.apple.security.application-groups. Фізично контейнер розташовується в системній директорії — його шлях відрізняється від пісочниці основного застосунку та розширень, але всі авторизовані процеси мають права на читання та запис.
Apple гарантує безпеку App Group через зв'язку team ID та підпису коду. Процес, не підписаний тим самим сертифікатом розробника, не може отримати доступ до контейнера групи. Це запобігає витоку даних між застосунками різних розробників.
Формат ідентифікатора: group.<team-id>.<name>. Наприклад, group.ABC123DEFG.widget-data. На одному пристрої можна створити кілька груп, кожна зі своїм набором учасників. Один застосунок може входити до кількох App Group одночасно — це корисно для розділення даних різних розширень.
// 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 надає метод containerURL(forSecurityApplicationGroupIdentifier:), який повертає URL спільної директорії. Важливо викликати цей метод у кожному процесі окремо — шлях фізично однаковий, але кожен процес бачить його через власну призму безпеки.
Увімкнення App Group у Xcode починається з Capabilities — перемикач App Groups додає entitlement до проєкту. Apple Developer Portal також вимагає, щоб ідентифікатор застосунку включав цю можливість. Без неї підпис коду не спрацює на реальному пристрої.
Відкрийте проєкт у Xcode, виберіть таргет застосунку та перейдіть на вкладку Signing & Capabilities. Натисніть + і виберіть App Groups. Створіть або виберіть існуючу групу. Повторіть ті самі кроки для кожного розширення, яке повинно мати доступ до спільного контейнера. Усі учасники повинні використовувати один і той самий ідентифікатор групи.
Після ввімкнення Capabilities Xcode автоматично створює файл .entitlements із ключем com.apple.security.application-groups та масивом ідентифікаторів. Переконайтеся, що всі необхідні розширення мають цей файл із коректним team ID в ідентифікаторі групи.
<!-- Example entitlements file -->
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.example.shared</string>
</array>
Якщо у вашому проєкті кілька розширень (Today Widget, Share Extension, Notification Service), кожне повинно мати власний файл entitlements із тією самою групою. Відсутність entitlements у будь-якого таргета — часта причина, через яку розширення не бачить спільні дані.
Найпростіший спосіб синхронізації даних між застосунком та розширеннями — UserDefaults із зазначенням suite name. Замість стандартного UserDefaults.standard ви створюєте екземпляр з ідентифікатором App Group, і всі процеси читають одні й ті самі налаштування.
За даними Apple Human Interface Guidelines, цей механізм підходить для синхронізації стану: вибраної теми, вподобаних елементів, прапорців онбордингу. Однак він не призначений для великих обсягів даних або конкурентних операцій запису — для цього використовуйте файли або Core Data.
// 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
Зверніть увагу: екземпляр UserDefaults із suiteName створюється в кожному процесі окремо, але читає з одного plist-файлу в спільному контейнері. Метод synchronize() гарантує негайний запис на диск — в iOS 13+ його можна опустити, оскільки система синхронізує дані періодично.
Для більш складних сценаріїв App Group надає доступ до спільної файлової системи. Будь-який файл, створений у директорії контейнера, доступний усім процесам групи. Це дозволяє реалізувати спільну базу Core Data, кеш зображень або тимчасові файли.
Щоб використовувати спільне сховище Core Data, створіть NSPersistentContainer з URL файлу .sqlite, розташованого в директорії App Group. Переконайтеся, що лише один процес пише до бази одночасно — конкурентний запис може пошкодити дані. Типова архітектура: основний застосунок пише, розширення читають.
// 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
}()
Альтернативний підхід — файловий кеш зображень. NSCache живе лише в пам'яті, але через App Group можна зберігати кешовані зображення на диску в спільній директорії. Розширення віджету отримує доступ до тих самих файлів і відображає актуальні дані без додаткового завантаження з мережі.
| Сценарій | Рекомендований API | Розмір даних |
|---|---|---|
| Налаштування та прапорці | UserDefaults suiteName | до 1 КБ |
| Кеш зображень | FileManager + NSCache | до 100 МБ |
| Структуровані дані | Core Data store | до 500 МБ |
| Тимчасові файли | FileManager тимчасовий | до 50 МБ |
Працюючи зі спільними файлами, враховуйте, що система може вивантажити розширення в будь-який момент. Використовуйте NSFileCoordinator для координації доступу, щоб уникнути пошкодження даних при одночасному записі різними процесами.
Часті запитання
App Group — це механізм iOS, який створює спільний контейнер для зберігання даних між застосунком та його розширеннями. Він дозволяє процесам з однаковим ідентифікатором групи обмінюватися файлами, налаштуваннями UserDefaults та даними Core Data через єдину директорію у файловій системі.
Відкрийте Capabilities таргета в Xcode, увімкніть App Groups та додайте ідентифікатор у форматі group.*. Потім повторіть ті самі кроки для кожного розширення, яке повинно мати доступ до спільного контейнера. Переконайтеся, що всі учасники використовують однаковий ідентифікатор групи.
Усі типи розширень iOS підтримують App Group: Today Widget (розширення віджету), Share Extension, Notification Service Extension, Custom Keyboard та інші. Кожне розширення повинно мати окремий файл entitlements із тим самим ідентифікатором групи, що й основний застосунок.
Так, але лише якщо застосунки підписані одним і тим самим сертифікатом розробника та мають однаковий team ID. Apple гарантує безпеку через підпис коду: два застосунки від різних розробників не можуть отримати доступ до одного контейнера навіть з однаковим ідентифікатором групи.
Використовуйте UserDefaults із suite name для невеликих налаштувань, FileManager для файлів та Core Data для структурованих даних. Усі ці API працюють із директорією App Group — достатньо вказати ідентифікатор групи при ініціалізації. Для Core Data переконайтеся, що URL сховища вказує на спільну директорію.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також