CocoaPods隐私清单实现Skill cocoapods-privacy-manifests

该技能用于为CocoaPods库实现iOS 17+隐私清单,确保App Store合规性和用户透明度。涵盖PrivacyInfo.xcprivacy文件创建、必要原因API声明和资源包集成。关键词:CocoaPods、隐私清单、iOS 17、App Store、合规、API声明、资源包。

移动开发 0 次安装 0 次浏览 更新于 3/25/2026

名称: cocoapods-privacy-manifests 用户可调用: false 描述: 用于为CocoaPods库实现iOS 17+隐私清单。涵盖PrivacyInfo.xcprivacy文件创建、必要原因API声明以及适当的资源包集成以确保App Store合规性。 允许工具:

  • 读取
  • 写入
  • 编辑
  • Bash
  • Grep
  • Glob

CocoaPods - 隐私清单

为App Store合规性和用户透明度实现iOS 17+隐私清单。

什么是隐私清单?

隐私清单(PrivacyInfo.xcprivacy)是XML属性列表文件,声明:

  • 数据收集和使用实践
  • 必要原因API使用
  • 跟踪域名
  • 隐私敏感API

为什么需要隐私清单?

从iOS 17和Xcode 15开始,Apple要求隐私清单用于:

  • 使用隐私敏感API的应用程序
  • 第三方SDK和框架
  • 任何访问用户数据的代码

隐私清单文件格式

基本结构

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSPrivacyTracking</key>
    <false/>
    <key>NSPrivacyTrackingDomains</key>
    <array/>
    <key>NSPrivacyCollectedDataTypes</key>
    <array/>
    <key>NSPrivacyAccessedAPITypes</key>
    <array/>
</dict>
</plist>

在Podspec中包含

资源包(推荐)

Pod::Spec.new do |spec|
  spec.name = 'MyLibrary'
  spec.version = '1.0.0'

  spec.source_files = 'Source/**/*.swift'

  # 在资源包中包含隐私清单
  spec.resource_bundles = {
    'MyLibrary' => [
      'Resources/**/*.xcprivacy',
      'Resources/**/*.{png,jpg,xcassets}'
    ]
  }
end

直接资源(替代)

spec.resources = 'Resources/PrivacyInfo.xcprivacy'

# 或使用glob模式
spec.resources = 'Resources/**/*.xcprivacy'

文件位置

MyLibrary/
├── MyLibrary.podspec
├── Source/
│   └── MyLibrary/
└── Resources/
    ├── PrivacyInfo.xcprivacy  # 隐私清单
    └── Assets.xcassets

必要原因API

常见需要原因的API

Apple要求为这些隐私敏感API声明原因:

文件时间戳API

<key>NSPrivacyAccessedAPITypes</key>
<array>
    <dict>
        <key>NSPrivacyAccessedAPIType</key>
        <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
        <key>NSPrivacyAccessedAPITypeReasons</key>
        <array>
            <string>C617.1</string>
        </array>
    </dict>
</array>

原因代码:

  • C617.1: 向用户显示时间戳
  • 0A2A.1: 访问应用容器中文件的时间戳
  • 3B52.1: 为应用功能访问时间戳
  • DDA9.1: 为调试访问时间戳

用户默认值API

<dict>
    <key>NSPrivacyAccessedAPIType</key>
    <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
    <key>NSPrivacyAccessedAPITypeReasons</key>
    <array>
        <string>CA92.1</string>
    </array>
</dict>

原因代码:

  • CA92.1: 在同一应用组中访问用户默认值
  • 1C8F.1: 为应用功能访问用户默认值
  • C56D.1: SDK特定配置偏好
  • AC6B.1: 第三方SDK功能

系统启动时间API

<dict>
    <key>NSPrivacyAccessedAPIType</key>
    <string>NSPrivacyAccessedAPICategorySystemBootTime</string>
    <key>NSPrivacyAccessedAPITypeReasons</key>
    <array>
        <string>35F9.1</string>
    </array>
</dict>

原因代码:

  • 35F9.1: 为应用功能测量经过时间
  • 8FFB.1: 计算绝对时间戳
  • 3D61.1: 为性能测试测量时间

