iOS - 超好用的隐私清单修复脚本(持续更新)
文章目录
- 前言
- 开发环境
- 项目地址
- 下载安装
- 隐私访问报告
- 隐私清单模板
- 最后
前言
在早些时候,提交应用到App Store审核,大家应该都收到过类似这样的邮件:
Although submission for App Store review was successful, you may want to correct the following issues in your next submission for App Store review. Once you've corrected the issues, upload a new binary to App Store Connect.ITMS-91053: Missing API declaration - Your app’s code in the “Runner” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategoryDiskSpace. While no action is required at this time, starting May 1, 2024, when you upload a new app or app update, you must include a NSPrivacyAccessedAPITypes array in your app’s privacy manifest to provide approved reasons for these APIs used by your app’s code. For more details about this policy, including a list of required reason APIs and approved reasons for usage, visit: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api.ITMS-91053: Missing API declaration - Your app’s code in the “Runner” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategoryFileTimestamp. While no action is required at this time, starting May 1, 2024, when you upload a new app or app update, you must include a NSPrivacyAccessedAPITypes array in your app’s privacy manifest to provide approved reasons for these APIs used by your app’s code. For more details about this policy, including a list of required reason APIs and approved reasons for usage, visit: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api.ITMS-91053: Missing API declaration - Your app’s code in the “Runner” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategorySystemBootTime. While no action is required at this time, starting May 1, 2024, when you upload a new app or app update, you must include a NSPrivacyAccessedAPITypes array in your app’s privacy manifest to provide approved reasons for these APIs used by your app’s code. For more details about this policy, including a list of required reason APIs and approved reasons for usage, visit: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api.ITMS-91053: Missing API declaration - Your app’s code in the “Runner” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategoryUserDefaults. While no action is required at this time, starting May 1, 2024, when you upload a new app or app update, you must include a NSPrivacyAccessedAPITypes array in your app’s privacy manifest to provide approved reasons for these APIs used by your app’s code. For more details about this policy, including a list of required reason APIs and approved reasons for usage, visit: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api.
因为这个问题,分别写了两篇文章,其中一篇介绍审核新政策,另一篇介绍隐私清单分析脚本:
- iOS问题记录 - App Store审核新政策:隐私清单 & SDK签名(持续更新)
- iOS - 超好用的隐私清单分析脚本(持续更新)
当时还有点担心一些SDK到期(2024/05/01)还没适配咋搞,特别是我还维护着一些老项目,实在是一点也不想升级那些SDK增加额外工作量。那时候就想,要不写个快速修复隐私清单的脚本?
结果时间到了,苹果也没贯彻执行审核新政策,该提交的提交,甚至我手头有个老项目连应用的隐私清单都没有也能正常提交。我不经在想,难道苹果也知道这东西不好执行放弃了?写了个大概的隐私清单修复脚本就此封存。
时间来到10月底,有人在隐私清单分析脚本文章中评论了一个问题,同时也有人收到新的警告邮件:
ITMS-91061: Missing privacy manifest - Your app includes “Frameworks/MBProgressHUD.framework/MBProgressHUD”, which includes MBProgressHUD, an SDK that was identified in the documentation as a privacy-impacting third-party SDK. Starting November 12, 2024, if a new app includes a privacy-impacting SDK, or an app update adds a new privacy-impacting SDK, the SDK must include a privacy manifest file. Please contact the provider of the SDK that includes this file to get an updated SDK version with a privacy manifest. For more details about this policy, including a list of SDKs that are required to include signatures and manifests, visit: https://developer.apple.com/support/third-party-SDK-requirements.
我就好奇苹果是不是又开始执行审核新政策,于是找到官方文档瞅了一眼:

这是机翻:
包含无效隐私清单文件的应用程序提交可能会被拒绝。如果您将应用程序上传到App Store Connect,其中包含具有意外键或值的隐私清单文件,您将收到一封电子邮件,其中包含应用程序包中无效文件的名称和路径。从2024年11月12日开始,不包含所需隐私清单的应用程序无法在App Store Connect中提交审核。您需要获取该电子邮件中提到的所有隐私清单文件的有效版本并将其包含在您的应用程序中。如果无效文件来自第三方SDK,请联系其开发人员以获取包含有效隐私清单的SDK更新版本。使用Xcode再次构建、存档并提交您的应用程序。有关更多信息,请参阅分发应用程序以进行Beta测试和发布。
截止时间变为了2024/11/12,同时还强调隐私清单不能包含意外键或值。什么意思呢?当时我猜测是不能把全部所需原因API都在隐私清单声明一遍,必须用了才能声明,不然就是无效的隐私清单。现在不用猜,因为当我写下这篇文章的时候,苹果又更新了文档:

