強火で進め

このブログではプログラム関連の記事を中心に書いてます。

UnityでのAppleのPrivacy Manifestへの対応方法

Privacy Manifestとは?

Privacy Manifestとは2024年春から導入される予定のAppleの新しいプライバシー対策のアップデートです。

App Storeへの提出におけるプライバシー要件のアップデート - 最新ニュース - Apple Developer

このアップデートにより、フィンガープリントに利用できる情報にアクセスをするAPI(※)を使用する場合にはPrivacy Manifestというファイルを作成し、そこでAPIを利用する理由を明示するというルールが導入されます。

Appleはフィンガープリントの使用を禁止しています。ユーザのトラッキングにはフィンガープリントでは無く、広告識別子(IDFA)を使う必要が有ります。

Xcodeのメニューから File > New > File… と選択し、Resourceセクションに有るApp Privacyを選択するとPrivacyInfo.xcprivacyというファイルで空のPrivacy Manifestファイルが作成されます。

Unityでの対応方法

Unityでは以下のバージョンからPrivacy Manifestに対応しています。その為、Unityでの対応方法としては該当のバージョンへのバージョンアップになります。 それ以前のバージョンを使ってプロジェクトを作成している場合にはバージョンアップが必要に有ります。

Privacy Manifest ファイルが生成される様になったバージョン

Release NoteにはAdded Apple Privacy Manifest support.と記載されています。

系統 バージョン
Unity 2021.x系 Unity 2021.3.35f1(2024/2/8リリース)
Unity 2022.x系 Unity 2022.3.18f1(2024/1/20リリース)
Unity 2023.x系 Unity 2023.2.7f1(2024/1/23リリース)

※このバージョンで生成されるPrivacy Manifestファイルには「System boot time APIs - 35F9.1」の記載が抜けています。こちらについてはUnity 2023.2.13、2022.3.21、および 2021.3.36で修正予定とアナウンスされています

「System boot time APIs - 35F9.1」の記載漏れが修正されているバージョン

Release NoteにはAdded missing privacy manifest entry for System Boot time API usage.と記載されています。

Unity 2023.2.13f1だけはFixed an issue by adding a missing privacy manifest entry for System Boot time API usage.と記載されています。

系統 バージョン
Unity 2021.x系 Unity 2021.3.36(2024/3/5リリース)
Unity 2022.x系 Unity 2022.3.21f1(2024/3/5リリース)
Unity 2023.x系 Unity 2023.2.13f1(2024/3/5リリース)

UnityにPrivacy Manifest向けの機能として追加される内容についてはこちらのページ(英語)を参照下さい。

重要な部分を引用しておきます。

[Available today] Unity Engine core Required Reason Privacy Manifest entries & related Documentation. See them here. This covers Unity Engine core’s internal usage of Required Reasons APIs.
[Available today] Documentation for C# methods that map to Required Reason APIs. If you use one of these, you will need to declare a Reason. See them here.
[Available today] Fixes to the Unity Engine core to comply with Required Reasons. We are updating the Engine to use fewer Required Reason APIs. This change is available in Unity 2021.3.34f1, 2022.3.16f1 and 2023.2.5f1 releases. This is an internal change, so it is not mentioned in the release notes. This change requires a Unity Editor update.
[Available soon] Solution to incorporate Privacy Manifests coming from Unity plugins, packages and your project. We expect this change to be available in Unity 2021.3.35f1, 2022.3.18f1 and 2023.2.7f1 releases. The release notes will state "Add Apple Privacy Manifest support". This change will require a Unity editor update.
[Work in progress] We will sign Unity Engine libraries within UnityFramework. We expect this change to be available in Unity 2021/2022/2023 forthcoming patch releases This change will require a Unity editor update.

(翻訳)

