Apple Privacy Manifest files explained for indie iOS developers in 2026
What goes inside a PrivacyInfo.xcprivacy file, why Apple now expects one for many SDKs, and how a solo iOS developer can map their stack to the four required arrays without guessing.
If you ship an iOS app and use almost any third-party SDK, Apple expects a
Privacy Manifest (PrivacyInfo.xcprivacy) inside your app bundle and inside
each SDK bundle. The deadline for one common set of SDKs was 2024-Q2; the rules
have continued to expand since.
This post walks through what the file actually contains, what Apple’s docs say about each section, and the common mistakes solo founders make when they wire this in for the first time. It’s a primer, not legal advice — when in doubt, read Apple’s docs and ship the file the way Xcode validates it.
TLDR
A PrivacyInfo.xcprivacy file is a property list with four arrays:
NSPrivacyTracking— boolean, whether your app or SDK tracks users in Apple’s sense of the word.NSPrivacyTrackingDomains— the domains your code reaches that are used for tracking. Apple’s App Tracking Transparency blocks these when the user has not granted permission.NSPrivacyAccessedAPITypes— the list of “required reason” APIs you call (e.g.UserDefaults, file timestamps, system boot time) and the documented reason code from Apple’s list.NSPrivacyCollectedDataTypes— the categories of data your code collects, linked-to-user flag, used-for-tracking flag, and one or more purposes from Apple’s fixed list.
These four arrays roll up across your app and every SDK that ships its own manifest. The Xcode 15 build report will surface SDKs that fail to ship one for SDKs on Apple’s “commonly used SDKs” list.
Why Apple is asking for this
The Privacy Manifest sits next to Apple’s older App Privacy Details disclosure, which is a checklist you fill in inside App Store Connect. The manifest is the machine-readable version of the same information, scoped per SDK. Apple’s Privacy Manifest Files documentation states that the two should be consistent: the App Store Connect form aggregates the data collection that the manifests describe.
The other half is the “required reason” APIs. Some iOS APIs were historically
abused for device fingerprinting — file timestamps, UserDefaults, system boot
time, free disk space, and active keyboards. Apple now requires that any access
to those APIs comes with a documented reason code drawn from a fixed list, in
your manifest. Apple’s documentation lists each API and each allowed reason
code.
Note on volatility: Apple’s required-reason API list and the SDK list grow over time. Re-check Apple’s docs before each major release. We accessed the linked pages on 2026-05-25; if you are reading this much later, treat the categories below as the shape of the requirement, not the final list.
What an indie-stack manifest typically looks like
Most indie iOS apps that ship a payment flow, an LLM-backed feature, and analytics will touch the same handful of categories. The manifest typically may look something like this (example wording, not advice):
<?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>
<false/>
<key>NSPrivacyTrackingDomains</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>
<key>NSPrivacyCollectedDataTypes</key>
<array>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeEmailAddress</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeUserID</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
</array>
</dict>
</array>
</dict>
</plist>
The reason codes (CA92.1, C617.1) come straight from Apple’s documentation
for each required-reason API. Do not invent them — use the ones Apple lists.
A six-step mini workflow
- List every third-party SDK in your app. Include analytics, payments, auth, push notifications, crash reporters, and any SwiftPM/CocoaPods package that hits the network.
- Check Apple’s required-reason API category list. Apple publishes a list
of API categories that need a documented reason — file timestamps, system
boot time, disk space, active keyboards,
UserDefaults. Identify every one your app reaches, directly or via an SDK. - For each SDK on Apple’s commonly-used list, confirm the vendor ships its own manifest. Apple’s documentation lists the SDKs that must ship a manifest and an SDK signature. If a vendor hasn’t shipped one, file an issue and consider whether you can substitute.
- Author your app’s manifest. Use Xcode’s File → New → File → App Privacy template. Xcode will validate the structure.
- Map every entry to your App Privacy Details form in App Store Connect. The two must be consistent — that’s an App Review hot button.
- Re-check after each new SDK addition and after Apple updates the required-reason API list.
Common mistakes
- Leaving
NSPrivacyTrackingtrue when you don’t actually fingerprint or share with a tracker. Apple’s definition of “tracking” is narrower than the common-English use; review their docs before flipping the flag. - Forgetting reason codes for
UserDefaults. Almost every app uses it. Apple’s reason list includesCA92.1(access in-app state) and a few others; use the one that matches. - Skipping the manifest because the app is “small”. Apple’s enforcement is SDK-level, not app-size-level. A 500-line app that imports a single SDK with a manifest still needs one of its own.
- Letting the manifest drift from your App Privacy Details form. They describe the same data — keep them in sync.
FAQ
Does a manifest replace the App Privacy Details form? No. App Privacy Details is filled in inside App Store Connect; the manifest ships inside the app bundle. They describe the same data and Apple expects them to match. (Apple’s App Privacy Details docs, accessed 2026-05-25.)
What happens if I ship without a manifest? For SDKs on Apple’s commonly-used list, App Store Connect upload validation may warn or reject. For everything else, the manifest is part of the privacy declaration Apple expects — review the current state of Apple’s docs.
Do I need one for a watchOS or visionOS target? Apple’s documentation lists each platform that supports the manifest. Check the documentation page for the current platform list.
Is UserDefaults always going to need a reason code?
That has been the case since Apple introduced the required-reason categories.
Verify against the current Apple docs before each release — the reason list
itself is versioned.
Related reading
S-001, S-002, S-007, S-008. Each source row is listed in the full disclosure matrix .
Open the Indie App Privacy Disclosure Matrix for a side-by-side view of which platforms expect which disclosures for the services in your stack.