Privacy Manifest (PrivacyInfo.xcprivacy) — файл, который все приложения и сторонние SDK обязаны включать в сборку iOS, начиная с весны 2024 года. Apple требует декларировать причины использования защищённых API (Required Reason API) и типы собираемых данных. Согласно Apple Developer Documentation, каждый бинарник в составе приложения — основной таргет, фреймворки, Swift Package Manager зависимости — должен содержать собственный Privacy Manifest.
Главное
Privacy Manifest — это файл PrivacyInfo.xcprivacy в формате property list (XML), который декларирует, какие типы данных собирает приложение и почему оно использует определённые API. Apple ввела манифесты в рамках инициативы по повышению прозрачности приватности, аналогичной Privacy Nutrition Label, но на уровне кода и бинарника.
Основное назначение манифеста — документировать использование так называемых Required Reason API. Это категории API, которые могут быть использованы для снятия цифрового отпечатка устройства (fingerprinting), поэтому каждое их использование должно сопровождаться декларацией конкретной причины из утверждённого Apple списка.
Начиная с 1 мая 2024 года, Apple отклоняет сборки, которые не содержат Privacy Manifest. Это касается как основных таргетов приложения, так и всех встроенных SDK и зависимостей. Согласно WWDC 2023, манифест обязателен для всех приложений, распространяемых через App Store.
Манифест должен присутствовать в каждом бинарнике — не только в главном приложении, но и в каждом фреймворке и статической библиотеке. Если сторонний SDK не предоставил манифест, разработчику нужно добавить его вручную или обратиться к поставщику SDK за обновлением.
До появления манифестов разработчики могли использовать обширные системные API (доступ к файловой системе, дате/времени, системным логам) без прозрачного объяснения цели использования. Это создавало риск утечки данных через сторонние SDK, которые могли собирать информацию без ведома разработчика.
По данным Mysk Inc. (2023), многие популярные SDK использовали API для снятия отпечатка устройства без явной необходимости — например, читали время uptime для определения часового пояса или сканировали директории для сбора метаданных. Privacy Manifest обязывает декларировать каждое такое действие.
Помимо Required Reason API, манифест включает раздел NSPrivacyTracking — флаг, указывающий, использует ли приложение трекинг (требует ATT), и NSPrivacyCollectedDataTypes — список типов собираемых данных в формате Privacy Nutrition Label.
Privacy Nutrition Label — это пользовательское представление на странице приложения в App Store, показывающее, какие данные собирает приложение. Privacy Manifest — это технический файл внутри бинарника, который проверяется Apple автоматически. Если данные в манифесте не совпадают с метками в App Store Connect, Apple отклоняет сборку.
Таким образом, манифест — источник правды для системы проверки Apple. На его основе автоматически генерируются метки приватности, но разработчик должен поддерживать оба представления в актуальном состоянии. Изменение манифеста после публикации требует отправки новой сборки на ревью.
Файл PrivacyInfo.xcprivacy использует формат property list с корневым типом Dictionary. Основные ключи верхнего уровня: NSPrivacyTracking (Boolean), NSPrivacyTrackingDomains (Array), NSPrivacyCollectedDataTypes (Array), NSPrivacyAccessedAPITypes (Array).
Ключ NSPrivacyTracking — булево значение, указывающее, применяет ли приложение трекинг (требует ATT). Если true, необходимо также указать NSUserTrackingUsageDescription в Info.plist. Ключ NSPrivacyTrackingDomains — массив доменов, на которых применяется трекинг.
Ключ NSPrivacyCollectedDataTypes — массив словарей, каждый из которых описывает тип собираемых данных: категория (NSPrivacyCollectedDataType), обязательность (NSPrivacyCollectedDataTypeLinked), цель (NSPrivacyCollectedDataTypePurposes). Цели включают: разметка третьих сторон, аналитика, разработка продукта и персонализация контента.
Ключ NSPrivacyAccessedAPITypes — массив словарей для каждой категории Required Reason API: категория (NSPrivacyAccessedAPITypeReasons) — конкретная причина из утверждённого списка Apple и NSPrivacyAccessedAPIType — идентификатор категории API.
<!-- 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>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>
Типы данных делятся на несколько категорий: контактная информация (имя, email, телефон), финансы (платёжные данные), идентификаторы (IDFA, User ID), данные об использовании (логи, клики), диагностика (crash logs) и контент пользователя (фото, видео, файлы). Каждая категория дополнительно маркируется как «связанная с пользователем» (linked) или «не связанная» (not linked).
Linked означает, что данные связаны с учётной записью пользователя; not linked — данные агрегированы или анонимизированы. От этой маркировки зависит, как Apple отображает метку приватности: linked данные отмечаются жёлтым, not linked — зелёным.
Apple выделила несколько категорий API, каждое использование которых должно сопровождаться конкретной причиной из утверждённого списка. Причина — это уникальный код, напримерC617.1 или 35F9.1, который сопоставлен с конкретной целью, разрешённой Apple.
Категория NSPrivacyAccessedAPICategoryFileTimestamp включает API для доступа к временным меткам файлов (creationDate, modificationDate). Причины: C617.1 (синхронизация файлов), 3B52.1 (бекап), 0A2A.1 (антифрод).
Категория NSPrivacyAccessedAPICategoryDiskSpace включает API для проверки свободного места на диске (NSFileManager. Проверки (NSFileManager). Причины: E174.1 (управление кешем), 85F4.1 (загрузка контента), B728.1 (диагностика).
Категория NSPrivacyAccessedAPICategorySystemBootTime включает API доступа к времени загрузки системы (uptime). Причина только одна: 35F9.1 (измерение времени сессии для аналитики). Любое другое использование расценивается как fingerprinting.
Каждая категория имеет от 1 до 5 утверждённых причин. Разработчик обязан выбрать причину, наиболее точно соответствующую реальному использованию API. Предоставление недостоверной причины может привести к отклонению сборки или бану аккаунта.
Начиная с 1 мая 2024 года, все сторонние SDK — как бинарные, так и с открытым исходным кодом — обязаны включать Privacy Manifest в свой пакет. Apple проверяет манифесты для всех зависимостей, и если хотя бы один SDK не имеет манифеста, сборка будет отклонена.
Крупные SDK (Firebase, Adjust, AppsFlyer, Facebook SDK) уже обновили свои пакеты. Если ваш проект использует малоизвестный SDK, проверьте его версию и при необходимости обновите или обратитесь к разработчику. Временное решение — добавить манифест за SDK вручную в проект, но это не рекомендуется из-за расхождения при обновлениях.
Создать Privacy Info.xcprivacy можно через встроенный шаблон Xcode 15+ или вручную. Рассмотрим оба варианта.
В Xcode 15 добавлен шаблон Privacy Manifest: File → New → File → Resource → Privacy Manifest. Xcode создаёт файл с базовой структурой и заполняет NSPrivacyTracking и пустые массивы для API и данных. После создания нужно вручную указать причины для каждого используемого Required Reason API.
Шаблон автоматически добавляет файл в основной таргет. Если в проекте есть несколько таргетов (Extensions, Watch app), нужно добавить манифест в каждый. Xcode не проверяет наличие манифеста в зависимостях на этапе компиляции — только на этапе архивации.
// AppDelegate: проверка манифеста на этапе разработки
import Foundation
func validatePrivacyManifest() {
guard let path = Bundle.main.path(
forResource: "PrivacyInfo", ofType: "xcprivacy"
) else {
print("PrivacyInfo.xcprivacy not found")
return
}
guard let dict = NSDictionary(contentsOfFile: path)
else { return }
print("Privacy manifest loaded: \(dict.count) keys")
}
Можно создать PrivacyInfo.xcprivacy вручную как обычный XML-файл property list. Для этого создайте файл с именем PrivacyInfo.xcprivacy, напишите стандартный заголовок plist и добавьте корневой словарь с необходимыми ключами. Убедитесь, что файл добавлен в таргет (Target Membership).
Ручной способ полезен, когда нужно добавить манифест в статическую библиотеку или Package Manager зависимость, не используя Xcode UI. После компиляции проверьте, что файл попал в бинарник через команду nm или архивацию.
Перед отправкой сборки в App Store необходимо проверить, что Privacy Manifest корректен и полон. Apple предоставляет несколько инструментов проверки.
При архивации проекта (Product → Archive) Xcode выполняет проверку манифестов. Если обнаружена ошибка — отсутствие манифеста, неверная причина, пустая категория — архивация завершается ошибкой. Лог ошибок выводится в Issue navigator с указанием проблемного SDK и категории API.
Дополнительная проверка выполняется на стороне App Store Connect при загрузке сборки. Если валидация не пройдена, сборка отклоняется с автоматическим письмом, содержащим идентификатор проблемного API и рекомендуемое исправление.
Для автоматизации проверки используйте скрипты, которые анализируют бинарник на предмет использования Required Reason API. Apple предоставляет инструмент libtool и скрипты проверки символов, но сообщество разработало более удобные утилиты.
# Поиск использования FileTimestamp API в бинарнике
nm MyApp.app/MyApp | grep "NSFileCreationDate"
# Проверка наличия PrivacyInfo.xcprivacy в приложении
find MyApp.app -name "*.xcprivacy"
Самая распространённая ошибка — отсутствие манифеста в одном из SDK. Даже если основной таргет содержит манифест, Apple проверяет все бинарники по отдельности. Вторая по частоте — неверный код причины: использование причины для одной категории API с API из другой категории.
Третья ошибка — избыточное декларирование API, которые на самом деле не используются. Разработчики добавляют все возможные причины «на всякий случай», что настораживает ревьюеров Apple. Добавляйте только те категории, которые действительно используются. Используйте статический анализатор Xcode для проверки.
Часто задаваемые вопросы
Начиная с 1 мая 2024, Apple отклоняет любую сборку без манифеста. Ошибка возникает на этапе загрузки в App Store Connect. Старые приложения не блокируются, но обновления требуют обязательного включения манифеста.
Да, манифест обязателен для всех платформ Apple: iOS, iPadOS, macOS, tvOS, watchOS и visionOS. Требования к Required Reason API едины для всех платформ, хотя наборы API могут незначительно отличаться.
Если SDK не предоставил манифест, создайте отдельный файл PrivacyInfo.xcprivacy и добавьте его в группу SDK в проекте. Укажите причины для API, которые использует этот SDK, на основе документации SDK.
Да. При автоматической проверке Apple сверяет декларированные причины с фактическими вызовами API. Несоответствие ведёт к отклонению. При ручной проверке ревьюер может запросить пояснения.
Да, Apple проверяет манифесты для всех зависимостей, включая SPM. Поставщики пакетов обязаны включать PrivacyInfo.xcprivacy в свои репозитории. Xcode предупреждает о пропущенных манифестах при архивации.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также