Skip to content

Add opt-in isEligibleForAgeFeatures() for iOS 26.2+ - #36

Merged
zigapovhe merged 1 commit into
zigapovhe:0.10.0from
Insight-Timer:is-eligible-for-age-features
Sep 22, 2026
Merged

zigapovhe merged 1 commit into
zigapovhe:0.10.0from
Insight-Timer:is-eligible-for-age-features

Conversation

@danielwilliamson

Copy link
Copy Markdown
Contributor

Adds isEligibleForAgeFeatures() as an opt-in call, without changing how checkAgeSignals() behaves.

Why

requestAgeRange() shows its sharing sheet in every region, so an app that only wants to prompt people who are actually subject to age assurance needs a pre-check. Apple's guide still lists isEligibleForAgeFeatures as the first step, and getRequiredRegulatoryFeatures() does not cover it on its own: Apple DTS states that regulations added after iOS 26.4 may not map onto an existing RegulatoryFeature, so the set can be empty while isEligibleForAgeFeatures is true and the obligation still stands. Apps that gate on region need both.

The 0.6.0 reasons for dropping the internal pre-gate still hold, so this does not reintroduce it. checkAgeSignals() is unchanged; the property is only reachable through the new method, and it runs under the same withDeadline as the regulatory call so a hang surfaces as ApiErrorException after 10 seconds.

API

  • Future<bool> isEligibleForAgeFeatures() on AgeRangeSignals, the platform interface and the method channel.
  • Throws UnsupportedPlatformException below iOS 26.2, in apps built with a pre-26.2 SDK (same compiler(>=6.2.3) guard as the other 26.2 symbols) and on Android, so false always means Apple reports no obligation. AgeRangeService.Error.notAvailable maps to ApiNotAvailableException.
  • Docs: usage section, API reference, a rewrite of the Testing note that described the property as abandoned, CHANGELOG under Unreleased, llms.txt and a context7.json rule under the 255 character limit. The example app gains a button next to the regulatory ones.

Testing

  • flutter test (83 tests), flutter analyze on the package and the example, and dart format are clean.
  • Example iOS app builds with Xcode 26.6.
  • Verified on a physical device on iOS 26.x with a Sandbox Apple Account: returns true with an Age Assurance scenario selected and false without one, both well inside the deadline.
  • An unanswered thread reports the property flipping from true to false for Brazil after 26.4 with no account change, so the README keeps the advice to treat it as an obligation signal with a caller-side fallback rather than a stable region flag.

🤖 Generated with Claude Code

Exposes Apple's region eligibility check as a separate call, guarded by
the same 10-second deadline as getRequiredRegulatoryFeatures().
checkAgeSignals() still does not call it. Throws UnsupportedPlatformException
below iOS 26.2, on pre-26.2 SDKs and on Android so false always means Apple
reports no obligation. Apple DTS confirms requiredRegulatoryFeatures can be
empty while this is true (forums thread 815952), so pre-gating apps need both.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@zigapovhe
zigapovhe changed the base branch from main to 0.10.0 September 22, 2026 09:21
@zigapovhe

Copy link
Copy Markdown
Owner

thanks for the PR, nicely done. code side is clean — verified the DTS empty-set answer and the forum reports against apple's docs before merging.

two doc things I'm fixing in a follow-up commit (can't push to your branch, org forks ignore the maintainer-edit flag):

  • "false always means Apple reports no obligation" oversells it. the pre-prompt false reports are sandbox-only, but apple never answered whether the value is reliable in production, and there's an open thread about brazil devices flipping true→false after 26.4 with no account change. rewording to "apple's current report, not a stable region flag" with a caller-side fallback note.
  • the retained docs still say an empty regulatory set means no obligation, which your own DTS quote contradicts. aligning those, plus a couple of stale anchors and the version bump to 0.10.0.

merging into the 0.10.0 release branch rather than main directly.

@zigapovhe
zigapovhe merged commit af10d55 into zigapovhe:0.10.0 Sep 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants