「ITMS-91053: Missing API declaration」アプリのプライバシーレポートファイル内でのAPI使用宣言

![itms91053-ja-thumbnail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/d459da31-21b2-e38c-4a2a-4b69b76aee51.png)

App Storeにアップデートを提出しようとして、以下のメールを受け取ったことはありますか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/bb2f2148-f9ca-bf0f-d682-1b441f44bcff.png)

WWDC 2023で明らかになったように、UserDefaultsのようなAPIを使用する場合は、プライバシーレポートを作成する必要があります。2024年5月1日から、このようなプライバシー宣言なしで新しいアプリのビルドをアップロードすることは許可されません。
プライバシーレポートを作成するには、以下の手順に従ってください：

まず、プロジェクトに新しいファイルを作成します：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/1a1a4633-13e5-16d9-40e1-a830fcef7833.png)

そのファイルのタイプは「App Privacy」と呼ばれます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/bd9bb36e-87e6-c1d8-83db-dfcafbc806b1.png)

このファイルが適用されるターゲットに対してファイルをリンクする必要があります。例えば、UserDefaultsをすべてのアプリターゲット内で使用している場合、このファイルをそれら全てに適用します：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/c474cabd-524f-3ac7-33c7-3f9ea01049bc.png)

アプリのプライバシー設定内には、主に4つのカテゴリーがあります：

|キーの値 | キー名 | タイプ | 説明 |
|---|---|---|---|
| NSPrivacyTracking | プライバシー トラッキング有効 | YES or NO | アプリまたはサードパーティのSDKがApp Tracking Transparencyフレームワークの下で定義されているようにデータをトラッキング目的で使用するかどうかを示すブール値です。 | 
| NSPrivacyTrackingDomains | プライバシートラッキングドメイン | ドメインホスト名の文字列の配列 | トラッキング目的であなたのアプリが使用するドメインです。ユーザーがトラッキングを許可していない場合、これらのドメインへのネットワーク接続が失敗する可能性があります。 | 
| NSPrivacyCollectedDataTypes | プライバシーナビゲーションラベルタイプ | 辞書の配列 | アプリまたはサードパーティのSDKがアプリを使用する人に関して収集するデータのカテゴリと、そのデータを収集する理由を記録します。 | 
| NSPrivacyAccessedAPITypes | プライバシーがアクセスしたAPIのタイプ | エントリの配列（各エントリにはAPIのタイプとアクセス理由が含まれます） | UserDefaultsやディスクスペース、ファイルサイズなどの他のAPIへのアクセスが必要な理由を宣言するためにこれを使用する必要があります |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/8685f6b3-49ea-8227-c8db-85805530e7e6.png)

注：いつでも、生のキーや英語の説明タイトルの間で切り替えることができます。白いエリアを右クリックして生の値の切り替えを使用してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/25041440-0dbe-81be-eba0-1e9be65460bb.png)

以下は、私のアプリがユーザーを追跡せず、ユーザーIDをユーザー登録に使用するが追跡には使用しない、そしてUserDefaultsフレームワークを使用してメインアプリとウィジェット間で設定を保存する場合の、完成したファイルの例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/c1df5e78-b82e-ba72-6d4d-cc64924cca4d.png)

## プライバシーがアクセスしたAPIのタイプ

これは、UserDefaultsやその他のAPIを使用する理由を宣言する必要がある場所です。宣言する必要があるAPIの完全なリストはこちらです：
https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api

プライバシーがアクセスしたAPIのタイプを選択してエンターキーを押し、新しい辞書エントリを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/dcce8ec9-618b-1785-3681-e5f3fbf6d3aa.png)

この項目を展開し、エンターキーを押してプロパティを追加します。2つのプロパティが必要で、「プライバシーがアクセスしたAPIタイプ」はAPIのタイプを宣言し、「プライバシーがアクセスしたAPI理由」はアプリがそのデータが必要な理由の配列です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/b6c94d54-8a29-0c10-3a62-7695587f3edb.png)

例えば、私のアプリがUserDefaultsを使用する場合、アクセスしたAPIタイプとしてUser Defaultsを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/e55c9c37-77fd-1da7-bab7-518f9715c77b.png)

その後、このデータへのアクセス理由のコードを記入します。各APIタイプごとに異なるコードのセットがあります：

### UserDefaults

UserDefaultsを使用してユーザー設定を保存する場合、理由を宣言する必要があります。APIタイプは `NSPrivacyAccessedAPICategoryUserDefaults` と呼ばれます。

#### CA92.1
アプリ自身だけがアクセス可能な情報を読み書きするためにユーザーデフォルトにアクセスします。
注意：このコードを宣言する場合、アプリグループ内でUserDefaultsの値を共有することはできません（アプリとウィジェット間でデータを共有することはできません）

#### 1C8F.1

アプリ自体と同じアプリグループのメンバーであるアプリ、アプリ拡張、App Clipsのみがアクセス可能な情報を読み書きするためにユーザーデフォルトにアクセスします。
注意：この理由でも、同じアプリグループ外のアプリ、アプリ拡張、App Clipsがアクセスできる情報を書き込むことは許可されません。

#### C56D.1

サードパーティのSDKがアプリが使用するためのユーザーデフォルトAPIを囲むラッパー機能を提供しており、アプリがラッパー機能を呼び出すときのみユーザーデフォルトAPIにアクセスします。
注意：この理由でアクセスされた情報、または派生した情報は、サードパーティSDK自身の目的のために使用されたり、サードパーティSDKによってデバイス外に送信されることはできません。

例えば、私のアプリがUserDefaultsを使用して、メインiOSアプリとウィジェット間でユーザーの現在の都市を共有し、天気を表示する場合、`1C8F.1`を使用する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/57232674-a75c-a41b-5389-e773e0666f7e.png)

ウィジェットやアプリグループを持っていない場合は、コード`CA92.1`を使用できますが、将来的にはコードを`1C8F.1`に変更することを忘れないでください。そうしないと、UserDefaultsのデータがアプリ自身にのみ制限される可能性があります。

## ファイルタイムスタンプAPI

これらは、ファイルのタイムスタンプにアクセスするためのAPIであり、`creationDate`、`modificationDate`などを含みます。

APIタイプは`NSPrivacyAccessedAPICategoryFileTimestamp`と呼ばれます。

### APIメソッド
creationDate、modificationDate、fileModificationDate、contentModificationDateKey、creationDateKey、getattrlist(:::::)、getattrlistbulk(:::::)、fgetattrlist(:::::)、stat、fstat(::)、fstatat(::::)、lstat(::)、getattrlistat(:::::_:)

### 宣言コード

#### DDA9.1
デバイスを使用している人にファイルのタイムスタンプを表示したい場合。
注：この理由を宣言すると、情報はデバイス外に送信されません。

#### C617.1
アプリコンテナ、アプリグループコンテナ、またはアプリのCloudKitコンテナ内のファイルのタイムスタンプ、サイズ、またはその他のメタデータにアクセスします。

#### 3B52.1
ユーザーが特にアクセスを許可したファイルやディレクトリのタイムスタンプ、サイズ、またはその他のメタデータにアクセスします。例えば、ドキュメントピッカービューコントローラーを使用する場合などです。

#### 0A2A.1
サードパーティのSDKがアプリが使用するためのファイルタイムスタンプAPIの周りにラッパー機能を提供しており、アプリがラッパー機能を呼び出すときのみファイルタイムスタンプAPIにアクセスします。
要約すると、システムネイティブのファイルピッカーを使用してユーザーが選択したファイルのみを読み取る場合は3B52.1を使用します。情報を表示するだけで保存やアップロードを行わない場合はDDA9.1を使用します。アプリ、アプリグループ、またはCloudKit内でこの情報にアクセスして使用する場合はC617.1を使用します。

私のアプリは、ユーザーが(iOSシステムネイティブのファイルピッカーを使用して)選択したファイルのタイムスタンプにのみアクセスするため、以下の設定を行いました：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/b1fb212f-a9aa-3755-b8e4-0ef0acf0e812.png)

## システム起動時間API

APIタイプは `NSPrivacyAccessedAPICategorySystemBootTime` です。

### APIメソッド
systemUptime
mach_absolute_time()

#### 35F9.1
アプリ内で発生したイベント間の経過時間を測定したり、タイマーを有効にするための計算を実行するために、システム起動時間にアクセスします。このデータをデバイス外に送信することはできません。

#### 8FFB.1
UIKitやAVFAudioフレームワークに関連するイベントなど、アプリ内で発生したイベントの絶対タイムスタンプを計算します。

#### 3D61.1
ユーザーが提出を選択したバグレポートにおいて。システム起動時間情報はレポートの一部としてユーザーに顕著に表示されなければなりません。

## ディスクスペースAPI

APIタイプは `NSPrivacyAccessedAPICategoryDiskSpace` です。

### APIメソッド
volumeAvailableCapacityKey
volumeAvailableCapacityForImportantUsageKey
volumeAvailableCapacityForOpportunisticUsageKey
volumeTotalCapacityKey
systemFreeSize
systemSize
statfs(::)
statvfs(::)
fstatfs(::)
fstatvfs(::)
getattrlist(::::_:)
fgetattrlist(::::_:)
getattrlistat(::::::)

#### 85F4.1
デバイスを使用している人にディスクスペース情報を表示します（表示のみで、この情報をデバイス外に送信することは含まれません）。

#### E174.1
ファイルを書き込むための十分なディスクスペースがあるかを確認する、またはディスクスペースが少ない場合にアプリがファイルを削除できるようにするためにディスクスペースが低いかをチェックします。

#### 7D9E.1
バグレポートに使用されますが、ユーザーが提出するかどうかを選択するオプショナルな情報でなければなりません。

#### B728.1
健康研究アプリで、このAPIカテゴリにアクセスして、研究データ収集に影響を与える低ディスクスペースを研究参加者に知らせます。

## アクティブなキーボードのアクセスリスト

APIタイプは `NSPrivacyAccessedAPICategoryActiveKeyboards` です。

### APIメソッド
activeInputModes

#### 3EC4.1
あなたのアプリがカスタムキーボードアプリであり、デバイス上でアクティブなキーボードを特定するためにこのAPIカテゴリにアクセスするときに使用します。

#### 54BD.1
デバイスを使用している人に正しいカスタマイズされたユーザーインターフェースを提示するためにアクティブなキーボード情報にアクセスします。アプリはテキストの入力や編集のためのテキストフィールドを持ち、ユーザーに観察可能な方法でアクティブなキーボードに基づいて異なる振る舞いをする必要があります。

## プライバシー トラッキング有効 (Privacy Tracking Enabled)
このブール値は、アプリがユーザー情報をトラッキング目的で使用するかどうかを示します。

## プライバシー トラッキングドメイン (Privacy Tracking Domains)
これは、ドメインホスト名の文字列値の配列を含む文字列配列です。これらはトラッキング関連目的で使用されるドメインです。トラッキングに使用されないドメインを記載しないでください。なぜなら、ユーザーがアプリにトラッキングしないように求めた場合、これらのドメインへのネットワークリクエストは失敗するからです。

## プライバシーナビゲーションラベルタイプ (Privacy Nutrition Label Types)
ここでは、アプリが収集するデータのタイプと、これらを収集する理由を宣言します。プライバシーナビゲーションラベルタイプを選択してエンターキーを押すと、必要な情報を含む新しいエントリが自動的に作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/6514d4cb-f055-aea4-9d93-012fe74dbdc5.png)

収集データタイプのドロップダウンメニューを選択できます。これは、私たちが収集するデータのタイプを示します。例えば、ここではユーザーのメールアドレスを選択できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/6156c2be-6845-209d-6e76-e990cb202321.png)

データタイプの完全なリストはこちらにあります：https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_data_use_in_privacy_manifests

次に、データがユーザーにリンクされているかどうかを回答します（例えば、メールアドレスがユーザープロファイルにリンクされている場合、これをYESに設定する必要があります）。そして、データがトラッキング目的で使用されているかどうか。

その後、コレクション目的の配列に、アプリがこの情報を必要とする理由を追加します（例えば、ユーザーアカウントの登録にメールアドレスが必要な場合、アプリ機能 (App Functionarlity) を選択できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/bbf2ad92-908a-58c5-ed02-a1c8989c772e.png)

これは、App Store Connectでプライバシーに関する質問に答える方法と似ています。

## Documentation

https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_data_use_in_privacy_manifests

---

English version

https://medium.com/@MszPro/itms-91053-missing-api-declaration-for-accessing-userdefaults-timestamps-other-apis-d5c0cbf84a5e

---

:relaxed: [Twitter @MszPro](https://twitter.com/MszPro)

:relaxed: 個人ウェブサイト https://MszPro.com

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/33652157-7da9-ee68-3e4d-4b416edfec58.png">