Как внедрить PrivacyInfo.xcprivacy для приложений и SDK под iOS

opoinstall
2026-08-21
5 min read

Как внедрить PrivacyInfo.xcprivacy для iOS-приложений? Реализация PrivacyInfo.xcprivacy требует добавления корректного манифеста конфиденциальности в цель вашего приложения или SDK, объявления утвержденных кодов обоснования для любых API обязательного назначения (Required Reason APIs), таких как User Defaults или System Boot Time, а также проверки того, что сторонние зависимости соответствуют требованиям к манифестам конфиденциальности и цифровым подписям, применимым к их форме распространения.

Манифест конфиденциальности (PrivacyInfo.xcprivacy) — это стандартизированный файл со списком свойств (property list), который включается в состав iOS-приложений и сторонних SDK. В нем декларируются категории сбора данных, конфигурации доменов для отслеживания и утвержденные обоснования для доступа к API обязательного назначения, определяемым Apple. Начиная с 1 мая 2024 года, приложения, отправляемые в App Store Connect, должны содержать одобренные причины для API обязательного назначения, используемых кодом приложения, включая применимый код сторонних SDK.

Термин Определение
PrivacyInfo.xcprivacy Стандартизированный формат списка свойств Apple для объявления правил конфиденциальности приложений и SDK.
Required Reason APIs Специфические системные API (например, User Defaults или Disk Space), требующие кодов явного обоснования.
Resource Bundle Signing Процесс подписания кодом в сборочной системе, применяемый к целевым пакетам ресурсов (resource bundles), который в некоторых конфигурациях Xcode и CocoaPods может потребовать устранения неполадок.
Privacy Report Сводный PDF-отчет, генерируемый в Xcode 15 и выше, объединяющий декларации манифестов конфиденциальности, обнаруженные в заархивированном приложении и связанных SDK.

Понимание требований Apple к манифестам конфиденциальности для iOS SDK

Архитектура манифестов конфиденциальности: манифест основного приложения против встроенных манифестов SDK

Фреймворк манифестов конфиденциальности Apple устанавливает модульную модель прозрачности всей цепочки поставки программного обеспечения для iOS. Вместо того чтобы заставлять хост-приложение вручную проверять и декларировать детали внутренней реализации каждой импортируемой библиотеки, Apple разделяет управление конфиденциальностью на четкие уровни:

  • Манифест основного приложения: охватывает сбор данных первой стороны, домены отслеживания на уровне приложения и API обязательного назначения, вызываемые напрямую кодом основной цели приложения.
  • Встроенные манифесты SDK: декларации API обязательного назначения должны принадлежать приложению или коду стороннего SDK, который использует эти API. Для исполняемых файлов и динамических библиотек пакет, содержащий этот исполняемый файл или библиотеку, должен включать соответствующий манифест конфиденциальности; сторонний SDK не может полагаться на манифест хост-приложения для отчета об использовании им API обязательного назначения.
  • Автоматическая агрегация зависимостей: при создании архива приложения в Xcode 15 или новее сборочная система обходит дерево зависимостей, обнаруживает все файлы PrivacyInfo.xcprivacy и объединяет их в единый сводный отчет о конфиденциальности (Privacy Report).

Архитектура манифеста PrivacyInfo xcprivacy для приложения и SDK

Четыре корневых ключа конфигурации

Каждый файл PrivacyInfo.xcprivacy структурирован как словарь списка свойств XML, содержащий до четырех ключей корневого уровня:

  • NSPrivacyTracking (Boolean): объявляет, использует ли приложение или SDK данные, собранные из приложения, для трекинга в соответствии с определениями фреймворка прозрачности отслеживания приложений Apple (ATT).
  • NSPrivacyTrackingDomains (Array of Strings): перечисляет интернет-домены, с которыми устанавливает соединение приложение или SDK и которые осуществляют трекинг. Если пользователь не предоставил разрешение ATT, iOS блокирует сетевые соединения с доменами, указанными в этом массиве. Если приложение или SDK не подключается к доменам трекинга, этот ключ можно опустить.
  • NSPrivacyCollectedDataTypes (Array of Dictionaries): сообщает определяемые Apple категории данных, которые приложение или SDK собирает о пользователях, а также информацию о том, связаны ли эти данные с личной идентификацией пользователя, используются ли они для трекинга и для каких операционных целей они собираются.
  • NSPrivacyAccessedAPITypes (Array of Dictionaries): декларирует API обязательного назначения, определяемые Apple и вызываемые бинарным файлом, в сопровождении утвержденных строковых кодов обоснования.