[本日公開】Unity Engineコア 必須理由 プライバシーマニフェストエントリ&関連ドキュメント。こちらをご覧ください。Unity Engine coreのRequired Reason APIの内部的な使用方法をカバーしています。
[本日公開】Required Reason APIに対応するC#メソッドのドキュメントです。これらのいずれかを使用する場合は、Reasonを宣言する必要があります。こちらを参照してください。
[本日公開】Required Reasonに対応するためのUnity Engineコアの修正。より少ないRequired Reason APIを使用するようにエンジンを更新しています。この変更はUnity 2021.3.34f1、2022.3.16f1、2023.2.5f1で利用可能です。これは内部的な変更であるため、リリースノートには記載されていません。この変更にはUnity Editorのアップデートが必要です。
[近日公開予定] Unityプラグイン、パッケージ、プロジェクトからのプライバシーマニフェストを取り込むためのソリューションです。この変更はUnity 2021.3.35f1、2022.3.18f1、2023.2.7f1リリースで利用可能になる予定です。リリースノートには「Add Apple Privacy Manifest support」と記載されます。この変更にはUnityエディタのアップデートが必要です。
[作業中] UnityFramework内のUnity Engineライブラリに署名します。この変更は、Unity 2021/2022/2023の今後のパッチリリースで利用可能になることを期待しています。

現時点ではここに記載されている様にUnityエディタでは「Privacy Manifestファイルについて扱える様になった」という部分まで対応済みで、署名の作業については作業中です。

Unity Engine コア ライブラリは署名する必要無くなった様です。

また、Unity公式ドキュメントのここに Privacy Manifest についての情報が追加されているので目を通しておいた方が良いでしょう。

Unity が生成する Privacy Manifest ファイルの内容を確認

UnityでXcodeプロジェクトを生成するとPrivacyInfo.xcprivacyが含まれたプロジェクトが作成されます。ファイルをXcode上で開くと以下の様に表示されます。

ファイルを直接開いた場合には以下の様になります。

<?xml version="1.0" encoding="utf-8"?>
<plist version="1.0">
  <dict>
    <key>NSPrivacyAccessedAPITypes</key>
    <array>
      <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>
      <dict>
        <key>NSPrivacyAccessedAPIType</key>
        <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
        <key>NSPrivacyAccessedAPITypeReasons</key>
        <array>
          <string>0A2A.1</string>
          <string>C617.1</string>
        </array>
      </dict>
    </array>
    <key>NSPrivacyCollectedDataTypes</key>
    <array />
  </dict>
</plist>

ここで使われているパラメータの説明は以下のAppleの公式ドキュメントで確認できます。

Privacy manifest files | Apple Developer Documentation

※ドキュメントはトップページだけでは無く、Describing data use in privacy manifestsDescribing use of required reason APIも確認しましょう。

主な部分について確認してみましょう。以下の部分に注目してみます。

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

この部分ではdictの中にkeyとして、NSPrivacyAccessedAPITypevalueとしてstring(文字列)で「APIのカテゴリ」を記述するルールになっています。ここではNSPrivacyAccessedAPICategoryDiskSpaceが設定されています。Appleの公式ドキュメントで確認するとこれは「Disk space APIs」と記載されており、「使用可能なディスク容量にアクセスするAPI」のカテゴリだと確認できます。

次にkeyとして、NSPrivacyAccessedAPITypeReasonsが有ります。このkeyに対応するvalueとしては「アプリが API を使用する理由を示す文字列」を配列(array)の中にstring(文字列)で記述します。ここではE174.1が記述されています。E174.1の説明文は「ファイルを書き込むのに十分なストレージの空き容量が有るか確認する為」と書かれています。

話をまとめると使用するAPIについて「カテゴリ」と「そのAPIを使用する理由」を記述する必要が有り、解説した部分では以下の内容を記述しています。

  • カテゴリ :Disk space APIs
  • 理由:ファイルを書き込むのに十分なストレージの空き容量が有るかを確認する為

なお、理由の部分は配列なので1つでも複数でも設定可能です。実際、以下の様に複数設定している箇所も有ります。

        <key>NSPrivacyAccessedAPIType</key>
        <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
        <key>NSPrivacyAccessedAPITypeReasons</key>
        <array>
          <string>0A2A.1</string>
          <string>C617.1</string>
        </array>

ドキュメントに記載されている内容と生成されるPrivacy manifestファイルの内容に差が有る

Unityのドキュメントを確認するとUnity Engine内で使用しているAPIに関するPrivacy manifest(「カテゴリ」と「理由」)が確認できます。

この情報を確認すると「System boot time APIs - 35F9.1」についての部分が生成されたPrivacyInfo.xcprivacyには含まれてない事が確認できます。

こちらについてはフォーラムの投稿によるとドキュメントが正しく、PrivacyInfo.xcprivacyの記述が間違ってるようです。まぁ、直ぐに修正されるでしょうが待てない場合は手動で追加しましょう。

Privacy Manifestファイルの自作例

例としてここではUnity向けにiOSのPluginを自作したというシチュエーションを想定します。

このPluginの中では「UIDocumentPickerViewController経由でファイルのタイムスタンプにアクセスする」という事があります。この場合にはどの様な Privacy Manifest ファイルを作成するのかを考えます。

まずはファイルのタイムスタンプに関わる事なのでNSPrivacyAccessedAPITypeに設定するのはNSPrivacyAccessedAPICategoryFileTimestampになります。

次にNSPrivacyAccessedAPITypeReasonsで設定する理由について考えます。

確認すべきはこちらのドキュメントです。 NSPrivacyAccessedAPICategoryFileTimestamp(File timestamp APIs)には以下の理由が選択可能です。

説明
DDA9.1 バイスを使用している人にファイルのタイムスタンプを表示する。この理由でアクセスされた情報はデバイス外に送信できない。
C617.1 アプリ コンテナ、アプリ グループ コンテナ、またはアプリの CloudKit コンテナ内のファイルのタイムスタンプ、サイズ、またはその他のメタデータにアクセス。
3B52.1 ドキュメント ピッカー ビュー コントローラー(UIDocumentPickerViewController)を使用するなど、ユーザーが特別にアクセスを許可したファイルまたはディレクトリのタイムスタンプ、サイズ、またはその他のメタデータにアクセスする。
0A2A.1 サードパーティ SDK がアプリが使用するファイル タイムスタンプ API のラッパー関数を提供しており、アプリがラッパー関数を呼び出すときにのみファイル タイムスタンプ API にアクセスする。

3B52.1が該当しそうですね。これを設定します。

この情報をまとめるとファイルの内容は以下の様になります。

<?xml version="1.0" encoding="utf-8"?>
<plist version="1.0">
  <dict>
    <key>NSPrivacyAccessedAPITypes</key>
    <array>
      <dict>
        <key>NSPrivacyAccessedAPIType</key>
        <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
        <key>NSPrivacyAccessedAPITypeReasons</key>
        <array>
          <string>3B52.1</string>
        </array>
      </dict>
    </array>
  </dict>
</plist>

これをPrivacyInfo.xcprivacyというファイル名(※)で保存し、Assets/Plugins/iOSという構造のフォルダを作成し、そこに配置します。

※拡張子が.xcprivacyならPrivacy Manifestファイルと判定されるので実際にはPrivacyInfoの部分はPlugin名など区別が付きやすい名前を使った方が良いでしょう。保存するフォルダについてもAssets/Pluginsを使う事も可能です。

Xcodeプロジェクト内のPrivacyInfo.xcprivacyを確認すると以下の様にきちんと追加されている事が確認できます。

Item2の所に追加されるのが綺麗では有りますが、これでも記述ルール的にはOKなのかな?

補足

現状、Xcode(Version 15.2)で「Generate Privacy Report」を実行した時に空白の(何も記述されていない)PDFが生成されます。 FlutterのGithubのissueでも同じ症状が出ているとの記載が有る為、現状はこの挙動になる様です。