Home / Blog / iOS 17 Privacy Manifest: how to fill it in correctly

iOS 17 Privacy Manifest: how to fill it in correctly

Apple's PrivacyInfo.xcprivacy file is mandatory at submission time. Get it wrong and you get rejected.

Apple introduced the Privacy Manifest (PrivacyInfo.xcprivacy) file with iOS 17. As of May 2024 it’s mandatory. Submit to the App Store with a missing or incorrect manifest and you get rejected outright.

I’ve added the manifest to all 12 of my iOS apps. What I learned: Apple’s documentation covers about 70% of what you need to write. The other 30% comes from experience. This post walks through how I fill in each field.

What is the Privacy Manifest?

An XML plist file. It declares:
– Which user data your app collects
– Why you’re collecting it
– Which Required Reason APIs your app calls
– Which tracking domains your app connects to

All of this gets read automatically when you upload to App Store Connect and turned into a public privacy report.

NSPrivacyCollectedDataTypes

This array has an entry for every category of data your app collects.

Example: the app collects the user’s email and uses it for analytics.

<key>NSPrivacyCollectedDataTypes</key>
<array>
    <dict>
        <key>NSPrivacyCollectedDataType</key>
        <string>NSPrivacyCollectedDataTypeEmailAddress</string>
        <key>NSPrivacyCollectedDataTypeLinked</key>
        <true/>
        <key>NSPrivacyCollectedDataTypeTracking</key>
        <false/>
        <key>NSPrivacyCollectedDataTypePurposes</key>
        <array>
            <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
        </array>
    </dict>
</array>

The keys:

  • NSPrivacyCollectedDataType: which data (Email, Phone, Location, HealthData, etc).
  • NSPrivacyCollectedDataTypeLinked: is this data linked to the user’s identity? (true = stored with user ID)
  • NSPrivacyCollectedDataTypeTracking: is it used for third-party tracking? Apple’s definition of tracking (cross-app, cross-website).
  • NSPrivacyCollectedDataTypePurposes: why do you collect it? Analytics, AppFunctionality, DeveloperAdvertising, ProductPersonalization.

Required Reason APIs

iOS 17 moved certain system APIs into a “Required Reason” category. If you call them, you must declare why.

Most common ones:
UserDefaults (CA92.1)
FileTimestamp (C617.1)
SystemBootTime (35F9.1)
DiskSpace (85F4.1)
ActiveKeyboards (54BD.1)

Example: you use UserDefaults (every iOS app does):

<key>NSPrivacyAccessedAPITypes</key>
<array>
    <dict>
        <key>NSPrivacyAccessedAPIType</key>
        <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
        <key>NSPrivacyAccessedAPITypeReasons</key>
        <array>
            <string>CA92.1</string>
        </array>
    </dict>
</array>

CA92.1 = “Access information from user defaults stored by the app itself”. You’re reading your own UserDefaults, not someone else’s app’s.

Every Required Reason API has its own reason codes. The full list is in Apple’s documentation.

NSPrivacyTracking

If your app does tracking, this is true. Apple defines tracking as: combining data with third-party data to build a profile about a user.

<key>NSPrivacyTracking</key>
<true/>

If you only do your own analytics (Mixpanel, your own backend), this is usually false.

If you use the Facebook SDK, Google Analytics, AdMob, or other advertising/tracking SDKs, it’s true.

NSPrivacyTrackingDomains

A list of tracking domains. Requests to these domains get blocked if the user hasn’t granted ATT (App Tracking Transparency) permission.

<key>NSPrivacyTrackingDomains</key>
<array>
    <string>graph.facebook.com</string>
    <string>doubleclick.net</string>
</array>

Every tracking SDK’s domains go here. Miss one, and its requests get blocked with silent failures.

Third-party SDK manifests

This is where it gets messy. Apple also requires every SDK you use to have its own Privacy Manifest. Popular SDKs ship with manifests now, but some are behind.

Check your SDK list:
– Firebase: has a manifest
– Alamofire: has a manifest
– RevenueCat: has a manifest
– Facebook SDK: has a manifest
– OneSignal: has a manifest
– AppsFlyer: has a manifest
– Branch: no manifest (problem for custom SDK users)
– Smaller/older SDKs: manifest may be missing

Include an SDK without a manifest and App Store Connect upload warns you. Upgrade to the latest version of every SDK before a release build.

Validation at upload time

Archiving in Xcode 15:

Product > Archive
Organizer opens
"Distribute App" > App Store Connect
Validation is automatic

Validation catches issues like missing manifests, undeclared Required Reason APIs, or missing tracking domains.

Fix, re-archive, re-validate. Validation has to be clean before you upload.

Common mistakes

1. Forgetting to declare a reason for UserDefaults. Every iOS app uses UserDefaults. It’s the most commonly forgotten entry.

2. Shipping a third-party SDK with no manifest. Ignoring the build warning. Apple rejects the submission.

3. Wrong NSPrivacyTracking value. You’re doing analytics but leaving Tracking as false (correct). Or you use Facebook Ads but leave Tracking as false (wrong, rejected).

4. Under-declaring data types. The app collects email but the manifest doesn’t say so. Rejected.

5. Wrong purposes. Declared as analytics but actually used for advertising.

Creating the manifest file

In Xcode:

  1. File > New > File
  2. Resource section > App Privacy File
  3. Name it PrivacyInfo.xcprivacy
  4. Fill in the fields through the Xcode GUI
  5. Include it in the project target

Writing the XML by hand is possible but the Xcode GUI is safer: no typos.

Incremental onboarding

Adding a manifest to an existing app:

  1. Create an empty manifest through the Xcode GUI
  2. Run Xcode’s Privacy Report feature (Product > Build For > Analysis)
  3. The report shows which APIs and data types are missing
  4. Fill in the manifest based on the report
  5. Re-analyze until there are no warnings

A one to two hour job. After that, every new SDK or feature takes 5 to 10 minutes of manifest updates.

Compliance testing

Final checks before submission:

  1. Xcode Privacy Report: is the manifest complete?
  2. App Store Connect validation: does the archive upload without errors?
  3. Test with Tracking disabled. User picked “Ask App Not to Track”. Does the app crash, do features degrade gracefully?
  4. SDK check: Sentry, Firebase, RevenueCat on the latest version? (Manifests are only in the latest versions.)

All four clean = ready to submit.

Relationship to Privacy Nutrition Labels

Users see your app’s privacy info on the App Store (the Nutrition Label). The manifest generates these labels.

Privacy Manifest = source of truth
Nutrition Labels = user-facing view

You used to fill in the Nutrition Labels form by hand. Now the manifest generates them. Consistency goes up.

Bottom line

The Privacy Manifest is a required part of iOS submission. Read the docs carefully once, build the first manifest through Xcode’s GUI, upgrade SDKs to their latest versions, validate before you upload.

Once set up correctly, every release after just needs 5 to 10 minutes of manifest review. The pain of the initial setup is collected back on every subsequent release.

Have a project on this topic?

Leave a brief summary — I’ll get back to you within 24 hours.

Get in touch