技术速递|为 .NET iOS 和 .NET MAUI 应用程序添加 Apple 隐私清单支持

时间:2024-04-16 07:23:30

作者:Gerald Versluis
排版:Alan Wang

Apple 正在推出一项隐私政策,将隐私清单文件包含在针对 App Store 上的 iOS、iPadOS 和 tvOS 平台的新应用程序和更新应用程序中。请注意,至少目前 macOS 应用程序被排除在外。

隐私清单文件(PrivacyInfo.xcprivacy)列出了 .NET MAUI 应用程序或任何第三方 SDK 和包收集的数据类型,以及使用某些必需原因 API 类别的原因。

截至撰写本文时,Apple 已发出有关将此政策纳入您的应用程序的通知。自 2024 年 5 月 1 日起,为了通过 App Store 审核,这将是强制性的。在这篇文章中,我们将了解您的 .NET MAUI、.NET for iOS 和 Xamarin 应用程序需要什么,才能保持合规性并能够继续发布应用程序的更新。

什么是 Apple 隐私清单?

几年前,Apple 开始向您收集有关您在 iOS 应用程序中收集的数据以及您如何使用这些数据的信息。然后,这些信息会在您的应用程序的 App Store 列表中显示给最终用户。下面是一个例子。
在这里插入图片描述
虽然这是向用户透明和保护他们的隐私迈出的一大步,但作为应用程序开发人员,您可能并不总是清楚您实际收集的数据。您知道您在应用程序中收集的数据是什么以及如何处理这些数据,但您很可能正在使用第三方库,这些库可能会进行自行处理。例如,通过使用 .NET MAUI 构建应用程序,您已经在使用可能需要在隐私报告中进行记录的某些 API 的框架。

为了进一步丰富隐私报告数据,Apple 推出了 Apple 隐私清单。此清单是另一个基于 XML 的元数据文件,应包含在您的应用程序中,而且库开发人员现在也应在需要时将其包含在其库中。

通过这种方式,Apple 可以将框架、库和应用程序中的所有不同的 PrivacyInfo.xcprivacy 文件级联为一份非常完整的隐私报告,然后将其显示在应用程序的 App Store 列表中。

隐私清单和 .NET

这对于基于 .NET 的 iOS 应用程序意味着什么?您的 .NET MAUI 和 .NET for iOS 应用程序中还需要包含隐私清单。幸运的是,这里不需要额外的支持,就像 .NET for iOS 和 .NET MAUI 应用程序一样。您可以使用现有的工具和 SDK 完成所需的一切。

PrivacyInfo.xcprivacy 文件是 XML 格式的元数据文件,很像您可能已经知道的 Info.plist。该文件应填写适用于您的应用程序的隐私条目。当前需要在隐私清单中添加条目的 API 列表可以在 .NET for iOS 存储库中找到,以及有关何时在清单中添加哪个条目以及如何添加的详细说明。

.NET 应用程序的最小隐私清单

根据您使用的 SDK,三层可能会使用任何必需的原因 API

  • .NET 运行时和基类库 (BCL)
  • 适用于 iOS SDK 的 .NET
  • .NET MAUI SDK

作为上述 SDK 的一部分,我们确定了这些 SDK 中使用的三个类别,需要在隐私清单中添加条目:

  • 文件时间戳 API
  • 系统启动时间 API
  • 磁盘空间 API

因此,所有 .NET 应用程序都必须在隐私清单文件中包含上述类别。以下是当您构建基于 .NET 的 iOS 应用程序时 PrivacyInfo.xcprivacy 文件的内容。

需要澄清的是,所有使用 .NET 构建并在 iOS 上运行的应用程序都至少需要以下清单。最重要的是,您应该识别在自己的代码中使用的 API 以及来自第三方库和框架的条目。

注意:以下内容仅针对 .NET MAUI 版本 8.0.0 及更高版本进行验证。

<?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>NSPrivacyAccessedAPICategoryFileTimestamp</string>
            <key>NSPrivacyAccessedAPITypeReasons</key>
            <array>
                <string>C617.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>E174.1</string>
            </array>
        </dict>
        <!--
            The entry below is only needed when you're using the Preferences API in your app.
        <dict>
            <key>NSPrivacyAccessedAPIType</key>
            <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
            <key>NSPrivacyAccessedAPITypeReasons</key>
            <array>
                <string>CA92.1</string>
            </array>
        </dict> -->
    </array>
</dict>
</plist>

特别是对于 .NET MAUI,可能需要取消对最后一个条目的注释。仅当您使用 Preferences API 时,才需要 CA92.1 的条目。否则你不需要它的原因是因为编译器将修剪所有未使用的 API,包括 Preferences 使用的 API,除非你在代码中引用它们。

若要将此文件添加到您的 .NET for iOS 项目中,请复制上述内容并将其粘贴到名为 PrivacyInfo.xcprivacy 的文件中,并将其放置在 Resources 文件夹下。这就是将文件打包到 iOS 应用程序的根目录中所需的全部内容。

对于 .NET MAUI 应用程序,将上述内容复制粘贴到名为 PrivacyInfo.xcprivacy 的文件中,并将其放置在 Platforms/iOS 文件夹下。然后使用您喜欢的文本编辑器编辑 .NET MAUI 项目 csproj 文件,并将以下部分添加到 节点下的某处。

<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
    <BundleResource Include="Platforms\iOS\PrivacyInfo.xcprivacy" LogicalName="PrivacyInfo.xcprivacy" />
</ItemGroup>

这将确保清单文件位于捆绑包的根目录中。

有关隐私清单以及您的应用可能需要哪些条目的更多信息,请参阅 Microsoft Learn 文档

Xamarin.iOS 和 Xamarin.Forms 的隐私清单

上述所有内容也适用于 Xamarin.iOS 和 Xamarin.Forms 应用程序。就像适用于 iOS 的 .NET 和 .NET MAUI 应用程序一样,幸运的是,这里不需要额外的支持,所需的一切都可以使用今天提供的工具和 SDK 来完成。

您可以创建一个 PrivacyInfo.xcprivacy 文件并将其包含在您的项目中,该文件应满足 App Store 要求。确保创建一个完整的隐私清单文件,其中包含描述您的应用程序并将其添加到您的项目所需的所有条目。

请确保对于 Xamarin.iOS 项目和 Xamarin.Forms 项目,文件都标记为捆绑资源(将Build Action设置为 BundleResource),这将正确地添加到生成的二进制文件中。对于 Xamarin.Forms,只需在 iOS 项目中添加清单文件。

有关应用程序可能需要哪些条目以及如何将 PrivacyInfo.xcprivacy 文件添加到 Xamarin 项目的更多说明,可以在 .NET for iOS 存储库中找到。还有适用于 .NET MAUI 的 Microsoft Learn 文档,就隐私清单的外观而言,该文档仍然适用于 Xamarin。

Mac Catalyst 和 macOS 应用程序

目前,包括 Mac Catalyst 在内的 macOS应用程序似乎不需要解释所需原因 API 的隐私清单条目。但是,如果您的应用程序或您在应用程序内部使用的任何 SDK 正在收集个人数据,则仍然需要清单文件和相关条目。有关所需条目的更多信息,请参阅 Apple 文档

将 PrivacyInfo.xcprivacy 文件添加到项目中的过程与上述相同,但是您应该将该文件放置在 macOS 应用程序包中的 Contents/Resources/ 子文件夹下,而不是像 iOS 那样放置在根目录下。

第三方库

请注意,最终,作为应用程序开发人员,您有责任为您的应用程序提供正确的隐私清单,无论您使用什么库或框架。如果您不断收到来自 App Store 审核系统的警告,请确保您已添加涵盖您的应用程序代码的所有必要条目。

当您确定警告不是由应用程序中的代码触发时,请务必检查您可能正在使用的第三方库和框架,确保它们在需要时也包含清单文件。

对于开源项目,您可以轻松检查代码以查看是否使用了需要清单中条目的任何 API。请参阅 Microsoft Learn 以获取需要在隐私清单中输入的 API 列表。

如果项目作者无法为其产品提供清单文件,您可以通过在您自己的 PrivacyInfo.xcprivacy 文件中添加已识别的所需条目来解决此问题。确保您了解 API 的用途及其用途,以便您可以在需要时自信地将此信息传达给用户。

您是库作者吗?

也许您自己就是库维护者,在这种情况下,本博客文章和链接文档中描述的所有内容也适用于您的项目。

截至撰写本文时,我们仍在研究如何才能最好地帮助您(以及您的用户)满足 Apple 的这些新要求。目前我们的建议是检查您的代码库,识别需要在隐私清单中输入条目的代码,并将该信息提供给您的用户,以便他们可以将其添加到他们的应用程序清单中。您可能需要包含一些关于为什么需要这些条目的解释。

如果您维护绑定库,您将需要考虑更新本机库。很可能其中已包含隐私清单文件。但是,绑定该新版本的库不会自动在最终用户应用程序中包含所需的清单文件。请暂时仍将此信息传递给用户,以便他们可以手动添加。

验证添加清单

为了验证隐私清单是否已正确添加,请将包含清单的应用程序提交到 App Store 进行审核。Apple 系统将对提供的二进制文件进行大量自动检查。如果出现问题,他们会向您注册 Apple 开发者帐户的电子邮件地址发送一封电子邮件。

如果您没有收到任何电子邮件,或者电子邮件没有具体说明有关隐私清单的任何内容,您可以放心地假设它已正确添加。

总结

请参阅我们对 Apple 隐私清单的详细描述,并确保您了解您的应用程序所需内容。归根结底,您有责任告知用户您如何处理他们的数据,并以正确的方式向 Apple 提供这些信息。

为了确保您的应用程序发布不受影响,请现在开始将其添加到您的应用程序中。在 2024 年 5 月 1 日截止日期之前做好准备,您将确保在此之后可以继续发布您的应用程序。

请记住,作为开发人员,您始终有责任确保隐私清单是正确的、最新的并包含在您的应用程序中。在撰写本文时(2024 年 3 月),我们已经确定了需要在清单中添加条目的所有 API,但这些 API 可能会随着时间的推移而发生变化。请务必检查 Apple 文档以了解最新要求。

如果您有任何疑问,请在 .NET for iOS 存储库上查看此问题,以查找其他开发人员的经验以及我们工程团队对问题的解答。