Skip to content

Latest commit

 

History

History
259 lines (213 loc) · 17.4 KB

apple-privacy-manifest.md

File metadata and controls

259 lines (213 loc) · 17.4 KB

Apple’s privacy manifest policy requirements

Apple is introducing a privacy policy for including privacy manifest files in new and updated applications targeted for iOS, iPadOS, and tvOS platforms on the App Store.

The privacy manifest file (PrivacyInfo.xcprivacy) lists the types of data your .NET MAUI applications, 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 isn’t declared in the privacy manifest, your application might be rejected by the App Store. For more information, visit Apple’s documentation on Required Reasons APIs.

Prepare your .NET MAUI applications for Apple’s privacy manifest policy

You must review your native code, C# code, and data collection and tracking practices to understand if Apple’s 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: It’s your responsibility however, to make sure that the owners of these third-party components include privacy manifest files. Microsoft isn’t responsible for any third-party privacy manifest, and their data collection and tracking practices.

  • If your application includes the C# .NET APIs that call certain APIs listed in the Apple’s 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 Apple’s documentation on privacy manifest files. Note: It’s your responsibility to assess your use of each of these APIs and declare the applicable reasons for using them.

Depending on whether you’re 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. It’s important that you review Apple’s 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 Apple’s 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 you’re 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 don’t 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:

  • It’s 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. It’s recommended that you search these third-party components for any references to a privacy manifest declaration.

  • If you’re 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

If you are Binding project owner, and you are binding a xcframework, then the xcframework provider will need to include the PrivacyInfo.xcprivacy file as part of the xcframework. Otherwise, there are two options, provide documentation for package consumers to create the PrivacyInfo.xcprivacy file properly or change the bindings to bind an xcframework that has the PrivacyInfo.xcprivacy file included. It is currently not possible for Binding project authors to include a PrivacyInfo.xcprivacy file outside an xcframework that will be recognized by Apple when submitting an app.

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.

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 APIU categories and thier associated reasons must be in the `PrivacyInfo.xcprivacy'.

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

Additionally, if you use the NSUserDefaults API's in your app, you will need to add the NSPrivacyAccessedAPICategoryUserDefaults API category, with a reason code of CAS92.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 API's:

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

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 in 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 API's 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 API's 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>

Now that the file has been created, it needs to be placed properly when building the app.

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. Copy the PrivacyInfo.xcprivacy from your documents folder to 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. Copy the PrivacyInfo.xcprivacy from your documents folder to 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. Copy the PrivacyInfo.xcprivacy from your documents folder to the root folder of 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. Copy the PrivacyInfo.xcprivacy from your documents folder to 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.

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 Apple’s 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.