从2025年2月12日开始,提交审核的应用,其中一部分常用第三方SDK必须包含有效的隐私清单文件(个人理解,仅供参考)。从文档看,苹果是打算逐步推进。阅读TN3181: Debugging an invalid privacy manifest文档可以知道关于无效隐私清单的一些信息。
提交的应用包含无效的隐私清单会收到如下警告邮件:
ITMS-91056: Invalid privacy manifest - The PrivacyInfo.xcprivacy file from the following path
is invalid: "PrivacyInfo.xcprivacy". Keys and values in your app's privacy manifests must be
valid. For more details about privacy manifest files, visit:
https://developer.apple.com/documentation/bundleresources/privacy_manifest_files.
如此看来这些错误代码分别对应不同的隐私清单问题:
ITMS-91053:API声明缺失ITMS-91056:隐私清单无效ITMS-91061:隐私清单缺失
关于常用SDK支持隐私清单的最低版本,可以在这里查看。
无效的隐私清单分为两种(更详细内容请看官方文档):
- 包含无效键或值:类型不对(例如不是字符串/字典数组)、空字符串或和预期值不匹配(例如声明的原因不属于这个API类别)等
- 格式不正确:指plist文件的内容格式不正确,用Xcode编辑通常不会出现该问题
补充一点:据观察可用于声明的原因会随着Xcode版本变化,之前Xcode版本声明的原因假如后面的版本移除了它,不知道会不会被视作无效隐私清单。
至于说全部声明一遍会不会导致隐私清单无效,文档并没有明确说明,不过在结尾提了一句:如果您的隐私清单的键和值与App Store Connect期望的值不匹配,您的隐私清单仍然可能无效。

综合以上内容,审核新政策还在不断推进,并没有马上一刀切。考虑到迟早会全面推进,我把封存的隐私清单修复脚本项目进行了完善,支持对隐私清单进行修复以及生成隐私访问报告,推荐用于无法升级的SDK或者想保持现状的项目。
开发环境
- macOS: 15.2
项目地址
- GitHub
下载安装
首先下载最新版本,然后解压。建议解压到iOS项目根目录,一是方便为每个项目单独自定义隐私清单模板,二是避免运行在不同设备出现路径问题。
然后解压后执行安装命令:
sh install.sh <project_path>
建议使用--install-builds-only选项,这样修复工具通常只会运行在打包(Archive)时的项目构建,日常开发不运行可以加速项目构建:
sh install.sh <project_path> --install-builds-only
安装完成后在项目构建时会自动运行,更多用法请看:Installation Guide。
隐私访问报告
当未启用静默模式(默认不启用)时,会在Build目录下输出每次运行生成的隐私访问报告。
从报告中可以快速看到哪些SDK缺隐私清单、SDK声明了哪些API类型及SDK修复用的是哪个隐私清单模板。后续考虑生成完整的隐私报告以及在报告中呈现隐私清单问题(检测是否无效隐私清单)。
| 应用修复前的报告 | 应用修复后的报告 |
|---|---|
![]() | ![]() |
当然,你也可以手动执行命令给某个应用生成报告:
sh Report/report.sh <app_path> <report_output_path>
# <app_path>: Path to the app (e.g., /path/to/App.app)
# <report_output_path>: Path to save the report file (e.g., /path/to/report.html)
隐私清单模板
隐私清单模板放在Templates目录,自定义模板放在Templates/UserTemplates目录。
如果不存在应用隐私清单,将按照如下优先级获取隐私清单模板用于修复:
Templates/UserTemplates/AppTemplate.xcprivacy > Templates/AppTemplate.xcprivacy
如果某个SDK不存在隐私清单,将按照如下优先级获取隐私清单模板用于修复:
Templates/UserTemplates/FrameworkName.xcprivacy > Templates/UserTemplates/FrameworkTemplate.xcprivacy > Templates/FrameworkTemplate.xcprivacy
FrameworkName一般就是SDK的名称,但是也有不相同的情况。如果不清楚,可以检查构建后的应用程序包或者隐私访问报告找出SDK对应的framework。当然,如果SDK的API使用分析足够准确,通过自带的默认模板FrameworkTemplate.xcprivacy修复就可以了,无需自定义。
隐私清单模板更多介绍请看:Privacy Manifest Templates。
最后
如果这篇文章对你有所帮助,点赞👍收藏🌟支持一下吧,谢谢~
本篇文章由@crasowas发布于CSDN。
相关文章:
iOS - 超好用的隐私清单修复脚本(持续更新)
文章目录 前言开发环境项目地址下载安装隐私访问报告隐私清单模板最后 前言 在早些时候,提交应用到App Store审核,大家应该都收到过类似这样的邮件: Although submission for App Store review was successful, you may want to correct th…...
html <a>设置发送邮件链接、打电话链接 <a href=“mailto:></a> <a href=“tel:></a>
1.代码 <ul><li>电话:<a href"tel:18888888888">188-8888-8888</a></li><li>邮箱:<a href"mailto:10000qq.com">10000qq.com</a></li><li>邮箱:<a hre…...
clickhouse-副本和分片
1、副本 1.1、概述 集群是副本和分片的基础,它将ClickHouse的服务拓扑由单节点延伸到多个节点,但它并不像Hadoop生态的某些系统那样,要求所有节点组成一个单一的大集群。ClickHouse的集群配置非常灵活,用户既可以将所有节点组成…...
2009 ~ 2019 年 408【计算机网络】大题解析
2009 年 路由算法(9’) 讲解视频推荐:【BOK408真题讲解-2009年(催更就退网版)】 某网络拓扑如下图所示,路由器 R1 通过接口 E1 、E2 分别连接局域网 1 、局域网 2 ,通过接口 L0 连接路由器 R2 &…...
vue2使用render,js中写html
1、js部分table.js export default {name: "dadeT",data() {return {dades: 6666};},render(h) {return h(div, [h(span, 组件数据:${this.dades}), // 利用data里的dades数据,展示在页面上h(span, 89855545)]);} };2、vue部分 <templat…...
如何有效划分服务器磁盘空间?具体的步骤和流程
有效划分服务器磁盘空间对于提升系统性能、管理方便性和数据安全性至关重要。合理的磁盘分区不仅有助于提高服务器的运行效率,还能在数据恢复、系统故障修复和存储管理方面提供更高的灵活性。以下是如何有效划分服务器磁盘空间的几个关键步骤和注意事项。 磁盘分区的…...
labelme标签批量转换数据集json_to_dataset
文章目录 labelme标签批量转换数据集json_to_dataset转换原理单张图片转换多张图片批量转换bat脚本循环法 标注图片提取标注图片转单通道 labelme标签批量转换数据集json_to_dataset 转自labelme批量制作数据集教程。 转换原理 在安装了labelme的虚拟环境中有一个labelme_js…...
Fisco-Bcos-java-SDK 利用java与fisco-Bcos区块链上的智能合约交互(以HelloWorld为例)
Fisco-Bcos-java-SDK 利用java与fisco-Bcos区块链上的智能合约交互(以HelloWorld为例) 一、部署智能合约 1、编写智能合约 此处用最简单的HelloWorld合约作为例子 包含两个方法和一个构造函数 构造函数:当合约部署的时候 执行构造函数 将…...
OpenHarmony-3.HDF Display子系统(6)
Display 子系统 1.Display驱动模型介绍 当前操作系统和 SOC 种类繁多,各厂商的显示屏器件也各有不同,随之针对器件的驱动代码也不尽相同,往往是某一款器件驱动,只适用于某单一内核系统或 SOC,如果要迁移到其他内核或者…...
Nginx中Server块配置的详细解析
Nginx中Server块配置的详细解析 一、Server块简介 在Nginx配置文件中,server块是非常关键的部分。它用于定义虚拟主机,一个server块就代表一个虚拟主机。这使得我们可以在一台Nginx服务器上通过不同的配置来处理多个域名或者基于不同端口的服务请求。 …...
php学习资料分享
php学习资料分享:夸克网盘分享...
EE308FZ_Sixth Assignment_Beta Sprint_Sprint Essay 3
Assignment 6Beta SprintCourseEE308FZ[A] — Software EngineeringClass Link2401_MU_SE_FZURequirementsTeamwork—Beta SprintTeam NameFZUGOObjectiveSprint Essay 3_Day5-Day6 (12.15-12.16)Other Reference1. WeChat Mini Program Design Guide 2. Javascript Style Guid…...
Eureka学习笔记-服务端
Eureka学习笔记 服务端 模块设计 Resources :这部分对外暴露了一系列的 Restful 接口。Eureka Client 的注册、心跳、获取服务列表等操作都需要调用这些接口。另外,其他的 Server 在同步 Registry 时也需要调用这些接口。Controller :这里提…...
无限次使用 cursor pro
github地址 cursor-vip 使用方式 在 MacOS/Linux 中,请打开终端; 在 Windows 中,请打开 Git Bash。 然后执行以下命令来安装: 部分电脑可能会误报毒,需要关闭杀毒软件/电脑管家/安全防护再进行 方式1:通过…...
网站运维之整站同步
网站运维之整站同步 1、使用rsync安装rsync工具子服务器生成密钥子服务器发送公钥到服务端(需要root允许ssh登录)服务端添加密钥子服务器尝试免密登录子服务器添加任务计划 2、开启root用户远程ssh3、ubuntu开启root用户 1、使用rsync 很多时候由于访问…...
【机器人】Graspness 端到端 抓取点估计 | 论文解读
在复杂场景中实现抓取检测,Graspness是一种端到端的方法; 输入点云数据,输出抓取角度、抓取深度、夹具宽度等信息。 开源地址:GitHub - rhett-chen/graspness_implementation: My implementation of Graspnet Graspness. 论文地…...
力扣2300.咒语和药水的成功对数(二分法)
根据 灵茶山艾府 题解所写 题目描述: 给你两个正整数数组 spells 和 potions ,长度分别为 n 和 m ,其中 spells[i] 表示第 i 个咒语的能量强度,potions[j] 表示第 j 瓶药水的能量强度。 同时给你一个整数 success 。一个咒语和药…...
WEB开发: 全栈工程师起步 - Python Flask +SQLite的管理系统实现
一、前言 罗马不是一天建成的。 每个全栈工程师都是从HELLO WORLD 起步的。 之前我们分别用NODE.JS 、ASP.NET Core 这两个框架实现过基于WebServer的全栈工程师入门教程。 今天我们用更简单的来实现: Python。 我们将用Python来实现一个学生管理应用࿰…...
云原生周刊:Kubernetes v1.32 正式发布
开源项目推荐 Helmper Helmper 简化了将 Helm Charts导入OCI(开放容器倡议)注册表的过程,并支持可选的漏洞修复功能。它确保您的 Helm Charts不仅安全存储,还能及时应用最新的安全修复。该工具完全兼容 OCI 标准,能够…...
京准电钟:电厂自控NTP时间同步服务器技术方案
京准电钟:电厂自控NTP时间同步服务器技术方案 京准电钟:电厂自控NTP时间同步服务器技术方案 随着计算机和网络通信技术的飞速发展,火电厂热工自动化系统数字化、网络化的时代已经到来。一方面它为控制和信息系统之间的数据交换、分析和应用…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...
Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...
更新 Docker 容器中的某一个文件
🔄 如何更新 Docker 容器中的某一个文件 以下是几种在 Docker 中更新单个文件的常用方法,适用于不同场景。 ✅ 方法一:使用 docker cp 拷贝文件到容器中(最简单) 🧰 命令格式: docker cp <…...
多模态大语言模型arxiv论文略读(112)
Assessing Modality Bias in Video Question Answering Benchmarks with Multimodal Large Language Models ➡️ 论文标题:Assessing Modality Bias in Video Question Answering Benchmarks with Multimodal Large Language Models ➡️ 论文作者:Jea…...
Spring AI中使用ChatMemory实现会话记忆功能
文章目录 1、需求2、ChatMemory中消息的存储位置3、实现步骤1、引入依赖2、配置Spring AI3、配置chatmemory4、java层传递conversaionId 4、验证5、完整代码6、参考文档 1、需求 我们知道大型语言模型 (LLM) 是无状态的,这就意味着他们不会保…...

