Setup and context: Why Privacy Manifests Matter
Since May 2024, all new app submissions and updates to the App Store require a Privacy Manifest (PrivacyInfo.xcprivacy). This file tells Apple which APIs your app accesses and why, ensuring transparency around data usage.
Failing to include a properly configured Privacy Manifest can result in App Store rejection or warning emails containing errors like ITMS-91053. The challenge is that correctly identifying which APIs fall under Apple's "Required Reason" category — and choosing the right reason codes — can be tedious and error-prone when done manually.
What you'll learn:
- The fundamentals of Privacy Manifests and required fields
- Using Antigravity to scan your codebase for Required Reason APIs
- Auto-generating
PrivacyInfo.xcprivacyfrom scan results - A checklist for passing App Store review
This guide assumes you have a working knowledge of iOS development. If you're new to building iOS apps with Antigravity, check out Getting Started with iOS App Development in Antigravity first.
Privacy Manifest Basics
Required Reason API Categories
Apple defines several categories of APIs that require a stated reason. The main categories include:
- File timestamp APIs — accessing creation/modification timestamps of files
- System boot time APIs — retrieving device uptime
- Disk space APIs — reading available storage capacity
- Active keyboard APIs — detecting the current keyboard type
- User defaults APIs — reading/writing via
UserDefaults
For each of these APIs your app uses, you must declare a reason code — a fixed string defined by Apple. For example, if you use UserDefaults to store app settings, the appropriate reason code is CA92.1.
Structure of PrivacyInfo.xcprivacy
The manifest is an XML property list with the following structure:
<?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>
<!-- Data types your app collects -->
<key>NSPrivacyCollectedDataTypes</key>
<array>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeDeviceID</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<false/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
</array>
<!-- API access reasons -->
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
<!-- Tracking -->
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyTrackingDomains</key>
<array/>
</dict>
</plist>Writing this by hand becomes increasingly complex as your project grows — especially when third-party libraries introduce their own API usage.
Step 1: Scan Your Project with Antigravity
Instructing the Agent
Open Antigravity and give the agent the following prompt:
Please do the following:
1. Scan this Xcode project for all Required Reason API usage.
Look for: UserDefaults, FileManager, ProcessInfo,
UIDevice, UITextInputMode, and similar APIs.
2. List each usage with the file name and line number.
3. Based on Apple's official reason codes, suggest appropriate
NSPrivacyAccessedAPITypeReasons for each API.
4. Generate the content for a PrivacyInfo.xcprivacy file.
Example Scan Output
Antigravity will analyze your Swift files and return a report like this:
Scan Results:
[UserDefaults]
- AppSettings.swift:23 — saving and reading user preferences
- OnboardingManager.swift:45 — onboarding completion flag
→ Recommended reason code: CA92.1 (app settings storage)
[FileManager.attributesOfItem]
- CacheManager.swift:67 — checking cache file timestamps
→ Recommended reason code: C617.1 (file management)
[ProcessInfo.systemUptime]
- AnalyticsHelper.swift:89 — calculating session duration
→ Recommended reason code: 35F9.1 (session analytics)
This gives you a project-wide overview of API usage that would take hours to compile manually.
Step 2: Auto-Generate PrivacyInfo.xcprivacy
Generating the File
Once the scan is complete, ask Antigravity to generate the manifest:
Based on the scan results, generate a PrivacyInfo.xcprivacy file with:
- NSPrivacyTracking: false (no ad tracking)
- NSPrivacyTrackingDomains: empty array
- NSPrivacyCollectedDataTypes: crash data only, no device ID
- All detected APIs with their appropriate reason codes
- Compatible with Xcode 15 and later
Reviewing the Generated File
Antigravity will create the file at /YourApp/YourApp/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>NSPrivacyAccessedAPITypes</key>
<array>
<!-- UserDefaults: storing app settings -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
<!-- FileManager: cache management -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
<!-- ProcessInfo: session measurement -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>35F9.1</string>
</array>
</dict>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeCrashData</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<false/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
</array>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyTrackingDomains</key>
<array/>
</dict>
</plist>Step 3: Add the File to Your Xcode Project
Adding to Xcode
To add the generated file to your Xcode project, ask Antigravity for guidance:
Walk me through how to:
1. Drag PrivacyInfo.xcprivacy into the main target folder in Xcode
2. Add it to the correct targets using "Add to targets"
3. Verify it appears in Build Phases → Copy Bundle Resources
4. Run a build to check for any errors
Antigravity will also suggest terminal commands to validate your build:
# Build the project and filter for relevant warnings and errors
xcodebuild -project YourApp.xcodeproj \
-scheme YourApp \
-configuration Debug \
build 2>&1 | grep -E "(error:|warning:|ITMS)"Checking Third-Party Libraries
Libraries you depend on may also access Required Reason APIs. Antigravity can help you verify this:
Please do the following:
1. Parse Package.resolved or Podfile.lock to list all
third-party dependencies.
2. Check whether each library provides its own PrivacyInfo.xcprivacy
(refer to their latest GitHub release pages).
3. For any libraries without manifests, identify which Required Reason
APIs they use and flag them for manual inclusion.
Step 4: Validating in App Store Connect
Aligning with Privacy Nutrition Labels
The contents of your Privacy Manifest must be consistent with the Privacy Nutrition Labels you configure in App Store Connect.
Based on the NSPrivacyCollectedDataTypes in my PrivacyInfo.xcprivacy,
generate a checklist of data types I need to declare in App Store Connect.
Flag any potential mismatches.
A Validation Script for CI
Here's a simple shell script to validate the manifest locally and in CI pipelines:
#!/bin/bash
echo "=== Privacy Manifest Validation ==="
# Check file exists
if [ ! -f "YourApp/PrivacyInfo.xcprivacy" ]; then
echo "❌ PrivacyInfo.xcprivacy not found"
exit 1
fi
# Validate XML format
plutil -lint "YourApp/PrivacyInfo.xcprivacy"
if [ $? -eq 0 ]; then
echo "✅ XML format: valid"
else
echo "❌ XML format: errors found"
fi
# Check tracking flag
TRACKING=$(plutil -extract NSPrivacyTracking raw "YourApp/PrivacyInfo.xcprivacy" 2>/dev/null)
echo "📋 NSPrivacyTracking: $TRACKING"
echo "=== Validation Complete ==="Expected output:
=== Privacy Manifest Validation ===
✅ XML format: valid
📋 NSPrivacyTracking: 0
=== Validation Complete ===
Common Errors and How to Fix Them
Error 1: ITMS-91053 Missing Privacy Manifest
Cause: PrivacyInfo.xcprivacy is not included in the app bundle.
Fix: Check that the file appears in Build Phases → Copy Bundle Resources in Xcode. You can ask Antigravity: "I'm getting ITMS-91053 — can you help me verify the placement of PrivacyInfo.xcprivacy?"
Error 2: Incorrect or Missing Reason Codes
Cause: The API is present in the manifest but the reason code doesn't match the actual usage, or a reason code is missing entirely.
Fix: Ask Antigravity: "What are all valid reason codes for NSPrivacyAccessedAPICategoryUserDefaults?" to get a comprehensive list based on Apple's documentation.
Error 3: Third-Party Library Without a Manifest
Cause: A dependency hasn't yet added PrivacyInfo.xcprivacy to their package.
Fix: Ask Antigravity: "Can you check the privacy manifest support status for [library name] and suggest alternatives if needed?" This often leads to upgrading the library to a newer version that includes the manifest.
Advanced: Integrating into Your CI/CD Pipeline
For ongoing quality assurance, integrate manifest validation into GitHub Actions:
# .github/workflows/privacy-manifest-check.yml
name: Privacy Manifest Validation
on:
pull_request:
paths:
- '**/*.swift'
- '**/PrivacyInfo.xcprivacy'
jobs:
validate:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Validate Privacy Manifest
run: |
if [ ! -f "YourApp/PrivacyInfo.xcprivacy" ]; then
echo "::error::PrivacyInfo.xcprivacy not found"
exit 1
fi
plutil -lint "YourApp/PrivacyInfo.xcprivacy"
echo "✅ Privacy Manifest: OK"For a broader look at iOS-specific Xcode workflows with Antigravity, see Antigravity × Xcode 26 × iOS 26 — Complete iOS Development Guide for WWDC 2026.
Summary
Privacy Manifest compliance is a non-negotiable part of shipping iOS apps today — but it doesn't have to be painful. With Antigravity handling the scanning, code analysis, and file generation, you can go from zero to a validated PrivacyInfo.xcprivacy in a fraction of the time it would take manually.
The key workflow is: scan your project with Antigravity to identify Required Reason API usage, generate the manifest automatically from those results, add it to your Xcode target and verify it in CI, then align your App Store Connect Privacy Nutrition Labels accordingly.
Once your privacy configuration is solid, consider leveling up your async code architecture. The Antigravity × Swift Concurrency Complete Master Guide covers async/await, Actor isolation, and Structured Concurrency in depth — everything you need to build responsive, maintainable iOS apps.