磁盘空间API

<dict>
    <key>NSPrivacyAccessedAPIType</key>
    <string>NSPrivacyAccessedAPICategoryDiskSpace</string>
    <key>NSPrivacyAccessedAPITypeReasons</key>
    <array>
        <string>85F4.1</string>
    </array>
</dict>

原因代码:

  • 85F4.1: 向用户显示磁盘空间
  • E174.1: 在文件操作前检查磁盘空间
  • 7D9E.1: 健康/健身应用磁盘空间
  • B728.1: 用户发起的文件管理

数据收集

声明收集的数据

<key>NSPrivacyCollectedDataTypes</key>
<array>
    <dict>
        <key>NSPrivacyCollectedDataType</key>
        <string>NSPrivacyCollectedDataTypeEmailAddress</string>
        <key>NSPrivacyCollectedDataTypeLinked</key>
        <true/>
        <key>NSPrivacyCollectedDataTypeTracking</key>
        <false/>
        <key>NSPrivacyCollectedDataTypePurposes</key>
        <array>
            <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
        </array>
    </dict>
</array>

常见数据类型

  • NSPrivacyCollectedDataTypeEmailAddress
  • NSPrivacyCollectedDataTypeName
  • NSPrivacyCollectedDataTypePhoneNumber
  • NSPrivacyCollectedDataTypeDeviceID
  • NSPrivacyCollectedDataTypeUserID
  • NSPrivacyCollectedDataTypePreciseLocation
  • NSPrivacyCollectedDataTypeCoarseLocation
  • NSPrivacyCollectedDataTypeSearchHistory
  • NSPrivacyCollectedDataTypeBrowsingHistory

收集目的

  • NSPrivacyCollectedDataTypePurposeThirdPartyAdvertising
  • NSPrivacyCollectedDataTypePurposeAppFunctionality
  • NSPrivacyCollectedDataTypePurposeAnalytics
  • NSPrivacyCollectedDataTypePurposeProductPersonalization
  • NSPrivacyCollectedDataTypePurposeOther

跟踪配置

无跟踪

<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyTrackingDomains</key>
<array/>

有跟踪

<key>NSPrivacyTracking</key>
<true/>
<key>NSPrivacyTrackingDomains</key>
<array>
    <string>analytics.example.com</string>
    <string>tracking.example.com</string>
</array>

完整示例

网络SDK隐私清单

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <!-- 无跟踪 -->
    <key>NSPrivacyTracking</key>
    <false/>
    <key>NSPrivacyTrackingDomains</key>
    <array/>

    <!-- 数据收集 -->
    <key>NSPrivacyCollectedDataTypes</key>
    <array>
        <dict>
            <key>NSPrivacyCollectedDataType</key>
            <string>NSPrivacyCollectedDataTypeUserID</string>
            <key>NSPrivacyCollectedDataTypeLinked</key>
            <true/>
            <key>NSPrivacyCollectedDataTypeTracking</key>
            <false/>
            <key>NSPrivacyCollectedDataTypePurposes</key>
            <array>
                <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
            </array>
        </dict>
    </array>

    <!-- 必要原因API -->
    <key>NSPrivacyAccessedAPITypes</key>
    <array>
        <!-- 用户默认值用于缓存 -->
        <dict>
            <key>NSPrivacyAccessedAPIType</key>
            <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
            <key>NSPrivacyAccessedAPITypeReasons</key>
            <array>
                <string>CA92.1</string>
            </array>
        </dict>

        <!-- 文件时间戳用于缓存验证 -->
        <dict>
            <key>NSPrivacyAccessedAPIType</key>
            <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
            <key>NSPrivacyAccessedAPITypeReasons</key>
            <array>
                <string>3B52.1</string>
            </array>
        </dict>
    </array>
</dict>
</plist>

