We are storing FamilyActivitySelection tokens encoded via JSONEncoder to a backend for long-term use, and relying on them inside a DeviceActivityMonitorExtension to restore and apply shields when a schedule fires.
We came across reports on Medium and Apple Developer Forums suggesting that ApplicationToken and ActivityCategoryToken values issued by the FamilyControls framework are not guaranteed to be stable, that iOS may silently re-issue new tokens for the same apps after OS or app updates, making any previously stored tokens invalid.
On Medium, We Found That
The Token Mutation Problem One of the more painful bugs in real production apps: application tokens are not guaranteed to be stable forever. iOS can silently issue new, different tokens for the same app. If your store contains the old token and the Shield delegate receives a new one, the delegate has no way to match them — it doesn’t know which store is responsible for the shield, or which blocking “profile” caused it. This has been reported by multiple developers of real Screen Time apps and confirmed across several Apple Developer Forum threads. There is no official fix yet. The workaround is defensive: when the ShieldConfigurationDataSource or ShieldActionDelegate receives a token you don’t recognise, fall back to a generic shield UI rather than crashing or returning empty data. And never rely on token identity as a long-term stable key in your persistence layer — always re-derive from a fresh FamilyActivityPicker selection when the user re-activates a profile.
What we’re trying to understand is: is this token instability still an active problem in iOS 16/17/18/26, and when a token does become invalid, does JSONDecoder actually throw a DecodingError giving us a clear signal, or does it decode successfully and ManagedSettingsStore just silently ignore the stale tokens with no error at all?