2026年Apple隐私清单(Privacy Manifest)自查清单:必需理由API十二项核验
Apple 的隐私清单(Privacy Manifest)要求自 2024 年 5 月 1 日 起强制执行,而它至今仍是少数几个与应用行为无关、却直接导致上传失败的环节——只要用到了必需理由 API 又没有在隐私清单里声明理由,构建包就 不会被 App Store Connect 接受。同一个文件里其实是两项独立义务:数据收集声明(适用于全部平台),以及必需理由 API 声明(适用于 iOS、iPadOS、tvOS、visionOS 与 watchOS)。如果应用链接了 Apple 常用 SDK 清单 中的任何一个,该 SDK 自己的清单与签名还要另行满足。以下是我们每份归档发出前都会跑的十二项核验。
一句话版本:文件必须命名为 PrivacyInfo.xcprivacy,必须放在「使用该 API 的那段代码所属」的 bundle 里,并且每个 API 类别都要用 Apple 公布的固定理由代码声明——不是你自己写的一句话。
1. 这个应用到底需不需要隐私清单?
由两项义务决定,而两者的适用范围并不相同。数据收集声明对应用或第三方 SDK 在所有平台都适用;必需理由 API 声明适用于 iOS、iPadOS、tvOS、visionOS 与 watchOS。只要应用用到了必需理由 API、收集了使用该应用的人的数据、使应用能够收集用户数据,或访问了跟踪域名,就需要这个文件;而如果它本身属于清单内的 SDK,则无条件需要。
2. 文件名对了没,有没有进 bundle?
PrivacyInfo.xcprivacy 是唯一被认可的文件名。在 Xcode 里:File > New File,下滑到 Resource 区,选择 App Privacy File 类型,勾选目标后创建。随后务必确认它出现在该 target 的 resources 里——Xcode 只会在那里找到清单,否则生成隐私报告时不会采用。若你交付的是静态库形式的第三方 SDK,请使用 Xcode 15 起的静态 framework 支持,把清单与其他资源一起放进 framework target 的 bundle resources。
3. 四个顶层键是否齐全?
NSPrivacyTracking——应用或第三方 SDK 是否将数据用于跟踪。NSPrivacyTrackingDomains——为跟踪而访问的域名。NSPrivacyCollectedDataTypes——每种收集到的数据类型一个字典,分别记录数据类型、是否与用户身份关联、是否用于跟踪、以及收集目的。NSPrivacyAccessedAPITypes——每个必需理由 API 类别一个字典,记录类别与其理由代码。
如果不做跟踪,就在文件里明确写「否」,而不是把这组键直接省略。
4. 五类必需理由 API 是否逐类排查过?
Apple 把受管制的 API 归为五类。你写的代码要查,链接的每个 SDK 里的代码也要分别查——只要出现一次调用,声明就是必须的:
- 文件时间戳——
getattrlist、getattrlistbulk、fgetattrlist、fstat、fstatat、lstat、getattrlistat。 - 系统启动时间——
mach_absolute_time()。 - 磁盘空间——
statfs、statvfs、fstatfs、fstatvfs,以及getattrlist系列。 - 活动键盘——用于获知设备上当前启用哪些键盘的 API。
- User defaults——通过 user defaults API 进行的读写。
5. 每个条目是否都用了获批的理由代码?
理由代码是 Apple 公布的固定字符串,只能从列表里选,不能自造。我们最常声明的是:文件时间戳——DDA9.1(向设备使用者展示时间戳)、C617.1(应用容器、App Group 容器或 CloudKit 容器内的文件)、3B52.1(用户明确授权的文件或目录,例如通过文稿选择器)、0A2A.1(第三方 SDK 为应用封装该 API)。系统启动时间——35F9.1(测量应用内事件之间的时间差,或实现计时器)、8FFB.1(为应用内发生的事件计算绝对时间戳)、3D61.1(用户主动提交的可选问题报告中的启动时间)。磁盘空间——85F4.1(向设备使用者展示磁盘空间)、E174.1(检查是否有足够空间写入,或在空间不足时清理)、7D9E.1(可选问题报告中的磁盘空间)、B728.1(健康研究类应用)。User defaults——CA92.1(仅本应用可访问的数据)、1C8F.1(应用、应用扩展与 App Clips)、C56D.1(SDK 封装,仅第三方 SDK 可用)、AC6B.1(MDM 下发的受管配置键)。活动键盘——3EC4.1(自定义键盘类应用)、54BD.1(展示正确的定制界面)。
6. 理由与用户可见的功能是否一致?
每个理由都附带条件,审核方会照着读。E174.1 要求应用依据磁盘空间做出用户可观察到的不同行为;3EC4.1 只留给主要功能是系统级自定义键盘的应用;3D61.1 要求启动时间作为用户主动提交报告的一部分被显著展示。请选择真正描述代码行为的那个理由,并且声明的理由必须与向用户呈现的功能保持一致。
7. 该禁止的外传是否都停掉了?
声明理由只授权「为此目的」使用该 API 及派生数据。多数理由都带着一句话:所访问的信息及其派生信息不得传出设备。文档明确的例外很窄:应用内事件之间的时间差可以外传(35F9.1);应用内事件的绝对时间戳可以外传(8FFB.1),但启动时间本身不行;问题报告中的取值只能在用户主动提交该报告之后外传;磁盘空间只允许通过局域网传到同一使用者的另一台设备用于显示,绝不能经互联网传输。这条规则最先出问题的通常是统计类 SDK,签字之前先核实它上传了什么。
8. 跟踪声明是否自洽?
无论用户是否授予跟踪权限,设备指纹(fingerprinting)都是被禁止的,也不得把这些 API 或其派生数据用于跟踪。如果答案是「不跟踪」,就把它明确写进文件——写 false 是声明,留空不是。
9. SDK 由谁的清单覆盖?
由 SDK 自己的清单覆盖。第三方 SDK 不能依赖链接它的应用所带的清单,也不能依赖应用链接的其他 SDK 的清单。应用中凡是使用必需理由 API 的可执行文件或动态库,其所属 bundle 内都必须带有声明该 API 的清单。反过来的一条对开发者更友好:应用的隐私清单不需要覆盖它所链接的第三方 SDK 收集的数据。
10. 常用 SDK 清单与签名是否查过?
提交包含清单内 SDK 的新应用,或提交「新增了清单内 SDK」的应用更新时,该 SDK 的隐私清单是强制项;若这些 SDK 以二进制依赖形式使用,还必须提供签名,让 Xcode 能验证 SDK 由同一位开发者签署。清单内 SDK 的任意版本都在适用范围内,重新打包这些 SDK 的第三方库同样如此。这份清单覆盖面很广:Flutter 及其常用插件、FirebaseCore、FirebaseMessaging、FirebaseCrashlytics、OneSignal、Alamofire、SDWebImage、Reachability、nanopb、GoogleUtilities、UnityFramework、hermes 等都在其中。若某个这类 SDK 卡住了上传,解法通常就是把它升到自带清单与签名的版本。
11. 上传前能不能先出隐私报告?
在 Xcode 中打开项目,选择 Product > Archive,然后在 Organizer 里按住 Control 点击该归档,选择 Generate Privacy Report。Xcode 会把你的清单与应用链接的所有 SDK 的清单汇总成一份报告。请在填写 App Store Connect 隐私信息之前读这份报告——审核方看到的是同一份画面。
12. 不加清单直接上传会怎样?
先是邮件提醒:Apple 会发信提示你补上缺失的理由。然后是硬性拦截——自 2024 年 5 月 1 日 起,未在隐私清单中说明必需理由 API 用途的应用 不会被 App Store Connect 接受。这类校验不过的构建包不会进入审核队列;对于矩阵化运营的账号,感受会非常直接,因为同样的 API 调用会在每个包里重复出现。
来源
- Apple Developer——Privacy manifest files:developer.apple.com/documentation/bundleresources/privacy-manifest-files
- Apple Developer——Describing use of required reason API:developer.apple.com/documentation/bundleresources/describing-use-of-required-reason-api
- Apple Developer——Describing data use in privacy manifests:developer.apple.com/documentation/bundleresources/describing-data-use-in-privacy-manifests
- Apple Developer——Third-party SDK requirements:developer.apple.com/support/third-party-SDK-requirements
规模化运营开发者账号?运营侧交给我们。