Skip to content

Latest commit

 

History

History
237 lines (149 loc) · 12.9 KB

README.zh-CN.md

File metadata and controls

237 lines (149 loc) · 12.9 KB

App Privacy Manifest Fixer

Latest Version License

English | 简体中文

本工具是一个基于 Shell 脚本的自动化解决方案,旨在分析和修复 iOS App 的隐私清单,确保 App 符合 App Store 的要求。它利用 App Store Privacy Manifest Analyzer 对 App 及其依赖项进行 API 使用分析,并生成或修复PrivacyInfo.xcprivacy文件。

✨ 功能特点

  • 非侵入式集成:无需修改源码或调整项目结构。
  • 极速安装与卸载:一行命令即可快速完成工具的安装或卸载。
  • 自动分析与修复:项目构建时自动分析 API 使用情况并修复隐私清单问题。
  • 灵活定制模板:支持自定义 App 和 Framework 的隐私清单模板,满足多种使用场景。
  • 隐私访问报告:自动生成报告用于查看 App 和 SDK 的NSPrivacyAccessedAPITypes声明情况。
  • 版本轻松升级:提供升级脚本快速更新至最新版本。

📥 安装

下载工具

  1. 下载最新发布版本
  2. 解压下载的文件:
    • 解压后的目录通常为app_privacy_manifest_fixer-xxx(其中xxx是版本号)。
    • 建议重命名为app_privacy_manifest_fixer,或在后续路径中使用完整目录名。
    • 建议将该目录移动至 iOS 项目中,以避免因路径问题在不同设备上运行时出现错误,同时便于为每个项目单独自定义隐私清单模板

⚡ 自动安装(推荐)

  1. 切换到工具所在目录

    cd /path/to/app_privacy_manifest_fixer
  2. 运行以下安装脚本

    sh install.sh <project_path>
    • 如果是 Flutter 项目,project_path应为 Flutter 项目中的ios目录路径。
    • 重复运行安装命令时,工具会先移除现有安装(如果有)。若需修改命令行选项,只需重新运行安装命令,无需先卸载。

手动安装

如果不使用安装脚本,可以手动添加Fix Privacy Manifest任务到 Xcode 的 Build Phases 完成安装。安装步骤如下:

1. 在 Xcode 中添加脚本

  • 用 Xcode 打开你的 iOS 项目,进入 TARGETS 选项卡,选择你的 App 目标。

  • 进入 Build Phases,点击 + 按钮,选择 New Run Script Phase

  • 将新建的 Run Script 重命名为Fix Privacy Manifest

  • Shell 脚本框中添加以下代码:

    # 使用相对路径(推荐):如果`app_privacy_manifest_fixer`在项目目录内
    "$PROJECT_DIR/path/to/app_privacy_manifest_fixer/fixer.sh"
    
    # 使用绝对路径:如果`app_privacy_manifest_fixer`不在项目目录内
    # "/absolute/path/to/app_privacy_manifest_fixer/fixer.sh"

    请根据实际情况修改path/toabsolute/path/to,并确保路径正确。同时,删除或注释掉不适用的行

2. 调整脚本执行顺序

将该脚本移动到所有其他 Build Phases 之后,确保隐私清单在所有资源拷贝和编译任务完成后再进行修复

Build Phases 截图

下面是自动/手动安装成功后的 Xcode Build Phases 配置截图(未启用任何命令行选项):

Build Phases Screenshot

🚀 快速开始

安装后,工具将在每次构建项目时自动运行,构建完成后得到的 App 包已经是修复后的结果。

如果启用--install-builds-only命令行选项安装,工具将仅在安装构建时运行。

Xcode Build Log 截图

下面是项目构建时工具输出的日志截图(默认会存储到app_privacy_manifest_fixer/Build目录,除非启用-s命令行选项):

Xcode Build Log Screenshot

📖 使用方法

命令行选项

  • 强制覆盖现有隐私清单(不推荐)

    sh install.sh <project_path> -f

    启用-f选项后,工具会根据 API 使用分析结果和隐私清单模板生成新的隐私清单,并强制覆盖现有隐私清单。默认情况下(未启用-f),工具仅修复缺失的隐私清单。

  • 静默模式

    sh install.sh <project_path> -s

    启用-s选项后,工具将禁用修复时的输出,不再复制构建生成的*.app、自动生成隐私访问报告或输出修复日志。默认情况下(未启用-s),这些输出存储在app_privacy_manifest_fixer/Build目录。

  • 仅在安装构建时运行(推荐)

    sh install.sh <project_path> --install-builds-only

    启用--install-builds-only选项后,工具仅在执行安装构建(如 Archive 操作)时运行,以优化日常开发时的构建性能。如果你是手动安装的,该命令行选项无效,需要手动勾选 For install builds only 选项。

    注意:如果 iOS 项目在开发环境构建(生成的 App 包含*.debug.dylib文件),工具的 API 使用分析结果可能不准确。

升级工具

要更新至最新版本,请运行以下命令:

sh upgrade.sh

卸载工具

使用以下命令快速卸载工具:

sh uninstall.sh <project_path>

🔥 隐私清单模板

隐私清单模板存储在Templates目录,其中根目录已经包含默认模板。

