Privacy Manifest (PrivacyInfo.xcprivacy) — це файл, який усі застосунки та сторонні SDK зобов'язані включати до збірки iOS, починаючи з весни 2024 року. Apple вимагає декларувати причини використання захищених API (Required Reason API) та типи даних, що збираються. Згідно з документацією розробника Apple, кожен бінарний файл у складі застосунку — основний таргет, фреймворки, залежності 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), зв'язок (NSPrivacyCollectedDataLinked), мета (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) та контент користувача (фото, відео, файли). Кожна категорія додатково маркується як «пов'язана з користувачем» або «не пов'язана».
Пов'язана означає, що дані пов'язані з обліковим записом користувача; не пов'язана — дані агреговані або анонімізовані. Від цього маркування залежить, як Apple відображає позначку приватності: пов'язані дані позначаються жовтим, не пов'язані — зеленим.
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 вручну в проєкт, але це не рекомендується через розбіжності при оновленнях.
Створити PrivacyInfo.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 не знайдено")
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. Після компіляції перевірте, що файл потрапив у бінарний файл через команду 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також