Add PrivacyInfo.xcprivacy declaring NSPrivacyAccessedAPICategoryUserDefaults#2471
Open
Neelagiri65 wants to merge 1 commit into
Open
Add PrivacyInfo.xcprivacy declaring NSPrivacyAccessedAPICategoryUserDefaults#2471Neelagiri65 wants to merge 1 commit into
Neelagiri65 wants to merge 1 commit into
Conversation
…efaults
The app reads UserDefaults in two ways that require declaration under
Apple's Required Reason API rules (in force since May 2024):
- UserDefaults.standard in Packages/Env/Sources/Env/UserPreferences.swift:88
(the prepareTranslationType path) → CA92.1 (same-app data).
- UserDefaults(suiteName: 'group.com.thomasricouard.IceCubesApp') in
Packages/Env/Sources/Env/UserPreferences.swift:109, shared with the
widget/notification extensions → 1C8F.1 (same-app-group data).
Without this declaration, App Store Connect will block new submissions
with ITMS-91053 ('Missing API declaration').
Xcode's synchronized folder groups should include the file in the main
app target automatically; please verify in the Copy Bundle Resources
build phase before merging.
Note: extension targets (IceCubesActionExtension, IceCubesShareExtension,
IceCubesNotifications, IceCubesAppWidgetsExtension) that import Env and
therefore transitively use UserDefaults may need their own copies of this
manifest in their respective Resources folders — out of scope for this PR.
Discovered with PrivacyLint (https://github.com/Neelagiri65/privacylint).
The scanner also reported 14 'creationDate' findings that are SwiftData
@model property names rather than file-timestamp Required Reason API
calls — those are false positives in v1 (no semantic type resolution)
and not addressed here.
Neelagiri65
added a commit
to Neelagiri65/privacylint
that referenced
this pull request
Jun 8, 2026
Pushed the add-privacy-manifest branch to the fork, opened the PR against Dimillian/IceCubesApp main. PR is live, open, +24/-0 across 1 file (IceCubesApp/PrivacyInfo.xcprivacy). - HANDOFF now reflects PR-open state (was: 'drafted locally'). - Reddit + Swift Forums drafts updated to link the PR directly, replacing the 'will open a PR' placeholder. The Reddit headline now reads: 'I checked — no PrivacyInfo.xcprivacy anywhere in the IceCubesApp repo. Real finding. PR open here.' That's the strongest credibility hook the post can lead with. - 'Push the PR' removed from NEXT; replaced with 'monitor PR response, respond to Dimillian's review promptly'. If merged, it becomes the Show HN post's proof point. Tree clean; tests still 119 pass; tap install still working.
Neelagiri65
added a commit
to Neelagiri65/privacylint
that referenced
this pull request
Jun 8, 2026
…ion debt End-of-session sweep. Engine + tap + IceCubesApp PR (Dimillian/IceCubesApp#2471) are verified live. Blog post / Reddit / Swift Forums / LinkedIn were reported as 'done' by the user but the URLs were never pasted back, so Claude did not verify them. HANDOFF flags this honestly: - New 'Session end snapshot' block at the top separates 'verified live' from 'user reported done, not verified by Claude' so the next session knows exactly what to confirm before counting them as launched. - 'How to resume' now has URL-verification as step 3, before any new work. - NEXT list: 'verify the four launch URLs' is now the first remaining action; 'monitor PR #2471' is second; v0.2.0 SwiftData false-positive reduction stays as the next code milestone. Disk state recorded: fork clone at /tmp/pl-pr/IceCubesApp survives reboot but not a /tmp clean; reclone instructions in place. Helper script /tmp/publish-launch.sh is ephemeral but regeneratable from git show or from the dist/launch/ markdowns. Final verification: swift build ✅ swift test ✅ 119 tests in 9 suites git status clean, origin/master in sync gh pr view 2471 → state: OPEN, 0 comments Tree clean; pushed. Session safely handoverable.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi @Dimillian — IceCubesApp doesn't currently ship a
PrivacyInfo.xcprivacy, and the app readsUserDefaultsin a couple of places that fall under Apple's Required Reason API rules (in force since May 2024). App Store Connect rejects submissions for this withITMS-91053("Missing API declaration").This PR adds the manifest with the narrowest declaration the code actually needs.
Why these two reason codes
Packages/Env/Sources/Env/UserPreferences.swift:88—UserDefaults.standardNSPrivacyAccessedAPICategoryUserDefaultsCA92.1(same-app data)Packages/Env/Sources/Env/UserPreferences.swift:109—UserDefaults(suiteName: "group.com.thomasricouard.IceCubesApp")shared with widget/notification extensionsNSPrivacyAccessedAPICategoryUserDefaults1C8F.1(same-app-group data)IceCubesApp/App/Main/IceCubesApp.swift:42—register(defaults:)inside#if DEBUGNo other Required Reason API categories apply — I checked for
FileTimestamp,SystemBootTime,DiskSpace, andActiveKeyboardssymbols across the codebase and didn't find real usages. No tracking domains. No AI service endpoints. So this manifest stays minimal.Bundling
The project uses Xcode's synchronized folder groups (
PBXFileSystemSynchronizedRootGroup× 9 in the pbxproj), so dropping the file intoIceCubesApp/next toInfo.plistshould add it to the main app target automatically. Please verify it lands in the Copy Bundle Resources phase before merging.Out of scope for this PR
The extension targets —
IceCubesActionExtension,IceCubesShareExtension,IceCubesNotifications,IceCubesAppWidgetsExtension— all importEnvand therefore transitively useUserDefaults. Each is a separate bundle and will need its ownPrivacyInfo.xcprivacycopy to be fully compliant. Happy to follow up with a second PR for those if you'd like; I split it out so the main-app fix is reviewable on its own.How I found this
I ran PrivacyLint — a Swift CLI I built to catch this category of rejection — against the repo. It flagged 1 blocking error (no manifest) and 19 Required-Reason warnings; on triage, the two
UserDefaultsones above are real and the other 14 (creationDate) are SwiftData@Modelproperty names rather thanURLResourceValues.creationDatecalls, so they don't need declaration. PrivacyLint v1 can't statically disambiguate those — it's a documented limitation I'm fixing in v0.2.Happy to iterate on anything here.