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>
Врсте података се деле у неколико категорија: контакт информације (име, е-пошта, телефон), финансије (подаци о плаћању), идентификатори (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 у пројекат, али се не препоручује због неслагања при ажурирањима.
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 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 интерфејса. Након компилације, проверите да ли је датотека доспела у бинарну датотеку преко команде 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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође