xamarin-macios/docs/apple-privacy-manifest.md

19 KiB
Исходник Ответственный История

Apples privacy manifest policy requirements

Apple is introducing new privacy policies that affect .NET applications targeting macOS, Mac Catalyst, iOS, iPadOS, and tvOS platforms on the App Stores. The policies affect how app developers are expected to disclose how they use any data collected from a users device and why certain APIs are being used. Developers will provide the details for these in a privacy manifest file that is included in the application bundle.

The data collection policies require you to declare the types of data that you collect and describe the data in a privacy manifest files. Apart from how to properly include the privacy manifest files in your .NET project, this document does not go into any detail on the data collection settings. The Apple documentation should be sufficient for declaring how your App or framework uses data it collects from users.

The Required Reason APIs policy forces app developers to identify certain categories of APIs that their app, or frameworks use and to provide a reason for their use. This information is provided in a privacy manifest files along with the data collection information. This document will provide .NET application developers the information needed to provide a PrivacyInfo.xcprivacy file with thier .NET applications with the proper policy settings to pass the Required Reason APIs checks when submitting to the Apple App Stores.

The privacy manifest file (PrivacyInfo.xcprivacy) lists the types of data your .NET MAUI application, or any third-party SDKs and packages collect, and the reasons for using certain Required Reason APIs categories.

Important: If the use of the Required Reason APIs by you or third-party SDKs isnt declared in the privacy manifest, your application might be rejected by the App Store. For more information, visit Apples documentation on Required Reasons APIs.

Prepare your .NET MAUI applications for Apples privacy manifest policy

You must review your native code, C# code, and data collection and tracking practices to understand if Apples privacy manifest policy applies to you. Follow these guidelines to decide if you need to include a privacy manifest file in your product:

  • If your application includes any third-party SDKs or packages, then these third-party components (if applicable) must provision their own privacy manifest files separately. Note: Its your responsibility however, to make sure that the owners of these third-party components include privacy manifest files. Microsoft isnt responsible for any third-party privacy manifest, and their data collection and tracking practices.

  • If your application includes the .NET APIs that call certain native APIs listed in the Apples Required Reason API categories, then you must assess your product for the API usage. For assessing what constitutes as part of data collection and tracking practices, refer to Apples documentation on privacy manifest files. Note: Its your responsibility to assess your use of each of these APIs and declare the applicable reasons for using them.

Depending on whether youre using .NET for iOS or .NET MAUI to develop an application or providing ObjectiveC or Swift Binding packages to use with .NET MAUI applications, the requirement for providing a privacy manifest file might differ.

Note: The above guidelines are provided for your convenience. Its important that you review Apples documentation on privacy manifest files before creating a privacy manifest for your project.

Important: The following information is provided based on Apple's documentation as of March 2024. It is recommended that you review Apples documentation on privacy manifest files when creating a privacy manifest for your project to ensure you are using the most recent guidelines. If you find any discrepancies in the information below, please file a bug and include the API in question.

Privacy manifest for .NET MAUI and .NET for iOS or tvOS applications

If youre developing an application using .NET MAUI, consider the following steps:

  1. Assess if your native application code uses any of the following APIs:

  2. If you meet one or both of the conditions from step 1, or if you have disabled linking, which will retain all of the C# .NET APIs, then create a privacy manifest file following the example to add a PrivacyInfo.xcprivacy file to your project.

  3. In the privacy manifest file, declare the approved reasons for using the Required Reasons APIs or C# .NET APIs, as applicable.

Important: If you dont declare the reasons for the use of APIs, your application might be rejected by the App Store.

Verify if your native application code collects any type of data categorized by Apple and declare those data types in the privacy manifest file as applicable. Any third-party SDKs or packages used in your application must include their own separate manifest files to declare data collection and the use of any Required Reasons APIs with approved reasons.

