Skip to main content

Fixing ITMS-91053: Missing API Declaration in Privacy Manifests

 Receiving an email from App Store Connect with the subject "Action Needed: Missing API declaration" is the new standard frustration for iOS developers. Specifically, error ITMS-91053 blocks your submission or triggers a warning because your binary utilizes "Required Reason APIs" without declaring them in a PrivacyInfo.xcprivacy file.

Since the enforcement of iOS 17 privacy standards in Spring 2024, Apple requires explicit declarations for APIs that have the potential to be misused for device fingerprinting. This applies even if you are using the APIs for benign, standard purposes like storing user preferences.

This guide provides the technical root cause analysis and the specific XML configurations required to resolve ITMS-91053 and get your build approved.

The Root Cause: Why ITMS-91053 Happens

Apple’s static analyzer scans your compiled binary (and all embedded third-party SDKs) during the upload process. It looks for symbols associated with four specific categories of APIs:

  1. User Defaults (UserDefaults)
  2. File Timestamp APIs (e.g., statfstatgetattrlist)
  3. System Boot Time (e.g., mach_absolute_time)
  4. Disk Space APIs (e.g., statfsstatvfs)

If the analyzer detects these symbols but fails to find a corresponding NSPrivacyAccessedAPITypes entry in your bundle's PrivacyInfo.xcprivacy file, it flags the build.

The rejection is not an accusation of data misuse; it is a procedural failure to declare intent. To fix this, you must explicitly map the API usage to an Apple-approved "Reason Code."

Step 1: Identifying the Offending API

The rejection email usually identifies which specific API category is missing. However, if the email is vague, you can scan your codebase.

If you are using UserDefaults anywhere in your Swift or Obj-C code, you must declare it. If you use third-party libraries (like Realm, Firebase, or Alamofire), they likely use these APIs internally. While modern versions of these SDKs include their own privacy manifests, older versions do not, forcing the main app to declare usage or update the dependency.

Step 2: Creating the Privacy Manifest

If you do not already have a privacy manifest, you must create one.

  1. In Xcode, go to File > New > File.
  2. Search for App Privacy.
  3. Select App Privacy File.
  4. Name it PrivacyInfo.xcprivacy (this is the default and mandatory name).
  5. Ensure the file is checked in the Target Membership for your main app bundle.

Step 3: Configuring the Required Reason APIs

The PrivacyInfo.xcprivacy file is a Property List (plist). While you can edit it using Xcode's GUI, editing the raw XML source code is often less error-prone for copy-pasting specific keys.

To edit as source code, right-click the file in Xcode → Open As → Source Code.

You need to add the NSPrivacyAccessedAPITypes array. Below is a complete, valid example covering the most common scenario: User Defaults.

Implementation for UserDefaults

If your app uses UserDefaults.standard or UserDefaults(suiteName:), use the following configuration. The reason code CA92.1 covers accessing defaults within your own app explicitly.

<?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>
        <dict>
            <key>NSPrivacyAccessedAPIType</key>
            <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
            <key>NSPrivacyAccessedAPITypeReasons</key>
            <array>
                <string>CA92.1</string>
            </array>
        </dict>
    </array>
</dict>
</plist>

Breaking Down the Key-Values

  • NSPrivacyAccessedAPITypes: The root array containing all declared APIs.
  • NSPrivacyAccessedAPIType: The string identifier for the API category (e.g., NSPrivacyAccessedAPICategoryUserDefaults).
  • NSPrivacyAccessedAPITypeReasons: An array of strings representing the approved reason codes.

Reference: All Required API Categories

If your rejection cites other APIs, use the templates below. You must select the Reason Code that accurately reflects your usage.

1. File Timestamp APIs

Used when checking file creation or modification dates (e.g., for cache invalidation).

Key: NSPrivacyAccessedAPICategoryFileTimestamp Common Reason: C617.1 (Inside App) or 3B52.1 (General).

<dict>
    <key>NSPrivacyAccessedAPIType</key>
    <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
    <key>NSPrivacyAccessedAPITypeReasons</key>
    <array>
        <string>C617.1</string>
    </array>
</dict>

2. System Boot Time

Used for measuring elapsed time (e.g., mach_absolute_time).

Key: NSPrivacyAccessedAPICategorySystemBootTime Common Reason: 35F9.1 (Measuring time elapsed between events).

<dict>
    <key>NSPrivacyAccessedAPIType</key>
    <string>NSPrivacyAccessedAPICategorySystemBootTime</string>
    <key>NSPrivacyAccessedAPITypeReasons</key>
    <array>
        <string>35F9.1</string>
    </array>
</dict>

3. Disk Space APIs

Used for checking available storage before writing files.

Key: NSPrivacyAccessedAPICategoryDiskSpace Common Reason: E174.1 (Checking space before writing).

<dict>
    <key>NSPrivacyAccessedAPIType</key>
    <string>NSPrivacyAccessedAPICategoryDiskSpace</string>
    <key>NSPrivacyAccessedAPITypeReasons</key>
    <array>
        <string>E174.1</string>
    </array>
</dict>

Validating Your Fix

Before submitting to App Store Connect, you can verify that Xcode recognizes your privacy manifest and merges it correctly with any SDK manifests.

  1. Select your Product scheme.
  2. Go to Product > Archive.
  3. Once the archive is created, right-click it in the Organizer and select Generate Privacy Report.

This generates a PDF summarizing all declared data types and APIs. If your "Required Reason APIs" section is empty despite using UserDefaults, your PrivacyInfo.xcprivacy is either malformed or not a member of the target bundle.

Edge Case: Third-Party SDKs

If you have added the manifest but still receive ITMS-91053, the culprit is likely a static library or an old framework embedded in your app.

If a library like "OldAnalyticsSDK" uses stat API but does not include a privacy manifest (or a signature), the App Store attributes that usage to your main app.

The Solution:

  1. Update Dependencies: Check if a newer version of the pod/package exists that includes a privacy manifest (released after Spring 2024).
  2. Over-declare: If you cannot update the SDK, you must declare their API usage in your PrivacyInfo.xcprivacy. For example, if the SDK uses mach_absolute_time, add NSPrivacyAccessedAPICategorySystemBootTime to your app's manifest.

Summary

ITMS-91053 is a compliance check, not a code error. To resolve it:

  1. Create PrivacyInfo.xcprivacy.
  2. Identify the API category from the rejection email (usually UserDefaults).
  3. Add the corresponding Dictionary to NSPrivacyAccessedAPITypes.
  4. Select the Reason Code that matches your usage (e.g., CA92.1).

By explicitly declaring these APIs, you satisfy Apple's requirement to distinguish between functional API usage and device fingerprinting attempts.