Четыре корневых ключа конфигурации PrivacyInfo xcprivacy

Контроль соблюдения требований App Store Connect и диагностика ошибок

App Store Connect проверяет соблюдение манифестов конфиденциальности во время приема бинарных файлов:

  • Отсутствует декларация API (ITMS-91053): возникает, когда скомпилированный бинарный файл или связанная библиотека вызывают символ API обязательного назначения, но соответствующий ключ категории отсутствует в NSPrivacyAccessedAPITypes.
  • Декларация недействительного кода обоснования: происходит, когда в манифесте указана неутвержденная, некорректная или устаревшая строка обоснования для конкретной категории API.
  • Отсутствует обязательный манифест стороннего SDK: применяется в сценариях загрузки, определенных текущими требованиями Apple к сторонним SDK для указанных SDK, требуя наличия как манифестов конфиденциальности, так и действительных цифровых подписей для бинарных дистрибутивов.

Разработчики, интегрирующие клиентскую атрибуцию и диплинкинг, могут обратиться к документации по интеграции iOS SDK для получения технических спецификаций касательно объявлений в манифесте.

Смотрите также: iOS SDK ──> Архитектура мобильной атрибуции

Категории API обязательного назначения и утвержденные коды обоснований

Пять категорий API обязательного назначения

Согласно технической заметке Apple TN3183, Apple определяет пять конкретных категорий API, которые требуют кодов явного обоснования в NSPrivacyAccessedAPITypes. Мобильные SDK и приложения для iOS обычно взаимодействуют с четырьмя основными категориями:

  • NSPrivacyAccessedAPICategoryUserDefaults: доступ к локальным настройкам приложения через UserDefaults или NSUserDefaults.
  • NSPrivacyAccessedAPICategorySystemBootTime: измерение прошедшего времени или меток времени с использованием системных API загрузки, таких как sysctl(KERN_BOOTTIME) или systemUptime.
  • NSPrivacyAccessedAPICategoryDiskSpace: проверка емкости файловой системы через statfs, statvfs или volumeAvailableCapacityKey.
  • NSPrivacyAccessedAPICategoryFileTimestamp: проверка дат создания или изменения файлов с помощью stat, getattrlist или contentModificationDateKey.
  • NSPrivacyAccessedAPICategoryActiveKeyboards: проверка активных расширений пользовательских клавиатур (используется в основном специализированными утилитами клавиатур).

Выбранные маппинги утвержденных кодов обоснования для распространенных сценариев использования SDK

Таблица ниже сосредоточена на категориях, часто встречающихся в универсальных мобильных SDK; ознакомьтесь с актуальной документацией Apple для получения полного списка причин, включая активные клавиатуры. Чтобы соответствовать рекомендациям Apple, разработчики должны выбирать коды обоснований, которые строго соответствуют их реальному использованию данных во время выполнения:

Ключ категории API Утвержденный код Официальная цель, согласованная с Apple
NSPrivacyAccessedAPICategoryUserDefaults CA92.1 Чтение и запись данных, доступных только самому приложению
NSPrivacyAccessedAPICategoryUserDefaults 1C8F.1 Чтение и запись данных, общих только внутри одной группы приложений (App Group)
NSPrivacyAccessedAPICategoryUserDefaults C56D.1 Сторонняя обертка SDK, предоставляющая функции «ключ-значение» для хост-приложения
NSPrivacyAccessedAPICategorySystemBootTime 35F9.1 Измерение прошедшего времени между событиями, происходящими внутри приложения, или обработка таймеров
NSPrivacyAccessedAPICategorySystemBootTime 8FFB.1 Вычисление абсолютных меток времени для событий, произошедших внутри приложения
NSPrivacyAccessedAPICategoryDiskSpace E174.1 Проверка свободного места на диске перед записью файлов и изменение поведения приложения при нехватке места
NSPrivacyAccessedAPICategoryDiskSpace 85F4.1 Доступ к информации о дисковом пространстве для отображения доступной емкости пользователю
NSPrivacyAccessedAPICategoryFileTimestamp C617.1 Доступ к метаданным файлов внутри контейнера приложения, группы приложений (App Group) или контейнера CloudKit
NSPrivacyAccessedAPICategoryFileTimestamp 3B52.1 Доступ к метаданным файлов или каталогов, явно выбранных пользователем
NSPrivacyAccessedAPICategoryFileTimestamp 0A2A.1 Сторонняя обертка SDK, получающая доступ к меткам времени файлов исключительно от имени хост-приложения

