iOS 隐私清单文件 PrivacyInfo

2,708 阅读9分钟

 隐私清单文件 

描述应用或三方SDK对用户数据的收集使用情况,需要说明原因API的使用情况。

  • 数据的收集使用,您需要为您的应用程序或第三方SDK在所有平台上提供这些信息。
  • 需要说明原因API的使用,您需要为您的应用程序或第三方SDK在iOS、iPadOS、tvOS、visionOS和watchOS平台上提供这些信息。

您需要在 PrivacyInfo 文件中,将上面的数据信息列出并说明情况。

如果您的SDK在下列清单中,则需要在您的SDK中包含 PrivacyInfo 文件,以便开发者了解SDK在用户信息收集使用和需要说明原因API的使用情况。SDK列表在页尾

对三方SDK的新要求

三方SDK虽然可以为应用提供强大的功能,但如果三方SDK不向开发者和用户公开数据的收集和使用情况,将会严重影响到用户的隐私安全。每一个开发者都有责任去了解SDK的数据收集和使用情况。WWDC23大会,针对SDK引入了新的隐私清单文件和签名机制,以帮助开发者和用户更好的掌握三方SDK的数据收集和使用情况。对于所有应用来说,这个功能是一个进步,我们鼓励所有的SDK采用它来更好地支持依赖它们的应用程序。 下面是对SDK新的隐私和签名要求:

  • 隐私清单文件

    PrivacyInfo文件以标准格式列出了应用程序中第三方SDK中的用户数据使用情况。当你准备发布你的应用程序时,Xcode将把你应用程序使用的所有第三方SDK的PrivacyInfo文件合并成一个。生成一份综合的报告来了解应用中所有三方SDK的数据及权限使用情况,要比一条条地了解更快捷。

  • SDK的签名

    现在有了对SDK的签名要求,当你在应用中采用第三方SDK的新版本时,Xcode将验证它的签名是否是同一个开发者,从而提高了软件供应链的完整性。

如何创建隐私清单文件

  1. 打开Xcode,选择 File > New File
  2. 下滑到 Resource 部分,选择 App Privacy
  3. 点击 Next
  4. 在 Targets 列表中,选择你的应用或SDK的 Target
  5. 点击 Create

文件默认名称为 PrivacyInfo.xcprivacy;

需要将PrivacyInfo文件添加到Target的resources中,以便在Xcode生成隐私报告时使用它; 如果将SDK作为静态库发布,请使用Xcode 15或更高版本中来打包资源,并包含PrivacyInfo文件; 在Xcode中创建一个framework Target,将它的Mach-O构建类型设置为Static Library,并将PrivacyInfo文件与其他资源(例如图像文件)一起添加到Target的resources中。

PrivacyInfo内容的填写

