iOS 隐私清单缺失怎么办?2026 归档排查
收到隐私清单通知后,先依据错误代码和文件路径判断问题来自缺失、格式无效,还是第三方 SDK。本文提供责任定位对比、清单校验命令和 Archive 验收步骤,帮你确认修复确实进入待提交产物。
目录
先按通知中的错误代码和文件路径,确认问题是清单缺失、格式无效,还是第三方 SDK 没提供清单;修复后检查最终 Archive,再重新验证提交产物。这个排查顺序适用于收到隐私清单告警、并且能取得当前构建归档的 iOS 开发者。
本周建议动作:保留通知原文,先定位它指向的组件,再检查本次 Archive;不要先把 SDK 的隐私声明抄进 App 自己的清单。
适合收到 ITMS-91061 或类似通知、需要定位责任组件的独立开发者。
维护 CocoaPods、Swift Package 或 XCFramework 依赖的小团队,可用下文核对 SDK 是否把清单带入归档。
负责远程 Mac 或 CI 发布验收的开发者,可把 Archive 检查加入提交前流程。
iOS 隐私清单缺失:先从通知代码和路径判断故障类型
错误代码、邮件措辞和文件路径,是定位起点;项目导航栏里能看到文件,不代表归档中已经有它。先区分“文件不存在”“文件存在但结构或值无效”“通知指向的第三方 SDK 未提供清单”,再决定改 App Target、修清单内容,还是联系 SDK 提供方。
Apple 对 ITMS-91061 的说明指出,通知会列出缺少隐私清单的 SDK 名称和路径,并建议联系 SDK 提供方取得包含有效清单的版本;不要用 App 自己的清单代替 SDK 的隐私声明。具体可查看 Apple 关于第三方 SDK 隐私清单要求的说明。
| 你看到的线索 | 优先判断 | 下一步 |
|---|---|---|
| ITMS-91061,并列出 SDK 或组件路径 | 该依赖可能缺少清单 | 从路径确认实际嵌入的 SDK,核对版本并联系提供方 |
| ITMS-91056,说明清单无效并给出文件路径 | 文件已被发现,但 plist 格式、键或值可能不符合要求 | 对通知指向的文件运行 plutil -lint,再核对键和值 |
| 只在源码目录找到文件,Archive 中查不到 | 文件未加入正确 Target、未作为资源打包,或归档使用了不同构建输入 | 查 Target 资源配置与最终 .app、framework 内容 |
Apple 的技术说明将无效清单问题归为 plist 格式错误,或包含无效键值;它还给出了 ITMS-91056 示例和命令行校验方式。详细规则见 TN3181:排查无效隐私清单。
第一步:确认 App Target 和平台对应的打包位置
App 自身的 PrivacyInfo.xcprivacy 必须被构建该 App 的 Target 使用,并进入最终产品;仅把文件放进源码目录,或在 Xcode 项目导航栏中看见它,都不能证明它已打入包内。Apple 指定 iOS App 的清单位于 .app 包根目录,例如 Sample.app/PrivacyInfo.xcprivacy;iOS framework 的清单位于 framework 包根目录。macOS App 的目录结构不同,不能把它的路径规则套用到 iOS App。参见 Apple 添加 App 或 SDK 隐私清单的说明。
在 Xcode 中检查文件所属 Target 和 Build Phases 的资源输入;若使用 Swift Package,还要确认包明确声明了清单资源。Apple 特别说明,Swift Package 不会默认把隐私清单识别为资源,必须在包资源配置中声明。这个边界常导致“源码里有,产品包里没有”。
第二步:第三方 SDK 没有 PrivacyInfo.xcprivacy 时追踪依赖
通知中的组件路径不是可忽略的附注,而是区分责任归属的线索。沿路径查看归档内实际出现的 .framework、.xcframework 或其他依赖包,再与锁定文件、依赖解析记录及当前构建版本对应;只看项目声明的版本,可能漏掉实际被打包的旧二进制。
Apple 列出了需要包含隐私清单的第三方 SDK,并说明相关要求适用于名单中的 SDK 版本以及重新打包这些 SDK 的依赖。若通知定位到该类 SDK,向提供方索取带有效清单的更新版本,升级后重新解析依赖并归档;不要把 SDK 收集的数据、API 用途或追踪域名填写到 App 自己的清单中。清单描述的是各自组件的隐私实践,具体字段可对照 Apple 隐私清单文件说明。
格式无效和文件缺失是两种不同问题
缺失意味着预期位置没有对应清单;无效则意味着系统找到了文件,但它不是有效 plist,或其中的键值不符合规范。plutil -lint 能帮助判断 plist 是否格式正确,却不能单独证明内容符合 Apple 对各键和值的要求。
在 Mac 的终端对通知指向的文件执行:
plutil -lint "/path/to/PrivacyInfo.xcprivacy"
若输出 OK,继续检查清单中的键类型、必需字段和允许值;若报语法错误,先修复 XML 或 plist 结构,再重新执行校验。以 NSPrivacyTracking 为例,它的值必须是布尔值;NSPrivacyTrackingDomains 必须是字符串数组。必需原因 API 的类型和原因字段也有特定类型与允许值,不能凭猜测补入。相关声明规则见 Apple 对必需原因 API 的说明。
如果问题涉及追踪域名或数据收集声明,不要为了消除错误而随意添加域名或用途;应先核对实际行为,再按 Apple 文档规定的键、类型和值修正。格式校验通过只能证明文件可被解析,不能替代对清单内容是否真实、完整的审核。
第三步:在最终 Archive 中核对清单和依赖
源码改对了,不等于本次提交产物已经改对。旧依赖解析结果、Target 资源配置错误或归档输入未更新,都可能让 Archive 继续携带旧文件;因此,验收对象应是你准备上传的那份归档,而不是工作区中的文件。
先在 Xcode Organizer 找到本次 Archive,并用“显示包内容”查看 Products/Applications/你的 App.app。也可以在终端运行以下命令,列出归档中的清单:
find "/path/to/YourApp.xcarchive/Products/Applications" \
-name "PrivacyInfo.xcprivacy" -print
逐项对照通知路径:App 自身清单是否在 .app 根目录;被通知点名的 SDK 是否在对应 framework 或组件包内拥有自己的清单;文件是否为刚修复的版本。检查后,对归档里发现的清单再次运行 plutil -lint。对比构建产物时,至少保存 Archive 路径、依赖解析状态、命令输出和提交验证结果,方便团队复现和审计。
这也是源码与构建产物之间的关键差异:Xcode 项目中添加文件只是输入状态,归档中出现正确路径才是产物证据。Apple 对 App 与 framework 包结构的说明,可用于逐层核对清单位置。
第四步:重新验证上传,并把结果与审核状态分开记录
确认当前 Archive 的清单路径和内容正确后,再用 Xcode 或既有上传流程提交同一份归档。若上传验证仍指出相同路径,回头检查实际打包依赖与 Archive,而不是只重复修改源码;如果上传处理完成,也要查看是否还有警告。
App Store Connect 的上传状态用于说明构建上传和处理进度;“Complete”表示构建已处理并可用于测试,不等于 App Review 已批准。Apple 分别说明了构建上传状态和提交状态。因此,记录结果时分别写清“归档检查通过”“上传处理完成”和“审核结论”,不要把它们合并成一个“已通过”。
如果你需要在远程 Mac 或 CI 上复现,使用不含真实签名凭据的代表性项目,记录构建输入、Archive 路径和清单检查输出;不要把证书、密钥或 App Store Connect 凭据放进公开日志。远程环境适合验证完整的 Xcode 构建与归档链路,但它不会自动修复 SDK 供应方缺少清单的问题,也不能替代你对提交产物的检查。
如果你只偶尔需要 macOS 来复现归档问题,先判断是否值得为这次排查准备远程 Mac;若现有 Windows/Linux 流程无法完成 Xcode Archive,长期借用同事设备则会遇到环境不一致、依赖缓存不可控和复测难复现等问题。你可以先查看 VPSMAC 的 Mac 环境入口,或按 M4 远程 Mac 选项评估是否适合临时复现。若你已有稳定 Mac、需要物理连接设备,或持续承担固定高负载构建,购买或维护自己的机器可能更合适;租赁的价值在于按需获得可复现的 macOS 环境,而不是替你跳过依赖核对和 Archive 验收。