Категории API обязательного назначения и утвержденные коды обоснований

Создание примера файла свойств PrivacyInfo.xcprivacy

Настройка типов сбора данных

Массив NSPrivacyCollectedDataTypes сообщает определяемые Apple категории данных, которые приложение или SDK собирает о пользователях, а также информацию о том, связаны ли эти данные с личной идентификацией пользователя, используются ли они для трекинга и для каких операционных целей они собираются:

  • NSPrivacyCollectedDataType: стандартный строковый идентификатор Apple (например, NSPrivacyCollectedDataTypeDeviceID).
  • NSPrivacyCollectedDataTypeLinked: логическое значение (boolean), указывающее, связаны ли данные с личностью конкретного пользователя.
  • NSPrivacyCollectedDataTypeTracking: логическое значение, указывающее, используются ли данные для трекинга между приложениями.
  • NSPrivacyCollectedDataTypePurposes: массив стандартных строк целей (например, NSPrivacyCollectedDataTypePurposeAnalytics).

Декларирование доменов отслеживания

Если SDK или приложение осуществляет трекинг в соответствии с определениями ATT, все соответствующие домены отслеживания должны быть объявлены в NSPrivacyTrackingDomains. Если пользователь не предоставил разрешение на трекинг, iOS блокирует сетевые соединения с заявленными доменами. Если приложение или SDK не участвует в трекинге, параметр NSPrivacyTracking следует установить в значение false, а массив NSPrivacyTrackingDomains можно опустить.

Приведенная ниже конфигурация списка свойств иллюстрирует пример схемы PrivacyInfo.xcprivacy. Включайте только те категории и причины, которые отражают реальную реализацию вашего приложения:

