Privacy manifest (PrivacyInfo.xcprivacy) implementation including required reason APIs, tracking domains, third-party SDK declarations, and App Tracking Transparency. Use when preparing apps for App Store privacy requirements.
npx skills add https://github.com/rshankras/claude-code-apple-skills --skill privacy-manifests
Advisory skill for implementing Apple's privacy manifest (PrivacyInfo.xcprivacy) requirements: manifest file format, required reason APIs, tracking declarations, third-party SDK privacy, and App Tracking Transparency.
Use this skill when the user:
| Problem | Section |
|---------|---------|
| Creating PrivacyInfo.xcprivacy from scratch | Privacy Manifest File Format + Required Reason APIs |
| App Store rejection about required reason APIs | Required Reason APIs (match APIs in your code) |
| Declaring tracking domains | Tracking Domains and NSPrivacyTracking |
| Third-party SDK privacy | Third-Party SDK Declarations |
| Implementing ATT | App Tracking Transparency |
| Filling out App Store privacy labels | Privacy Nutrition Labels |
| Generating Xcode report | Xcode Privacy Report |
Glob: **/PrivacyInfo.xcprivacy
Grep: "NSPrivacyAccessedAPITypes|NSPrivacyTracking|NSPrivacyTrackingDomains"
Grep: "NSFileCreationDate|NSFileModificationDate|NSURLCreationDateKey"
Grep: "systemUptime|ProcessInfo.*processInfo"
Grep: "volumeAvailableCapacity|URLResourceKey.*volume"
Grep: "UserDefaults"
Grep: "activeInputModes|UITextInputMode"
Grep: "ATTrackingManager|requestTrackingAuthorization"
Check: Does PrivacyInfo.xcprivacy exist? Are all required reason APIs declared? Is NSPrivacyTracking correct? Are tracking domains listed? Do third-party SDKs have their own manifests? Use the sections below to generate correct entries.
The privacy manifest is a property list named PrivacyInfo.xcprivacy. Add it via File > New > File > App Privacy in Xcode. Four required top-level keys:
<?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>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array/>
</dict>
</plist>
// Package.swift
.target(
name: "MyLibrary",
resources: [
.copy("PrivacyInfo.xcprivacy")
]
)
Apple requires you to declare why your app uses certain system APIs. You must include at least one valid reason code for each API category your app uses.
APIs that access file creation or modification dates.
| Reason Code | Description |
|-------------|-------------|
| DDA9.1 | Display file timestamps to the user |
| C617.1 | Access timestamps inside the app container, app group container, or CloudKit container |
| 3B52.1 | Access timestamps of files or directories the user specifically granted access to (document picker, drag and drop) |
| 0A2A.1 | Access timestamps for files managed by the app itself (third-party SDK only) |
Common triggers: NSFileCreationDate, NSFileModificationDate, NSURLContentModificationDateKey, NSURLCreationDateKey, getattrlist, stat, fstat.
APIs that read how long the system has been running.
| Reason Code | Description |
|-------------|-------------|
| 35F9.1 | Measure elapsed time between events within the app |
| 8FFB.1 | Calculate absolute timestamps for events (e.g., events that occurred before app launch) |
| 3D61.1 | Access system boot time for the purposes of user-facing functionality |
Common triggers: systemUptime, ProcessInfo.processInfo.systemUptime, mach_absolute_time, clock_gettime(CLOCK_MONOTONIC).
APIs that query available or total disk space.
| Reason Code | Description |
|-------------|-------------|
| E174.1 | Display disk space to the user |
| 85F4.1 | Check whether there is sufficient disk space to write files |
| AB6B.1 | Query disk space for the app's own functionality, do not send off device |
| 7D9E.1 | Query disk space for the app's own functionality, results sent off device (e.g., analytics) |
Common triggers: volumeAvailableCapacityKey, volumeAvailableCapacityForImportantUsageKey, volumeAvailableCapacityForOpportunisticUsageKey, volumeTotalCapacityKey, statfs, statvfs.
APIs that read or write to UserDefaults.
| Reason Code | Description |
|-------------|-------------|
| CA92.1 | Read/write data accessible only to the app itself |
| 1C8F.1 | Read/write data accessible to app groups (shared UserDefaults) |
| C56D.1 | Read/write data from a third-party SDK for the SDK's own functionality |
| AC6B.1 | Read data from UserDefaults to retrieve a configuration set by an MDM (managed device) |
Common triggers: UserDefaults, NSUserDefaults, standardUserDefaults.
APIs that enumerate installed keyboards.
| Reason Code | Description |
|-------------|-------------|
| 3EC4.1 | Customize the app's UI based on active keyboards (e.g., supporting specific languages) |
| 54BD.1 | A custom keyboard app accessing active keyboards to implement its functionality |
Common triggers: UITextInputMode.activeInputModes, activeInputModes.
Each entry has the category identifier and an array of reason codes. See "Common Patterns" below for a full XML example.
NSPrivacyTracking declares whether your app tracks users. Apple defines tracking as: linking user/device data from your app with data from other companies' apps, websites, or offline properties for advertising, or sharing data with data brokers.
Apple does not consider these to be tracking: on-device-only data linking, fraud detection, security, or compliance.
If NSPrivacyTracking is true:
NSPrivacyTrackingDomains (the system blocks them until ATT is granted)<key>NSPrivacyTracking</key>
<true/>
<key>NSPrivacyTrackingDomains</key>
<array>
<string>analytics.example.com</string>
<string>tracker.adnetwork.com</string>
</array>
If your app does not track users, set NSPrivacyTracking to false and leave the domains array empty.
Starting Spring 2024, apps that include commonly used third-party SDKs must ensure those SDKs provide their own PrivacyInfo.xcprivacy files. Apple publishes a list of SDKs that require privacy manifests and signatures, including Alamofire, FBSDKCoreKit, Firebase, Google Analytics, Kingfisher, Lottie, Realm, SDWebImage, and many others. See Apple's full list.
Third-party XCFrameworks should be signed by their developer. Prefer SDKs distributed through Swift Package Manager (signatures verified automatically). For XCFrameworks, verify the signature matches the expected developer.
Glob: **/Pods/**/PrivacyInfo.xcprivacy
Glob: **/.build/**/PrivacyInfo.xcprivacy
Glob: **/Carthage/**/PrivacyInfo.xcprivacy
Grep: "pod '|.package(url:"
If a third-party SDK lacks a privacy manifest and uses required reason APIs, contact the maintainer -- declaring its API usage in your own manifest is a stopgap, not a fix.
You must present the ATT prompt if:
You do not need ATT for:
import AppTrackingTransparency
func requestTrackingPermission() {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
// IDFA available via ASIdentifierManager.shared().advertisingIdentifier
break
case .denied, .restricted:
// Do not track
break
case .notDetermined:
break
@unknown default:
break
}
}
}
<key>NSUserTrackingUsageDescription</key>
<string>We use this identifier to show you relevant ads and measure ad performance.</string>
Register ad network identifiers in Info.plist:
<key>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>example123.skadnetwork</string>
</dict>
</array>
The privacy manifest feeds into the App Store privacy labels ("nutrition labels") displayed on your app's product page. The connection works as follows:
| Manifest Key | App Store Privacy Label |
|-------------|-------------------------|
| NSPrivacyCollectedDataTypes | "Data Used to Track You" and "Data Linked to You" sections |
| NSPrivacyTracking | Determines if "Data Used to Track You" section appears |
| NSPrivacyAccessedAPITypes | Not directly shown, but required for submission |
Each entry declares: data type, whether it is linked to user identity, whether it is used for tracking, and purposes.
<key>NSPrivacyCollectedDataTypes</key>
<array>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeEmailAddress</string>
<key>NSPrivacyCollectedDataTypeLinked</key> <!-- linked to user identity? -->
<true/>
<key>NSPrivacyCollectedDataTypeTracking</key> <!-- used for tracking? -->
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
</array>
Common data types: EmailAddress, Name, PhoneNumber, Location, DeviceID, CrashData, PerformanceData, ProductInteraction, PurchaseHistory (prefix each with NSPrivacyCollectedDataType).
Common purposes: AppFunctionality, Analytics, ThirdPartyAdvertising, ProductPersonalization (prefix each with NSPrivacyCollectedDataTypePurpose).
The App Store privacy label must match your manifest declarations. Inconsistencies trigger review delays or rejections.
Generate a consolidated report via Product > Generate Privacy Report (or from the Organizer after archiving). Xcode produces a PDF listing all privacy manifest entries from the app and every embedded framework/SDK. Use this to verify all required reason APIs are declared, confirm third-party SDKs include their own manifests, and cross-check collected data types before filling out App Store Connect privacy labels.
NSPrivacyAccessedAPICategoryUserDefaults with reason CA92.1.UserDefaults.standard.set(true, forKey: "onboardingComplete") with no manifest entryMost apps need at minimum UserDefaults declared. Start from the minimal manifest structure above and populate NSPrivacyAccessedAPITypes:
<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>
Add to the template above: set NSPrivacyTracking to true, list tracking domains, add NSPrivacyCollectedDataTypes entries (see "Privacy Nutrition Labels" for format), implement ATT, and add NSPrivacyAccessedAPICategoryDiskSpace with reason 7D9E.1 if sending disk metrics off-device.
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling
Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification
Take rshankras/privacy-manifests from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.