Notes:

  • Its your responsibility to check the accuracy of the privacy manifest within the .NET MAUI app and if any third-party components included in your .NET MAUI project require any declarations in you privacy manifest. Its recommended that you search these third-party components for any references to a privacy manifest declaration.

  • If youre developing an application using .NET MAUI as a library, check if your native application code collects any of the following information outside of the .NET MAUI project:

    If it does, then you must declare their usage in the privacy manifest file.

Privacy manifest for Binding projects

Binding projects fall into two categories, static framework bindings, or dynamic framework bindings. Privacy manifests should be included with the framework by placing the privacy manifest in the framework bundle. If placed properly, then the binding project can automatically place them in the app bundle properly so app developers do not need to provide reasons for the framework api usages.

For a dynamic framework, the framework is added to the app bundle. The privacy policy manifest is in the location that the App Store expects it to be, and there is nothing for the app developer to do.

At this time, when binding a static framework, app developers will be required to manually merge the privacy manifest included with the static framework into the app privacy manifest. This is due to how static libraries are linked into the main app binary removing the need for the framework.

C# .NET APIs in .NET MAUI

.NET for iOS, tvOS and .NET MAUI build on top of the .NET runtime and BCL. Each SDK's API usages are detailed in the links below.

  • .NET Runtime and BCL API usages
  • .NET for iOS, tvOS and Xamarin.iOS API Usages
  • .NET MAUI and Xamarin.Forms API Usages

All .NET Apps that target devices running iOS, iPadOS, or tvOS will require a PrivacyInfo.xcprivacy file in the app bundle. This is due to the .NET Runtime and BCL using Required Reasons APIs that are not removed regardless of the linking setting. The following three API categories and their associated reasons must be in the PrivacyInfo.xcprivacy.

  • NSPrivacyAccessedAPICategoryFileTimestamp - C617.1
  • NSPrivacyAccessedAPICategorySystemBootTime - 35F9.1
  • NSPrivacyAccessedAPICategoryDiskSpace - E174.1

Additionally, if you use the NSUserDefaults APIs in your app, you will need to add the NSPrivacyAccessedAPICategoryUserDefaults API category, with a reason code of CA92.1.

See the example below for detailed instructions on how to add a PrivacyInfo.xcprivacy file to your App.

Example

Let's look at how you would add a Privacy Manifest file to an application that uses the following APIs:

How they are used is not that important for this example, but the why will determine the reason code needed for the privacy manifest.

Adding the PrivacyInfo.xcprivacy file to your project

The PrivacyInfo.xcprivacy is consider a resource when it is time to build the bundle. In accordance with Placing Content in a Bundle the file is placed in the root of the Bundle. Use the proper set of instructions below for your project type:

.NET MAUI

  1. Create a new blank file named PrivacyInfo.xcprivacy in the Platforms/iOS folder in your .NET MAUI project.
  2. In your favorite text editor, edit the .NET MAUI csproj project file.
  3. Add the following elements to the bottom of the root <Project> element:
    <ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
      <BundleResource Include="Platforms\iOS\PrivacyInfo.xcprivacy" LogicalName="PrivacyInfo.xcprivacy" />
    </ItemGroup>
    
    This will package the file into the iOS app at the root of the bundle.

.NET for iOS (net?-ios)

  1. Create a new blank file named PrivacyInfo.xcprivacy in the Resources folder in your .NET for iOS project. This is all that is needed to package the file into the iOS app at the root of the bundle.

.NET for tvOS (net?-tvos)

  1. Create a new blank file named PrivacyInfo.xcprivacy in the root folder in your .NET for tvOS project.
  2. In your favorite text editor, edit the .NET for tvOS csproj project file.
  3. Add the following elements to the bottom of the root <Project> element:
    <ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tvos'">
      <BundleResource Include="PrivacyInfo.xcprivacy" LogicalName="PrivacyInfo.xcprivacy" />
    </ItemGroup>
    
    This will package the file into the tvOS app at the root of the bundle.

