文章目录
前言
在早些时候,提交应用到App Store审核,大家应该都收到过类似这样的邮件:
text
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.
因为这个问题,分别写了两篇文章,其中一篇介绍审核新政策,另一篇介绍隐私清单分析脚本:
当时还有点担心一些SDK到期(2024/05/01)还没适配咋搞,特别是我还维护着一些老项目,实在是一点也不想升级那些SDK增加额外工作量。那时候就想,要不写个快速修复隐私清单的脚本?
结果时间到了,苹果也没贯彻执行审核新政策,该提交的提交,甚至我手头有个老项目连应用的隐私清单都没有也能正常提交。我不经在想,难道苹果也知道这东西不好执行放弃了?写了个大概的隐私清单修复脚本就此封存。
时间来到10月底,有人在隐私清单分析脚本文章中评论了一个问题,同时也有人收到新的警告邮件:
text
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.
我就好奇苹果是不是又开始执行审核新政策,于是找到官方文档瞅了一眼:
这是机翻:
text
包含无效隐私清单文件的应用程序提交可能会被拒绝。如果您将应用程序上传到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文档可以知道关于无效隐私清单的一些信息。
提交的应用包含无效的隐私清单会收到如下警告邮件:
text
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
项目地址
下载安装
首先下载最新版本,然后解压。建议解压到iOS项目根目录,一是方便为每个项目单独自定义隐私清单模板,二是避免运行在不同设备出现路径问题。
然后解压后执行安装命令:
shell
sh install.sh <project_path>
建议使用--install-builds-only
选项,这样修复工具通常只会运行在打包(Archive
)时的项目构建,日常开发不运行可以加速项目构建:
shell
sh install.sh <project_path> --install-builds-only
安装完成后在项目构建时会自动运行,更多用法请看:Installation Guide。
隐私访问报告
当未启用静默模式(默认不启用)时,会在Build
目录下输出每次运行生成的隐私访问报告。
从报告中可以快速看到哪些SDK缺隐私清单、SDK声明了哪些API类型及SDK修复用的是哪个隐私清单模板。后续考虑生成完整的隐私报告以及在报告中呈现隐私清单问题(检测是否无效隐私清单)。
应用修复前的报告 | 应用修复后的报告 |
---|---|
当然,你也可以手动执行命令给某个应用生成报告:
shell
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
目录。
如果不存在应用隐私清单,将按照如下优先级获取隐私清单模板用于修复:
text
Templates/UserTemplates/AppTemplate.xcprivacy > Templates/AppTemplate.xcprivacy
如果某个SDK不存在隐私清单,将按照如下优先级获取隐私清单模板用于修复:
text
Templates/UserTemplates/FrameworkName.xcprivacy > Templates/UserTemplates/FrameworkTemplate.xcprivacy > Templates/FrameworkTemplate.xcprivacy
FrameworkName
一般就是SDK的名称,但是也有不相同的情况。如果不清楚,可以检查构建后的应用程序包或者隐私访问报告找出SDK对应的framework。当然,如果SDK的API使用分析足够准确,通过自带的默认模板FrameworkTemplate.xcprivacy
修复就可以了,无需自定义。
隐私清单模板更多介绍请看:Privacy Manifest Templates。
最后
如果这篇文章对你有所帮助,点赞👍收藏🌟支持一下吧,谢谢~
本篇文章由@crasowas发布于CSDN。