App Group е механизъм на iOS, който създава споделен контейнер за обмен на данни между приложението и неговите разширения. Без него всеки процес (основно приложение, widget, share extension) работи в изолирана пясъчна кутия и няма достъп до данните на съседния компонент. Според 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 едновременно — това е полезно за разделяне на данните на различни разширения.
// Вземете URL на контейнера на App Group
guard let containerURL = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.com.example.widget")
else { return }
// Създайте файл в споделения контейнер
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 също изисква идентификаторът на приложението да включва тази capability. Без нея подписът на кода няма да работи на реално устройство.
Отворете проекта в Xcode, изберете target на приложението и отидете на раздела 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 на който и да е target е честа причина разширението да не вижда споделени данни.
Най-простият начин за синхронизиране на данни между приложението и разширенията — UserDefaults с посочване на suite name. Вместо стандартния UserDefaults.standard създавате инстанция с идентификатора на App Group и всички процеси четат едни и същи настройки.
Според Apple Human Interface Guidelines, този механизъм е подходящ за синхронизиране на състояние: избрана тема, любими елементи, флагове за онбординг. Той обаче не е предназначен за големи обеми данни или конкурентни операции за запис — за това използвайте файлове или Core Data.
// Запис в UserDefaults App Group (основно приложение)
let defaults = UserDefaults(suiteName: "group.com.example.shared")
defaults?.set(true, forKey: "isDarkMode")
defaults?.synchronize()
// Четене от UserDefaults App Group (разширение widget)
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. Уверете се, че само един процес записва в базата данни едновременно — конкурентният запис може да повреди данните. Типична архитектура: основното приложение записва, разширенията четат.
// Настройка на Core Data с контейнер на App Group
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 можете да запазите кеширани изображения на диска в споделената директория. Разширението на widget получава достъп до същите файлове и показва актуални данни без допълнително зареждане от мрежата.
| Сценарий | Препоръчително API | Размер на данни |
|---|---|---|
| Настройки и флагове | UserDefaults suiteName | до 1 KB |
| Кеш на изображения | FileManager + NSCache | до 100 MB |
| Структурирани данни | Core Data store | до 500 MB |
| Временни файлове | FileManager temporary | до 50 MB |
При работа със споделени файлове имайте предвид, че системата може да разтовари разширението по всяко време. Използвайте NSFileCoordinator за координация на достъпа, за да избегнете повреда на данни при едновременен запис от различни процеси.
Често задавани въпроси
App Group е механизъм на iOS, който създава споделен контейнер за съхранение на данни между приложението и неговите разширения. Той позволява на процеси с еднакъв идентификатор на група да обменят файлове, настройки на UserDefaults и данни на Core Data чрез единична директория във файловата система.
Отворете Capabilities на target в Xcode, включете App Groups и добавете идентификатор във формат group.*. След това повторете същите стъпки за всяко разширение, което трябва да има достъп до споделения контейнер. Уверете се, че всички участници използват един и същ идентификатор на група.
Всички типове iOS разширения поддържат App Group: Today Widget (widget extension), 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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също