What is an app group, and what can go wrong when an app and an extension share a database?
Predict first
The app is suspended while a SQLite connection in the app-group container still holds a lock. What happens?
// A: nothing
// B: the system terminates it with 0xdead10cc
// C: the lock is released automatically
- A
- B
- C
Mental model. A shared fridge in a house with separate flats. Anyone can use it, but if you are called away while holding the door open, you will be locked out.
An app group is an identifier (group.com.example.app) that several apps and extensions from the same team can declare in their entitlements. Members get a shared container directory, found with containerURL(forSecurityApplicationGroupIdentifier:), and a shared defaults store, UserDefaults(suiteName:). It is how a widget reads what the app saved. Inside a process, files are ordinary; across processes you must coordinate: two processes can write at once, so use file coordination, an atomic write, or a database designed for concurrent access.
The nasty case is 0xdead10cc. If the app is suspended while it holds a lock on a file or SQLite database in the shared container, the system terminates it, because a suspended process holding a lock in shared space could block other processes forever. Avoid it by not holding locks across a background transition: end database transactions and close or release shared files when the app is about to be suspended (a short background task helps), and use options such as WAL mode with care. For signalling between processes, use a Darwin notification or a lightweight shared file timestamp and reload on the other side.
A suspended process holding a shared lock could block other processes indefinitely, so the system ends it.
Common traps
- Keeping a SQLite transaction open as the app backgrounds. A suspended process holding the shared lock is killed with 0xdead10cc.
- Assuming the widget sees the app’s data immediately. It needs a reload trigger, and the data must be written to the group container.
They might follow up with
- How do you tell the extension that data changed? A Darwin notification or, for widgets, reloading the timeline.
- Does
UserDefaults.standardcross processes? No. Use a suite named with the app group.
Related questions
- 6.1.2 What is the app container, and why must you never persist an absolute path?
- 6.1.3 What are entitlements, and what happens when they do not match the provisioning profile?
- 6.8.3 Why is an app extension a separate process, and what does that mean for how you build it?
- 2.5.8 What belongs in UserDefaults, and how do you design and test around it?