◉CLAUDE LABJP
●2.1.301 — Adds the vim % motion, LaTeX math rendering in the VS Code panel, and a retry-watchdog limit for usage-limit waits (10/15)●2.1.299 — Conversations over 200K tokens left idle about 54 minutes get compacted; MCP allow rules now match only the server they name●SONNET 4.5 — Retires on the Claude API on 11/30, 45 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…●2.1.301 — Adds the vim % motion, LaTeX math rendering in the VS Code panel, and a retry-watchdog limit for usage-limit waits (10/15)●2.1.299 — Conversations over 200K tokens left idle about 54 minutes get compacted; MCP allow rules now match only the server they name●SONNET 4.5 — Retires on the Claude API on 11/30, 45 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…
Articles/Claude Code
⟐ Claude Code/2026-07-08Advanced

Auditing Your Own Code for Required Reason API Declarations with Claude Code

Required reason codes in PrivacyInfo.xcprivacy apply to your own code, not just third-party SDKs. After a wallpaper app of mine was rejected, here is the Claude Code workflow I use to scan Swift sources and match APIs to reason codes before submission.

Claude Code264iOS26App Store9PrivacyIndie Development11

✦ Premium Article

Last spring I shipped an update to one of my wallpaper apps, and a few hours after submitting to the App Store a notice landed: "ITMS-91053: Missing API declaration." I had kept my dependency manifests tidy, so what went wrong? It was my own code. A stray UserDefaults call I had used for saving a setting counts as one of Apple's Required Reason APIs.

Conversation about Required Reason APIs tends to gravitate toward SDK compliance. But the same declaration rules apply to the code you write yourself. This piece narrows in on scanning your own sources — using Claude Code to inventory the gaps and fill in reason codes in PrivacyInfo.xcprivacy. For the dependency side, I leave you to my separate write-up on catching missing manifest declarations in dependencies.

Why your own code slips through

Required Reason APIs sound imposing, yet they are a collection of quiet, everyday calls. UserDefaults for saving settings, modificationDate for reading a file's timestamp, volumeAvailableCapacityKey for checking free space, systemUptime for measuring elapsed time on device. None of them carry the drama the word "privacy" suggests. That is exactly why the need to declare them never registers, and they sink deep into the codebase.

In my case there were three gaps: a UserDefaults write for an onboarding-complete flag, a modificationDate read that judged how fresh a cached image was, and a volumeAvailableCapacityForImportantUsageKey check before a download. All of them were written years ago, before this rule even existed. I had no appetite to trace every source file by hand, so I wanted a mechanical way to surface them.

The four categories and their reason codes

The categories you are most likely to trip over in your own code are these four. Each has reason codes defined by Apple, and .xcprivacy records both the category and the reason code.

Category (NSPrivacyAccessedAPIType)Common APIsReason codes indie apps often use
UserDefaultsUserDefaults / NSUserDefaultsCA92.1 (used only within the app / App Group)
FileTimestampmodificationDate / creationDate / statC617.1 (display to user) / 3B52.1 (within your container)
DiskSpacevolumeAvailableCapacity… / systemFreeSize85F4.1 (display to user) / E174.1 (write to avoid low-space errors)
SystemBootTimesystemUptime / mach_absolute_time35F9.1 (measure time between on-device events)

The reason codes read alike, so you cannot mechanically settle on a single one. The script only goes as far as proposing candidates; which reason actually fits your usage is a choice the developer makes. Always confirm against Apple's Required Reason API documentation.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦A Python scanner that finds Required Reason APIs across four categories — UserDefaults, file timestamp, disk space, boot time — in your own Swift code
✦How to map detected symbols to .xcprivacy reason codes and head off the ITMS-91053 rejection email before you submit
✦A Claude Code routine that re-scans on every release so declaration gaps never creep back in
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

⟐ Claude Code2026-04-15
Building StoreKit 2 × SwiftUI Purchases with Claude Code — The Minimum That Passes Review
Build a StoreKit 2 × SwiftUI purchase flow end to end with Claude Code as your design partner — PurchaseManager, server-side validation, and paywall UI — plus the operational traps Apple's docs skip, like Ask to Buy and late-arriving transactions.
⟐ Claude Code2026-10-12
After Moving to SPM, My App Died the Moment It Launched — Reading One dyld Line with Claude Code
Right after moving from CocoaPods to Swift Package Manager, the build passed but the app died on launch. Here is how I traced one dyld line to its cause, the fix, and how to verify it.
⟐ Claude Code2026-09-10
One plugin.json turns a shelf of skills into something you can switch off as a group
When I sorted my skills by what work they belong to, the set I open almost daily turned out to be 5 percent of the total. Here is how I dropped a .claude-plugin/plugin.json into each group so I could switch a whole shelf off, plus the two loading rules I tripped over on the way.