Xamarin.iOS including Xamarin.Forms

  1. Create a new blank file named PrivacyInfo.xcprivacy in the root folder of your Xamarin.iOS project.
  2. In your favorite text editor, edit the Xamarin.iOS csproj project file.
  3. Locate the <ItemGroup> that contains other <BundleResource> elements and add the following element:
    <BundleResource Include="PrivacyInfo.xcprivacy" LogicalName="PrivacyInfo.xcprivacy" />
    
    This will package the file into the iOS app at the root of the bundle.

Now that the file has been created in the proper location your project, it needs to be ppopulated with the correct settings for your app or framework.

Creating the PrivacyInfo.xcprivacy file

We will start by building the contents of the PrivacyInfo.xcprivacy file, and then go through each supported platform and how to properly configure your project so the file is included in the bundle properly.

Since the application is based on .NET, a privacy manifest is required. Let's walkthrough the steps needed to add a privacy manifest that declares our usages of the above three API's.

  1. Open Xcode and either create new App project, or open an existing one.
  2. In Xcode use the File->New->File menu to open the Choose a new template for your file: dialog box.
  3. Scroll down until you find the App Privacy template.
  4. Select the App Privacy template and then click Next
  5. In the Save As dialog, leave the filename as PrivacyInfo as that is the required name for the file.
  6. Click Create and close Xcode.
  7. Use Finder to copy the PrivacyInfo.xcprivacy file from the Xcode project to your documents folder for now.
  8. The Xcode project is no longer needed and can be deleted.

You should now have a file named PrivacyInfo.xcprivacy under your documents folder with contents similar to:

<?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">
<!--
... omitted for brevity
-->
<plist version="1.0">
<dict/>
</plist>

Use your favorite text editor, like Visual Studio Code, to open the file for editing.

You can add the entries for the APIs usage to the PrivacyInfo.xcproject as follows:

  1. Edit the PrivacyInfo.xcprivacy file to appear as follows:

    <?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">
    <!--
    ... omitted for brevity
    -->
    <plist version="1.0">
    <dict>
        <key>NSPrivacyAccessedAPITypes</key>
        <array>
        </array>
    </dict>
    </plist>
    

    This adds the NSPrivacyAccessAPITypes key where each category usage will be added.

  2. Since the .NET runtime and BCL include APIs from the File timestamp, System boot time, Disk space API categories, add the following to the NSPrivacyAccessedAPITypes 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>
    
  3. For the NSProcessInfo.SystemUptime, a reason code of 35F9.1 is needed since that is the only reason code available. But since the .NET runtime and BCL already included that category and reason, there is nothing additional to add.

  4. For the NSFileManager.ModificationDate, a reason code of C617.1 is needed since the modification dates are stored as a hash using NSUserDefaults but not displayed to the user. Again, the .NET runtime and BCL requirements have already satisfied this category and reason so no additional changes are needed.

  5. For the NSUserDefaults, a reason code of CA92.1 is provided since the data accessed is only accessible to the app itself. Add the following element to the NSPrivacyAccessedAPITypes array:

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

The complete PrivacyInfo.xcprivacy should now look similar to:

<!-- 
    ... comments and headers omitted for brevity 
-->
<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>
        <dict>
            <key>NSPrivacyAccessedAPIType</key>
            <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
            <key>NSPrivacyAccessedAPITypeReasons</key>
            <array>
                <string>CA92.1</string>
            </array>
        </dict>
    </array>
</dict>
</plist>

Once added to your project, the PrivacyInfo.xcprivacy file will need to be updated if there are any additional API usages from additional categories or additional reasons for usage. This will include adding a NuGet package or Binding project that calls into any of Apples Required Reason APIs. It is ultimately your responsibility to provide an accurate PrivacyInfo.xcprivacy file, failing to do so may result in the App Store rejecting your submission.