PrivacyInfo文件的顶层,包含 Privacy Tracking EnabledPrivacy Tracking DomainsPrivacy Accessed API TypesPrivacy Nutrition Label Types 四项,填写规则如下:

  • Privacy Tracking Enabled

    一个布尔值,用来标记你的应用或三方SDK中是否有通过App Tracking Transparency framework(ATT)框架使用数据进行追踪。了解更多

    如果有进行追踪,值设置为YES,然后创建PrivacyTrackingDomains项;

    如果没有追踪行为,值设置为NO;

  • NSPrivacyTrackingDomains

    一个字符串数组,记录你的应用或三方SDK进行追踪的域名。

    此项数据与上面Privacy Tracking Enabled的值相关联

    如果应用里有进行追踪的域名,则需要将进行追踪的域名一一添加,并且将Privacy Tracking Enabled设置为YES;

    如果应用里没有进行追踪,此项不填,并且将Privacy Tracking Enabled设置为NO。

    如果用户没有授予App Tracking Transparency framework(ATT)框架的跟踪权限,对这些域名的网络请求将失败,你的应用程序将收到一个error。

  • Privacy Accessed API Types

    一个字典数组,描述你的应用程序或SDK所用到的系统访问权限。

    数组中可以添加多个Item,每个Item中包含 Privacy Accessed API TypePrivacy Accessed API Reasons 两项,根据实际情况选择列表中的值。不要自己填写!

    • PrivacyAccessedAPIType

    • PrivacyAccessedAPIReasons

    File timestamp 访问文件时间戳
    DDA9.1以向使用设备的人显示文件时间戳,访问的信息或任何派生信息没有发送到设备外。
    C617.1以访问App容器、App群组容器或App的CloudKit容器内文件的时间戳、大小或其他元数据。
    3B52.1以访问经过用户授权的文件的时间戳、大小或其他元数据,例如文档选择器控制器。
    0A2A.1此原因仅限SDK声明,保证SDK使用这个API只是为了通过封装的函数向外层应用提供服务,自己不能使用。
    System boot time 访问系统更新时间
    35F9.1为了计算本App中两次事件的时间差,或者是为了让timers使用,这些数据仅在本设备中使用
    8FFB.1为了计算本App中所有事件的绝对时间,UIKit或者AVFAudio相关功能
    3D61.1为了使用户选择提交的bug报告中包含系统启动时间信息,必须在报告中显眼的展示系统更新时间,访问的数据和派生数据,除了在用户选择提交后才能发送到设备外,并且只能用作对BUG报告的调查或回复用途。
    Disk space 访问磁盘空间
    85F4.1为了向用户展示剩余磁盘空间(例如剩余多少字节),或者计算HD视频的单位时间,数据仅限在设备内使用;经过用户的授权,通过网络向本人的其他设备发送本设备的磁盘数据,仅可用来展示。
    E174.1为了在向磁盘写入文件的时候检查磁盘空间是否充足,或者在磁盘空间不足的时候进行文件删除,所有这些操作必须用户可见;除了在设备空间不足的情况下避免下载文件的情况外,所有信息只能在设备内使用。
    7D9E.1为了在用户确定提交BUG报告的情况下,把磁盘信息归入报告,只能用作对BUG报告的调查或回复用途。
    B728.1如果你的App是设备健康研究类的App,为了查明和通知研究参与者,关于磁盘空间不足对研究数据收集的影响;你的App必须遵守 App Store Review Guideline §5.1.3.条款,在研究参与者同意后在进行数据的收集。
    Active keyboard 键盘状态
    3EC4.1如果你的App是一个自定义键盘App,是为了确定设备上键盘的激活;提供一个全系统的自定义键盘必须是这个App的主要功能,数据仅限设备内使用。
    54BD.1为了向用户展示和调整自定义界面正确的,去访问键盘的状态;必须包含text fields来编辑或确认文本内容,必须以明显告知用户的方式进行操作。
    User defaults 用户偏好设置
    CA92.1访问用户偏好设置只是为了方便App自己,读取或写入一些信息。
    1C8F.1访问用户偏好设置是为了方便App、APP扩展、应用剪辑或同一个组的其他应用,读取或写入一些信息。
    C56D.1此项为SDK需要声明的原因,为了向App提供用户偏好设置的读写功能,并且不能主动操作用户偏好设置。
    AC6B.1为了读取com.apple.configuration.managed 中的字段来检索MDM设置的托管应用配置,或者设置com.apple.feedback.managed 的字段来存储要通过MDM查询的反馈信息,详情参阅Apple Mobile Device Management Protocol Reference documentation。

    如果你上传到pp Store Connect的应用程序使用了这些系统API,但没有在PrivacyInfo文件中进行描述,苹果会向你发送一封电子邮件,提醒你将其添加到PrivacyInfo文件中。从2024年5月1日开始,如果应用使用了这些API,但在PrivacyInfo文件中没有进行描述,App Store Connect将不再接受新的构建版本。了解更多

  • Privacy Nutrition Label Types

    一个字典数组,描述你的应用程序或SDK所收集的用户信息类型、原因和使用情况。

    image.png

    数组中可以添加多个Item,每个item中包含Collected Data Type(数据类型)、Linked to User(是否关联用户)、Used for Tracking(是否用于追踪)、Collection Purposes(收集目的,可添加多个目的),根据实际情况添加Item和选择列表中对应类型和原因的值。不要自己填写!

    • Collected Data Type

    image.png

    • Collection Purposes

    image.png

    Collection Purposes收集目的
    Analytics数据分析
    App FunctionalityApp功能
    Developer's Advertising or Marketing开发者广告或营销
    Third-Party Advertising第三方广告
    Product Personalization产品的个性化
    Other Purposes其他目的

    提示:Privacy Nutrition Label Types 只需描述自己应用的收集情况,不需要覆盖三方SDK中收集行为。了解更多

    Xcode 以 Source Code 方式打开 PrivacyInfo.xcprivacy 文件,将下面内容替换即可:

    
    <?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>NSPrivacyAccessedAPITypes</key>
            <array>
                    <dict>
                            <key>NSPrivacyAccessedAPIType</key>
                            <string>NSPrivacyAccessedAPICategoryActiveKeyboards</string>
                            <key>NSPrivacyAccessedAPITypeReasons</key>
                            <array>
                                    <string>54BD.1</string>
                            </array>
                    </dict>
                    <dict>
                            <key>NSPrivacyAccessedAPIType</key>
                            <string>NSPrivacyAccessedAPICategorySystemBootTime</string>
                            <key>NSPrivacyAccessedAPITypeReasons</key>
                            <array>
                                    <string>35F9.1</string>
                            </array>
                    </dict>
                    <dict>
                            <key>NSPrivacyAccessedAPIType</key>
                            <string>NSPrivacyAccessedAPICategoryDiskSpace</string>
                            <key>NSPrivacyAccessedAPITypeReasons</key>
                            <array>
                                    <string>7D9E.1</string>
                                    <string>85F4.1</string>
                            </array>
                    </dict>
                    <dict>
                            <key>NSPrivacyAccessedAPIType</key>
                            <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
                            <key>NSPrivacyAccessedAPITypeReasons</key>
                            <array>
                                    <string>3B52.1</string>
                            </array>
                    </dict>
                    <dict>
                            <key>NSPrivacyAccessedAPIType</key>
                            <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
                            <key>NSPrivacyAccessedAPITypeReasons</key>
                            <array>
                                    <string>CA92.1</string>
                            </array>
                    </dict>
            </array>
            <key>NSPrivacyCollectedDataTypes</key>
            <array>
                    <dict>
                            <key>NSPrivacyCollectedDataType</key>
                            <string>NSPrivacyCollectedDataTypeContacts</string>
                            <key>NSPrivacyCollectedDataTypeLinked</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypeTracking</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypePurposes</key>
                            <array>
                                    <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
                            </array>
                    </dict>
                    <dict>
                            <key>NSPrivacyCollectedDataType</key>
                            <string>NSPrivacyCollectedDataTypeCreditInfo</string>
                            <key>NSPrivacyCollectedDataTypeLinked</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypeTracking</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypePurposes</key>
                            <array>
                                    <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
                            </array>
                    </dict>
                    <dict>
                            <key>NSPrivacyCollectedDataType</key>
                            <string>NSPrivacyCollectedDataTypeCrashData</string>
                            <key>NSPrivacyCollectedDataTypeLinked</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypeTracking</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypePurposes</key>
                            <array>
                                    <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
                            </array>
                    </dict>
                    <dict>
                            <key>NSPrivacyCollectedDataType</key>
                            <string>NSPrivacyCollectedDataTypeDeviceID</string>
                            <key>NSPrivacyCollectedDataTypeLinked</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypeTracking</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypePurposes</key>
                            <array>
                                    <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
                            </array>
                    </dict>
                    <dict>
                            <key>NSPrivacyCollectedDataType</key>
                            <string>NSPrivacyCollectedDataTypeEmailAddress</string>
                            <key>NSPrivacyCollectedDataTypeLinked</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypeTracking</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypePurposes</key>
                            <array>
                                    <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
                            </array>
                    </dict>
                    <dict>
                            <key>NSPrivacyCollectedDataType</key>
                            <string>NSPrivacyCollectedDataTypeName</string>
                            <key>NSPrivacyCollectedDataTypeLinked</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypeTracking</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypePurposes</key>
                            <array>
                                    <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
                            </array>
                    </dict>
                    <dict>
                            <key>NSPrivacyCollectedDataType</key>
                            <string>NSPrivacyCollectedDataTypePhotosorVideos</string>
                            <key>NSPrivacyCollectedDataTypeLinked</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypeTracking</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypePurposes</key>
                            <array>
                                    <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
                            </array>
                    </dict>
                    <dict>
                            <key>NSPrivacyCollectedDataType</key>
                            <string>NSPrivacyCollectedDataTypeOtherFinancialInfo</string>
                            <key>NSPrivacyCollectedDataTypeLinked</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypeTracking</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypePurposes</key>
                            <array>
                                    <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
                            </array>
                    </dict>
                    <dict>
                            <key>NSPrivacyCollectedDataType</key>
                            <string>NSPrivacyCollectedDataTypeUserID</string>
                            <key>NSPrivacyCollectedDataTypeLinked</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypeTracking</key>
                            <false/>
                            <key>NSPrivacyCollectedDataTypePurposes</key>
                            <array>
                                    <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
                            </array>
                    </dict>
            </array>
            <key>NSPrivacyTracking</key>
            <false/>
            <key>NSPrivacyTrackingDomains</key>
            <array/>
    </dict>
    </plist>
    
    

    生成隐私报告

    Xcode可以通过聚合你的应用及其链接的第三方SDK中的PrivacyInfo文件来创建隐私报告。通过隐私报告可以更好地了解您的应用程序收集的所有数据以及它是否对用户进行追踪。通过以下操作为您的应用程序创建隐私报告:

    1. 在Xcode中打开你的应用.
    2. 选择 Product > Archive,Xcode创建归档并将其显示在 Organizer 中。
    3. 点击 Organizer > 右击对应的 Archive > 选择 Generate Privacy Report 选项,生成报告.
    4. 选择文件保存的位置.
    5. 在Finder中双击进行查看.

    隐私报告的配置方式与Privacy Nutrition Labels类似。当您在app Store Connect中提供您的应用程序的隐私详细信息时,请参阅此报告。了解更多配置信息