```xml
<?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>NSPrivacyCollectedDataTypes</key>
    <array>
        <dict>
            <key>NSPrivacyCollectedDataType</key>
            <string>NSPrivacyCollectedDataTypeDeviceID</string>
            <key>NSPrivacyCollectedDataTypeLinked</key>
            <false/>
            <key>NSPrivacyCollectedDataTypeTracking</key>
            <false/>
            <key>NSPrivacyCollectedDataTypePurposes</key>
            <array>
                <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
                <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
            </array>
        </dict>
    </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>NSPrivacyAccessedAPICategorySystemBootTime</string>
            <key>NSPrivacyAccessedAPITypeReasons</key>
            <array>
                <string>35F9.1</string>
            </array>
        </dict>
        <dict>
            <key>NSPrivacyAccessedAPIType</key>
            <string>NSPrivacyAccessedAPICategoryDiskSpace</string>
            <key>NSPrivacyAccessedAPITypeReasons</key>
            <array>
                <string>E174.1</string>
            </array>
        </dict>
        <dict>
            <key>NSPrivacyAccessedAPIType</key>
            <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
            <key>NSPrivacyAccessedAPITypeReasons</key>
            <array>
                <string>C617.1</string>
            </array>
        </dict>
    </array>
</dict>
</plist>

Устранение ошибок подписи пакетов ресурсов CocoaPods

Первопричина: сбои подписания пакетов ресурсов в Xcode 15 и 16

При интеграции зависимостей через CocoaPods в Xcode 15 или 16 разработчики часто сталкиваются с остановкой компиляции:

Signing for "libOpoInstallSDK-OPPrivacy" requires a development team. Select a development team in the Signing & Capabilities editor.

Эта ошибка сборки представляет собой проблему интеграции Xcode и CocoaPods:

  • Традиционная статическая библиотека .a не может напрямую содержать такие ресурсы, как PrivacyInfo.xcprivacy. Apple рекомендует упаковывать код статического SDK и ресурсы вместе внутри статического фреймворка.
  • Некоторые интеграции CocoaPods вместо этого генерируют отдельные цели пакетов ресурсов для распространения ресурсов вместе со статическими библиотеками.
  • Определенные цели пакетов ресурсов, созданные CocoaPods, могут наследовать конфигурации подписи, из-за чего сборки Xcode останавливаются с запросом команды разработчиков. Это проблема интеграции сборочной системы, а не требование схемы PrivacyInfo.xcprivacy.

Применение целевых обходных путей сборочной системы в Podfile

Чтобы устранить эту ошибку в автоматизированных сборках, разработчики могут использовать локальный хук post_install в файле проекта Podfile. Поскольку это обходное решение сборочной системы для неисполняемых пакетов ресурсов, команды должны применять его к конкретным затронутым целям пакетов или проверять затронутые зависимости перед применением изменений глобально.

Приведенный ниже скрипт на Ruby демонстрирует, как перебирать цели CocoaPods и отключать подпись для указанных целей пакетов ресурсов:

post_install do |installer|
  # Specify non-executable resource bundle targets that encounter signing errors without a development team
  target_bundle_names = [
    'libOpoInstallSDK-OPPrivacy'
  ]

  installer.pods_project.targets.each do |target|
    if target.respond_to?(:product_type) &&
       target.product_type == "com.apple.product-type.bundle" &&
       target_bundle_names.include?(target.name)
      target.build_configurations.each do |config|
        # Strip code signing requirement from designated non-executable resource bundles
        config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
        config.build_settings['CODE_SIGN_IDENTITY'] = ''
      end
    end
  end
end

Аудит и генерация сводного отчета о конфиденциальности в Xcode

Генерация единого отчета о конфиденциальности через Xcode Archive Organizer

Чтобы убедиться, что все цели первой стороны и сторонние зависимости должным образом объявлены перед отправкой бинарного файла:

  1. Откройте свой проект в Xcode 15 или новее.
  2. Выберите Product > Archive для создания релизного архива.
  3. В Xcode Organizer нажмите правой кнопкой мыши (или удерживая Control) на архив и выберите Generate Privacy Report.
  4. Сохраните и изучите сгенерированный PDF-отчет, чтобы подтвердить, что все API обязательного назначения, категории данных и манифесты сторонних SDK отображаются корректно.

Статический анализ из командной строки: эвристические сканирования перед отправкой

Команды разработчиков могут внедрять эвристические проверки перед отправкой в конвейеры непрерывной интеграции (CI/CD), сканируя скомпилированные бинарные файлы на наличие ограниченных символов с помощью nm и otool:

# Scan unpacked application binary for candidate Required Reason API symbols
nm -u /path/to/Payload/YourApp.app/YourApp | grep -E 'sysctl|statfs|statvfs|getattrlist|NSUserDefaults'

# Check embedded frameworks and bundles for PrivacyInfo.xcprivacy manifests
find /path/to/Payload/YourApp.app -name "PrivacyInfo.xcprivacy"

Само по себе присутствие символа не определяет, какое утвержденное обоснование применяется; изучите фактический путь вызовов и вариант использования перед изменением манифеста. Команды должны использовать функцию Xcode Generate Privacy Report и предварительные проверки App Store Connect для авторитетной верификации.

Рабочий процесс предварительного аудита манифеста конфиденциальности iOS

Диагностическая матрица: первопричины отклонений манифестов конфиденциальности в App Store

Режим сбоя / Код ошибки Базовая первопричина Наблюдаемое поведение системы Рекомендуемое устранение
Отсутствует декларация API (ITMS-91053) Бинарный файл вызывает ограниченный API, но в манифесте отсутствует категория Предупреждение или отклонение при загрузке в App Store Connect Объявите соответствующую категорию API и действительный код обоснования
Недействительный код обоснования Указанный код обоснования не одобрен Apple для данной категории App Store Connect отклоняет отправку Обновите XML, используя утвержденную строку обоснования из спецификаций Apple
Отсутствует манифест стороннего SDK Зависимость от указанного стороннего SDK не содержит встроенного манифеста App Store Connect отмечает отсутствие манифеста SDK Обновите зависимость до версии, предоставляющей PrivacyInfo.xcprivacy
Ошибка подписи кода пакета ресурсов CocoaPods создает цель пакета ресурсов без команды подписания Компиляция Xcode останавливается во время сборки Оцените целевой пакет, вызывающий сбой, и примените локальный обходной путь подписи в Podfile
Необъявленная конечная точка трекинга Приложение подключается к серверам трекинга, не указанным в NSPrivacyTrackingDomains Конфигурация конфиденциальности неполна для поведения приложения в части трекинга Перечислите все конечные точки трекинга в разделе NSPrivacyTrackingDomains

Часто задаваемые вопросы (FAQ)

Нужен ли каждому стороннему SDK собственный файл PrivacyInfo.xcprivacy?
Не только потому, что это сторонняя библиотека. SDK, использующий API обязательного назначения, должен сообщать об этом в своем собственном манифесте конфиденциальности, а SDK, собирающие данные, должны описывать этот сбор в собственном манифесте. Кроме того, Apple требует манифесты конфиденциальности для перечисленных SDK в сценариях отправки, описанных в ее текущих требованиях к сторонним SDK, а также требует наличия подписей, когда эти перечисленные SDK используются в качестве бинарных зависимостей. Хост-приложения не могут декларировать API обязательного назначения от имени встроенного SDK.
Что произойдет, если приложение использует UserDefaults без объявления утвержденной причины?
Если бинарный файл приложения или связанный SDK вызывает API `UserDefaults` без объявления `NSPrivacyAccessedAPICategoryUserDefaults` с действительным кодом обоснования (таким как `CA92.1` для данных внутри приложения или `1C8F.1` для групп приложений), App Store Connect пометит бинарный файл ошибкой `ITMS-91053` или заблокирует отправку. Правильный код обоснования зависит от фактического использования данных во время выполнения.
Может ли приложение объявить несколько причин для одной категории API?
Да. Ключ `NSPrivacyAccessedAPITypeReasons` принимает массив строк. Если приложение или SDK использует API для нескольких различных утвержденных целей (например, проверка достаточного дискового пространства для изменения поведения приложения через `E174.1`, а также отображение доступного дискового пространства пользователю через `85F4.1`), в массиве могут быть объявлены оба утвержденных кода обоснования.

Резюме и фреймворк принятия решений

Фреймворк манифестов конфиденциальности Apple обеспечивает прозрачность всей цепочки поставки ПО для iOS. Обеспечение беспрепятственной отправки в App Store требует от команд разработчиков проведения аудита кода первой стороны на предмет использования API обязательного назначения, проверки того, что зависимости сторонних SDK удовлетворяют требованиям манифеста конфиденциальности, применимым к их использованию API, а также надлежащего управления подписанием пакетов ресурсов CocoaPods.

Информацию о декларациях манифеста конфиденциальности для конкретных продуктов см. в документации OpoInstall. Сравните поставляемый манифест с фактической интеграцией приложения и актуальными требованиями Apple.

Связанные материалы

  • Концепции: манифесты конфиденциальности (Privacy Manifests), API обязательного назначения (Required Reason APIs), подписание пакетов ресурсов (Resource Bundle Code Signing), отчеты о конфиденциальности (Privacy Reports), соблюдение требований App Store (App Store Compliance)

  • Технологии: Xcode 15+, менеджер зависимостей CocoaPods, Swift Package Manager, iOS SDK OpoInstall

  • Стандарты: спецификация манифеста конфиденциальности Apple, раздел 5.1.1 руководства по проверке приложений App Store Review Guidelines

  • API и конфигурации: PrivacyInfo.xcprivacy, NSPrivacyAccessedAPITypes, хук Podfile post_install

Официальная документация

Share this article