收到 App Store Connect 提示 PrivacyInfo.xcprivacy 无效,邮件通常会指出文件名和归档路径。
最快处理方式:先沿路径确认清单属于主 App、Swift Package 还是第三方 SDK,再回到对应来源修正,重新归档并验证;不要先删除或覆盖同名文件。
这篇文章适合收到隐私清单无效通知、需要定位具体文件的独立开发者。
如果你正在接入第三方 SDK,或要在远程 Mac 上完成 Xcode 归档与提交验收,也可以按下面的场景逐项排查。
App Store Connect 提示 PrivacyInfo.xcprivacy 无效:先从路径追到责任方
Apple 说明,包含无效隐私清单的提交会被拒绝,通知中可以列出无效文件名和它在 App bundle 中的路径。这个路径是定位起点,不是要求你把 App 里所有同名文件都改一遍。Apple 的 TN3181 排查说明和隐私清单添加说明都指出,错误文件可能来自 App 自身,也可能来自第三方 SDK。
先区分两种问题:“文件不在预期位置或没进入归档”,以及“文件进入了归档,但 plist 格式、键或值无效”。只看项目导航器里的源文件,无法证明提交包内的文件正确。
另外,隐私清单不是 App Store Connect 的隐私标签。清单描述 App 或 SDK 收集的数据、跟踪情况及使用受管 API 的原因;商店页面上的隐私详情是另一项填写内容。不要用修改隐私标签来替代清单排错。
主 App 清单缺失:检查 target 与 bundle 位置
如果邮件路径指向 App 主 bundle,先在 Xcode 项目中选中负责构建 App 的 target,检查 PrivacyInfo.xcprivacy 是否加入该 target 的资源,而不是仅存在于磁盘或某个未参与构建的目录。
对 iOS App,Apple 给出的清单位置是 .app bundle 根目录,例如 Sample.app/PrivacyInfo.xcprivacy。Xcode 在清单加入正确 target 后会按产品类型放置文件;所以重点是核实最终产物,而不是手工猜一个目录后复制进去。Apple 的清单布局说明列出了不同平台对应的位置。
还要区分“清单文件的职责”。主 App 清单记录 App 自身适用的数据收集和 required reason API 声明;第三方 SDK 的隐私实践应由 SDK 自己的清单描述。SDK 收集的数据不应简单抄进 App 主清单,来掩盖 SDK 文件缺失或错误。Apple 的数据使用说明明确区分了 App 与 SDK 的声明。
⚠️ 不要为了让提交通过而添加空清单,或照抄其他项目的理由。每项声明都要对应实际使用情况;无根据地补值,可能把格式问题变成内容不实。
Swift Package 源码有清单,为什么归档里没有?
在 Swift Package 中,文件位于仓库并不自动证明它已作为包资源构建。先打开 Package.swift,确认清单归属实际被 App 引用的 target,并检查资源配置。Apple 对 Swift Package 资源的规则是按 target 组织;无法自动识别的文件需要明确声明资源处理方式。Swift Package 资源配置文档说明了 process 和 copy 规则。
排查时按这条链路核对:
- 文件是否位于对应 target 的资源范围内,而不是只放在仓库根目录。
Package.swift是否为该 target 声明了资源;如果已经声明,路径是否与实际文件一致。- 当前 App 是否确实依赖这个 package target,是否选中了正确的 scheme 和构建配置。
- 重新生成 Archive 后,检查产物里由 package 生成的资源 bundle,确认清单确实随依赖进入本次归档。
若源码里存在文件、归档中却找不到,优先修资源声明和 target 归属。不要把一份清单手工塞进主 App bundle,就假设这能修复 package 或 SDK 自身的责任问题。
第三方 SDK 报错:根据归档路径判断该联系谁
如果报错路径落在某个 framework、XCFramework 或依赖资源 bundle 内,先把路径末端的 SDK 名称与项目依赖记录、锁定版本对上。然后查看该版本随包提供的 PrivacyInfo.xcprivacy,不要只检查你自己的源码目录。
处理原则很直接:
- 文件属于 App 主 target:由你检查 target 资源、文件结构和声明内容。
- 文件属于 Swift Package:由你核对 package target 与资源声明;若包本身维护清单,也要确认实际发布版本包含它。
- 文件属于第三方 SDK:先确认 SDK 版本和清单来源。若清单缺失或无效,优先联系 SDK 发布方获取修正版。Apple 也明确建议,对来自第三方 SDK 的无效清单联系其开发者更新 SDK。
这不是把所有 SDK 的问题都归咎于供应方:路径若指向你的 App 主 bundle,仍应由你排查;只有归档证据指向依赖内部时,才按 SDK 路径处理。版本记录、归档文件位置和发布方提供的 SDK 包,能让双方围绕同一文件复核。
清单已进入归档:逐项核对结构与允许值
文件存在但仍被判无效时,先验证它是不是合法的 plist,再核对键值是否符合 Apple 当前规则。TN3181 给出了检查格式的命令:
plutil -lint /path/to/PrivacyInfo.xcprivacy
如果输出 OK,只说明 plist 格式可解析,不代表其中的键和值符合提交要求。若格式检查失败,回到 Xcode 或文本编辑器修正结构后再检查;不要通过改扩展名或重新命名绕过问题。
接着查看邮件或验证结果指向的具体字段。Apple 的无效清单说明列出常见问题,例如键值类型不符、必填数组为空、required reason API 类别或理由不在允许值中。NSPrivacyAccessedAPIType 应匹配实际使用的 API 类别,理由应与该类别及项目用途相符。required reason API 文档说明,每个使用相关 API 的 App 或 SDK 都要在自己的清单中准确描述;SDK 不能依赖宿主 App 的清单代替自己的声明。
不要猜一个“看起来合理”的理由补进去。如果 App 代码没有使用对应 API,就不要为消除错误而虚构使用理由;如果是 SDK 使用,应先核对 SDK 清单和版本。每次修改后保留清单原文、依赖版本和验证反馈,方便复现。
从 Xcode Archive 验收修复,而不是只看源码
邮件里的路径对应的是提交产物。修复后应检查本次要上传的 Xcode Archive,而不是旧归档或本地源文件。
按下面的顺序操作:
- [ ] 在 App Store Connect 通知中复制完整文件路径、文件名和错误字段。
- [ ] 对照 Xcode target、Swift Package 资源声明及依赖版本,确认文件归属。
- [ ] 在对应来源修正 target、资源声明、plist 结构或允许值;第三方 SDK 文件问题则核对发布方提供的版本。
- [ ] 重新执行
Product > Archive,不要把旧 Archive 当作修复后的产物。 - [ ] 在 Organizer 中选中新归档,通过 Finder 查看归档内容,沿通知中的路径确认对应清单。
- [ ] 选择
Validate App完成提交前验证,并保存验证结果与本次构建记录。
Apple 的Xcode 分发与归档文档说明,可以在 Organizer 中选中 Archive 并使用 Validate App,在上传前获得自动验证反馈。验证通过后,确认实际上传的就是这份归档。
不要把“直接改旧归档里的文件”当成常规修复流程。签名用于检测签名后发生的更改;修改 bundle 内容可能使签名失效。Apple 的代码签名说明指出,修改已签名 bundle 后需要重新签名。对 iOS 提交而言,更稳妥的做法是回到项目或依赖源修正,再重新构建和签名,而不是在归档包里手工替换文件。
常见问题
App Store Connect 的通知里有文件路径,怎么确认具体是哪份清单?
先复制通知中的完整路径和文件名,不要只搜索项目源码里的同名文件。打开本次提交对应的 Xcode Archive,在归档包内沿路径核对文件;再对照依赖名称、framework 或资源 bundle,判断它属于主 App、Swift Package 还是第三方 SDK。源码文件和归档文件不是同一证据。
Swift Package 里的 PrivacyInfo.xcprivacy 为什么没进归档?
文件放在仓库或包目录里,并不等于它已作为目标资源参与构建。检查 Package.swift 中对应 target 的资源声明,以及文件是否归属实际被 App 引用的 target;随后重建 Archive,并查看包生成的资源 bundle 是否含清单。若依赖是二进制 SDK,则还要检查发布包本身。
第三方 SDK 的隐私清单报错,应该改 App 还是找 SDK 开发者?
以通知给出的归档路径判断归属。如果文件位于第三方 framework、XCFramework 或 SDK 资源 bundle 内,先核对依赖版本及发布方随包提供的清单;文件本身无效时,应向 SDK 开发者索取修正版,而不是把声明挪进 App 主清单。主 App 清单只负责 App 自身适用的声明。
修好 PrivacyInfo.xcprivacy 后,怎么确认重新提交的文件有效?
不要只在源码中检查或直接改旧归档。保存修改后重新执行 Product > Archive,在 Organizer 里选中新生成的归档,检查通知所指路径对应的文件,再运行 Validate App。确认验证针对本次准备上传的 Archive;如果归档内容在签名后被改动,应回到构建流程重新生成并签名。
如果你平时在 Windows 或 Linux 上写代码,却要临时处理 Xcode 专属的归档和验证,本地环境无法直接完成这段 macOS 工作,借用同事设备也容易遇到依赖、证书和构建版本不一致。反过来,长期、高频的重负载构建,或必须连接本地物理设备与接口的工作,更适合评估自购 Mac。先按 OsxNode 的使用文档确认远程操作方式,再通过方案对比页面判断是否符合你的周期与流程;若只是缺少一段可复核的 Mac 构建环境,可了解 OsxNode 的远程 Mac 选项,用于重新生成 Archive 并完成提交前验证。
常见问题
App Store Connect 的通知里有文件路径,怎么确认具体是哪份清单?
先复制通知中的完整路径和文件名,不要只搜索项目源码里的同名文件。打开本次提交对应的 Xcode Archive,在归档包内沿路径核对文件;再对照依赖名称、framework 或资源 bundle,判断它属于主 App、Swift Package 还是第三方 SDK。源码文件和归档文件不是同一证据。
Swift Package 里的 PrivacyInfo.xcprivacy 为什么没进归档?
文件放在仓库或包目录里,并不等于它已作为目标资源参与构建。检查 Package.swift 中对应 target 的资源声明,以及文件是否归属实际被 App 引用的 target;随后重建 Archive,并查看包生成的资源 bundle 是否含清单。若依赖是二进制 SDK,则还要检查发布包本身。
第三方 SDK 的隐私清单报错,应该改 App 还是找 SDK 开发者?
以通知给出的归档路径判断归属。如果文件位于第三方 framework、XCFramework 或 SDK 资源 bundle 内,先核对依赖版本及发布方随包提供的清单;文件本身无效时,应向 SDK 开发者索取修正版,而不是把声明挪进 App 主清单。主 App 清单只负责 App 自身适用的声明。
修好 PrivacyInfo.xcprivacy 后,怎么确认重新提交的文件有效?
不要只在源码中检查或直接改旧归档。保存修改后重新执行 Product > Archive,在 Organizer 里选中新生成的归档,检查邮件所指路径对应文件,再运行 Validate App。确认验证针对本次准备上传的 Archive;如果归档内容在签名后被改动,应回到构建流程重新生成并签名。