如何为 App 或 SDK 自定义隐私清单?只需使用自定义模板

模板类型

模板分为以下几类:

  • AppTemplate.xcprivacy:App 的隐私清单模板。
  • FrameworkTemplate.xcprivacy:通用的 Framework 隐私清单模板。
  • FrameworkName.xcprivacy:特定的 Framework 隐私清单模板,仅在Templates/UserTemplates目录有效。

模板优先级

对于 App,隐私清单模板的优先级如下:

  • Templates/UserTemplates/AppTemplate.xcprivacy > Templates/AppTemplate.xcprivacy

对于特定的 Framework,隐私清单模板的优先级如下:

  • Templates/UserTemplates/FrameworkName.xcprivacy > Templates/UserTemplates/FrameworkTemplate.xcprivacy > Templates/FrameworkTemplate.xcprivacy

默认模板

默认模板位于Templates根目录,目前包括以下模板:

  • Templates/AppTemplate.xcprivacy
  • Templates/FrameworkTemplate.xcprivacy

这些模板将根据 API 使用分析结果进行修改,特别是NSPrivacyAccessedAPIType条目将被调整,以生成新的隐私清单用于修复,确保符合 App Store 要求。

如果需要调整隐私清单模板,例如以下场景,请避免直接修改默认模板,而是使用自定义模板。如果存在相同名称的自定义模板,它将优先于默认模板用于修复。

  • 由于 API 使用分析结果不准确,生成了不合规的隐私清单。
  • 需要修改模板中声明的理由。
  • 需要声明收集的数据。

AppTemplate.xcprivacy中隐私访问 API 类别及其对应声明的理由如下:

NSPrivacyAccessedAPIType NSPrivacyAccessedAPITypeReasons
NSPrivacyAccessedAPICategoryFileTimestamp C617.1: Inside app or group container
NSPrivacyAccessedAPICategorySystemBootTime 35F9.1: Measure time on-device
NSPrivacyAccessedAPICategoryDiskSpace E174.1: Write or delete file on-device
NSPrivacyAccessedAPICategoryActiveKeyboards 54BD.1: Customize UI on-device
NSPrivacyAccessedAPICategoryUserDefaults CA92.1: Access info from same app

FrameworkTemplate.xcprivacy中隐私访问 API 类别及其对应声明的理由如下:

NSPrivacyAccessedAPIType NSPrivacyAccessedAPITypeReasons
NSPrivacyAccessedAPICategoryFileTimestamp 0A2A.1: 3rd-party SDK wrapper on-device
NSPrivacyAccessedAPICategorySystemBootTime 35F9.1: Measure time on-device
NSPrivacyAccessedAPICategoryDiskSpace E174.1: Write or delete file on-device
NSPrivacyAccessedAPICategoryActiveKeyboards 54BD.1: Customize UI on-device
NSPrivacyAccessedAPICategoryUserDefaults C56D.1: 3rd-party SDK wrapper on-device

自定义模板

要创建自定义模板,请将其放在Templates/UserTemplates目录,结构如下:

  • Templates/UserTemplates/AppTemplate.xcprivacy
  • Templates/UserTemplates/FrameworkTemplate.xcprivacy
  • Templates/UserTemplates/FrameworkName.xcprivacy

在这些模板中,只有FrameworkTemplate.xcprivacy会根据 API 使用分析结果对NSPrivacyAccessedAPIType条目进行调整,以生成新的隐私清单用于 Framework 修复。其他模板保持不变,将直接用于修复。

重要说明:

  • 特定的 Framework 模板必须遵循命名规范FrameworkName.xcprivacy,其中FrameworkName需与 Framework 的名称匹配。例如Flutter.framework的模板应命名为Flutter.xcprivacy
  • SDK 的名称可能与 Framework 的名称不完全一致。要确定正确的 Framework 名称,请在构建项目后检查 App 包中的Frameworks目录。

📑 隐私访问报告

默认情况下,工具会自动在每次构建时为原始 App 和修复后的 App 生成隐私访问报告,并存储到app_privacy_manifest_fixer/Build目录。

如果需要手动为特定 App 生成隐私访问报告,请运行以下命令:

sh Report/report.sh <app_path> <report_output_path>
# <app_path>: App路径(例如:/path/to/App.app)
# <report_output_path>: 报告文件保存路径(例如:/path/to/report.html)

注意:工具生成的报告目前仅包含隐私访问部分(NSPrivacyAccessedAPITypes),如果想看数据收集部分(NSPrivacyCollectedDataTypes)请使用 Xcode 生成PrivacyReport

报告示例截图

原始 App 报告(report-original.html) 修复后 App 报告(report.html)
Original App Report Fixed App Report

💡 重要考量

  • 如果最新版本的 SDK 支持隐私清单,请尽可能升级,以避免不必要的风险。
  • 此工具仅为临时解决方案,不应替代正确的 SDK 管理实践。
  • 在提交 App 审核之前,请检查隐私清单修复后是否符合最新的 App Store 要求。

🙌 贡献

欢迎任何形式的贡献,包括代码优化、Bug 修复、文档改进等。请确保遵循项目规范,并保持代码风格一致。感谢你的支持!