分析SDK隐私清单

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <!-- 跟踪启用 -->
    <key>NSPrivacyTracking</key>
    <true/>
    <key>NSPrivacyTrackingDomains</key>
    <array>
        <string>analytics.myservice.com</string>
    </array>

    <!-- 数据收集 -->
    <key>NSPrivacyCollectedDataTypes</key>
    <array>
        <dict>
            <key>NSPrivacyCollectedDataType</key>
            <string>NSPrivacyCollectedDataTypeDeviceID</string>
            <key>NSPrivacyCollectedDataTypeLinked</key>
            <true/>
            <key>NSPrivacyCollectedDataTypeTracking</key>
            <true/>
            <key>NSPrivacyCollectedDataTypePurposes</key>
            <array>
                <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
            </array>
        </dict>
    </array>

    <!-- 必要原因API -->
    <key>NSPrivacyAccessedAPITypes</key>
    <array>
        <dict>
            <key>NSPrivacyAccessedAPIType</key>
            <string>NSPrivacyAccessedAPICategorySystemBootTime</string>
            <key>NSPrivacyAccessedAPITypeReasons</key>
            <array>
                <string>35F9.1</string>
            </array>
        </dict>
    </array>
</dict>
</plist>

CocoaPods集成

Podspec配置

Pod::Spec.new do |spec|
  spec.name = 'MyAnalyticsSDK'
  spec.version = '1.0.0'

  spec.ios.deployment_target = '13.0'

  spec.source_files = 'Source/**/*.swift'

  # 包含隐私清单
  spec.resource_bundles = {
    'MyAnalyticsSDK' => [
      'Resources/PrivacyInfo.xcprivacy'
    ]
  }

  # 平台特定隐私清单
  spec.ios.resource_bundles = {
    'MyAnalyticsSDK_iOS' => ['Resources/iOS/PrivacyInfo.xcprivacy']
  }

  spec.osx.resource_bundles = {
    'MyAnalyticsSDK_macOS' => ['Resources/macOS/PrivacyInfo.xcprivacy']
  }
end

验证

检查隐私清单

# 使用隐私清单进行lint
pod lib lint

# 验证隐私清单是否包含
pod lib lint --verbose | grep -i privacy

Xcode验证

  1. 在Xcode中构建您的库
  2. 打开报告导航器
  3. 检查隐私警告
  4. 验证捆绑包中的隐私清单

App Store验证

# 生成.xcarchive
xcodebuild archive -workspace MyApp.xcworkspace -scheme MyApp

# 提交前验证
xcodebuild -exportArchive -archivePath MyApp.xcarchive -exportPath MyApp.ipa -exportOptionsPlist ExportOptions.plist

最佳实践

最小披露

<!-- 只声明实际使用的内容 -->
<key>NSPrivacyCollectedDataTypes</key>
<array>
    <!-- 只有实际收集此数据时才包含 -->
</array>

准确原因

<!-- 使用正确的原因代码 -->
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
    <string>CA92.1</string>  <!-- 必须匹配实际使用 -->
</array>

定期更新

# 当添加新API时更新隐私清单
spec.version = '1.1.0'  # 增加版本

# 使用新声明更新PrivacyInfo.xcprivacy

反模式

不要

❌ 为iOS 17+应用程序省略隐私清单

# 缺少隐私清单 - App Store拒绝风险
spec.resource_bundles = {
  'MyLibrary' => ['Resources/**/*.png']
  # 没有PrivacyInfo.xcprivacy
}

❌ 使用不正确的原因代码

<string>WRONG.1</string>  <!-- 无效代码 -->

❌ 声明跟踪但没有域名

<key>NSPrivacyTracking</key>
<true/>
<key>NSPrivacyTrackingDomains</key>
<array/>  <!-- 空 - 不一致 -->

✅ 为所有iOS SDK包含隐私清单

spec.resource_bundles = {
  'MyLibrary' => ['Resources/PrivacyInfo.xcprivacy']
}

✅ 使用准确的原因代码

<string>CA92.1</string>  <!-- 有效,匹配使用 -->

✅ 真实关于跟踪

<key>NSPrivacyTracking</key>
<true/>
<key>NSPrivacyTrackingDomains</key>
<array>
    <string>analytics.example.com</string>
</array>

资源

相关技能

  • cocoapods-podspec-fundamentals
  • cocoapods-subspecs-organization
  • cocoapods-publishing-workflow