◉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-05-18Advanced

Running Apple Privacy Manifest as an Indie Developer — Catching Dependency Drift with Claude Code

Apple Privacy Manifest (PrivacyInfo.xcprivacy) is a quietly painful area for indie iOS developers. Drawing on twelve years of running iOS apps with over 50 million combined downloads, this article walks through how I use Claude Code to detect drift, respond to rejections, and bake the whole flow into CI.

Claude Code264Apple Privacy ManifestPrivacyInfo.xcprivacyiOS26indie developer21App Store9dependencies

✦ Premium Article

I have been shipping iOS apps as an indie developer since 2014, and somewhere past fifty million combined downloads I started spending roughly as much time keeping up with Apple's policy changes as I did building features. Privacy Manifest (PrivacyInfo.xcprivacy), which Apple began requiring in stages from 2024, has been one of the heavier ones. The reason is structural: it is not enough that your own code is compliant. Every SDK you depend on also has to ship its own manifest, and you have to keep them all in sync as Apple's list of "commonly used APIs" expands.

A few months ago I bumped the AdMob SDK in Beautiful HD Wallpapers and was met with a rejection telling me that NSPrivacyAccessedAPITypes was missing entries. The same SDK update had gone through cleanly on one of my relaxing-music apps six months earlier. The difference was not obvious from a quick diff, and I lost a full day chasing it. This article distills what I have built since then so that days like that do not happen again. I use Claude Code for most of the heavy lifting, and I will show the prompts and scripts exactly as they sit in my repositories today.

Why Privacy Manifest Hits Indie Developers Hardest

Privacy Manifest is a declaration file Apple began rolling out as mandatory across spring 2024. Beyond your own app target, any SDK that touches Apple's list of "commonly used APIs" is also expected to ship its own manifest inside its framework bundle. There are three structural reasons this is harder for indie developers than for teams.

First, the rate at which SDKs adopt new requirements is inconsistent. A typical iOS app pulls in twenty or more dependencies — AdMob, Firebase, Sign in with Apple, lint helpers, reachability utilities — and indie developers rarely have a single dashboard that tracks the compliance status of all of them.

Second, dependencies that were fine when you added them can suddenly require a manifest later. Apple periodically expands the list of Required Reasons API categories. UserDefaults, fileTimestamp, systemBootTime, and diskSpace were all added after the initial release, and older indie apps tend to use them unconsciously.

Third, rejection messages are sparse. App Review usually says only "declarations for NSPrivacyAccessedAPITypes are missing or incomplete," leaving you to figure out which SDK is responsible and which API category needs a new entry.

Folding all of that into a monthly routine without an assistant is what burns time. The realistic move is to put the monitoring and patch generation on Claude Code.

The Minimum Vocabulary You Need

Just enough scaffolding so the rest of the article reads cleanly.

PrivacyInfo.xcprivacy declares four major keys. NSPrivacyTracking is a boolean for tracking activity. NSPrivacyTrackingDomains lists endpoints that contribute to tracking. NSPrivacyCollectedDataTypes describes the categories of data the app collects. And NSPrivacyAccessedAPITypes — the protagonist of this article — is an array of reasons for every Required Reasons API category your app uses.

The currently designated categories include File timestamp APIs, System boot time APIs, Disk space APIs, Active keyboard APIs, and User defaults APIs. Each category has a fixed set of reason codes — for instance, User Defaults APIs recognizes CA92.1, 1C8F.1, C56D.1, and AC6B.1. You pick the ones that match your actual usage and list them under each category.

A minimal real-world file looks like this.

<!-- A minimum PrivacyInfo.xcprivacy -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>NSPrivacyTracking</key>
  <true/>
  <key>NSPrivacyTrackingDomains</key>
  <array>
    <string>googleads.g.doubleclick.net</string>
  </array>
  <key>NSPrivacyCollectedDataTypes</key>
  <array/>
  <key>NSPrivacyAccessedAPITypes</key>
  <array>
    <dict>
      <key>NSPrivacyAccessedAPIType</key>
      <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
      <key>NSPrivacyAccessedAPITypeReasons</key>
      <array>
        <string>CA92.1</string>
      </array>
    </dict>
    <dict>
      <key>NSPrivacyAccessedAPIType</key>
      <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
      <key>NSPrivacyAccessedAPITypeReasons</key>
      <array>
        <string>C617.1</string>
      </array>
    </dict>
  </array>
</dict>
</plist>

The important point is that the values inside NSPrivacyAccessedAPITypeReasons are reason codes, not free text. When you have Claude Code generate manifest snippets, include the Apple reference list in your prompt so it does not invent codes.

✦

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 pragmatic mental model of how Privacy Manifest and Required Reasons APIs interact, sized for indie iOS work rather than enterprise compliance teams
✦A Claude Code workflow with real commands for spotting drift when adding or updating dependencies, before App Store rejection
✦An end-to-end pattern that turns an App Store Connect rejection log into a unified-diff patch and re-submission
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-04
The One File I Keep Out of Claude Code's Reach: project.pbxproj
With Xcode project files, the breakage that still opens costs far more than the breakage that refuses to open. Here is what I measured before moving every edit behind a script, and where the line sits today.