先日、新しい壁紙アプリを App Store Connect へ提出しようとしたところ、ビルドは通っているのに「このAppにはApp プライバシー情報がありません」という赤い表示で先へ進めませんでした。コードは仕上がっているのに、最後の最後で止まる。個人開発でアプリを出していると、この申告の欄で毎回少しだけ身構えます。
「Appプライバシー」は、アプリが集めるデータの種類を開発者自身が申告する欄です。やっかいなのは、自分が書いたコードだけでなく、組み込んだサードパーティSDK(広告・課金・クラッシュ解析)が裏で集めるデータまで、すべて自分の責任で申告しなければならない点です。私自身、最初の数本はここで何度も差し戻され、SDKごとに「何が集まるのか」を一つずつ調べ直す羽目になりました。
以下に、AdMob・RevenueCat・Crashlytics を入れた標準的な構成で、私が実際にどの項目へチェックを付けたかを手元メモとして残します。値は構成やSDKのバージョンで変わりますので、最後は必ずご自身の環境で確認してください。
「Appプライバシー」とプライバシーマニフェストは別物です
混同しやすいので最初に切り分けます。よく似た言葉が二つあり、両方とも必要です。
| 名称 | 実体 | どこで設定するか |
|---|---|---|
| プライバシーマニフェスト(PrivacyInfo.xcprivacy) | アプリのバイナリに埋め込むファイル。収集データ種別と「Required Reason API」の使用理由を機械可読で宣言する | ビルド(Expo の設定/各SDKが同梱) |
| Appプライバシー(栄養成分表示) | ストアの製品ページに表示される「データの取り扱い」一覧。開発者の自己申告 | App Store Connect のWebフォーム |
前者はクローラーが読む「機械向けの宣言」、後者はユーザーが製品ページで読む「人向けの表示」です。マニフェストを正しく入れていても、Web側の申告は別途自分で埋める必要があります。私はこの二つを当初は同じものだと思い込んでいて、マニフェストを整えたのに提出できず、しばらく原因がわかりませんでした。
広告・課金・解析を入れた瞬間に申告対象が増えます
純粋に画像を表示するだけの壁紙アプリなら、申告は最小限で済みます。ところが収益化と運用のために三つのSDKを足すと、一気に「データ収集あり」へ傾きます。私の構成で実際に付けた項目は、おおむね次の通りです。
| SDK(用途) | 主に集まるデータ種別 | ユーザーにリンクされる | トラッキングに使う |
|---|---|---|---|
| AdMob(広告) | 識別子(広告ID/IDFA等)、使用状況データ、診断 | はい(広告配信のため) | はい(パーソナライズ広告の場合) |
| RevenueCat(課金) | 購入、識別子(ユーザーID)、使用状況データ | はい | いいえ |
| Crashlytics(クラッシュ解析) | 診断、識別子(インストールID) | いいえ(多くの構成で) | いいえ |
ここで一番の分かれ道は AdMob の「トラッキングに使う」です。パーソナライズ広告を有効にすると、広告IDをユーザー追跡の目的で使うことになり、申告上も「Used to Track You」に該当します。RevenueCat と Crashlytics は、私の構成では「自社サービスの運用のために集めるが、第三者をまたいだ追跡には使わない」ため、トラッキングには含めていません。
各SDKは公式に「どのデータを集めるか」をまとめたページを公開しています。ここを読まずに自己判断で埋めると、後で齟齬が出ます。私は申告のたびに、各社の最新のデータ収集ドキュメントを開き直してから埋めるようにしています。
「トラッキングに使う」にチェックすると、ATTが必須になります
ここが提出時に最もつまずく連鎖です。Appプライバシーで「識別子をトラッキングに使う」と申告したのに、アプリが App Tracking Transparency(ATT)の許可ダイアログを出していないと、審査で差し戻されます。申告と実装が食い違っているからです。
Expo なら expo-tracking-transparency を入れ、許可文言を設定します。
{
"expo": {
"plugins": [
[
"expo-tracking-transparency",
{
"userTrackingPermission": "あなたに合った広告を表示するために、利用状況を利用します。"
}
]
]
}
}そして、パーソナライズ広告を読み込む前に必ず許可を求めます。
import { requestTrackingPermissionsAsync } from "expo-tracking-transparency";
const { status } = await requestTrackingPermissionsAsync();
// granted のときだけ、パーソナライズ広告を有効にする
const personalized = status === "granted";許可されなかった場合はパーソナライズを切り、非パーソナライズ広告にフォールバックする実装にしておきます。「申告した=ATTを実装した=ユーザーが拒否したら追跡しない」——この三つが揃っていないと、どこかで矛盾が表面化します。私は一度、ATTの文言だけ設定してダイアログの呼び出しを忘れ、提出後に気づいて慌てて差し替えたことがありました。
三軸(収集する/リンクされている/トラッキング)の決め方
Appプライバシーは、データ種別ごとに次の三つを順番に決めていく作業です。迷ったときは、この順で自問すると整理しやすいです。
まず「そもそも集めているか」。自分のコードに加えて、組み込んだSDKが集めるものも含めて棚卸しします。広告SDKを入れた時点で、識別子と使用状況データは「集めている」側に倒れます。
次に「ユーザー本人にひも付くか」。アカウントや端末IDを通じて個人を識別できるなら「リンクされている」です。購入履歴はアカウントにひも付きますので、私はRevenueCat関連を「リンクされている」に入れています。
最後に「第三者をまたいだ追跡に使うか」。これが ATT と直結する一番重い判断です。パーソナライズ広告は該当し、純粋な運用解析は通常該当しません。ここを曖昧なまま「念のため全部チェック」にすると、不要にATTが必須化して許可率も下がりますので、根拠を持って絞るのが実用的だと感じています。
SDKの更新と一緒に申告も見直す
一度埋めて終わり、ではないのが運用の難しいところです。SDKをメジャー更新すると、集めるデータ種別が増えていることがあります。私は6本のアプリを並行運用していますので、年に一度のSDK更新のタイミングで、各社のデータ収集ドキュメントと自分の申告を突き合わせる時間を必ず取るようにしました。
最近は、SDKごとの「集まるデータ→Appプライバシーの分類」の対応表を自分用に一枚作り、新しいアプリを出すときはそれをコピーして差分だけ直す形に落ち着いています。毎回ゼロから考えるより、はるかに事故が減りました。
次に新しいアプリを提出する前に、まずは組み込み済みSDKを一覧にして、それぞれの最新のデータ収集ページを開いてみてください。コードが完成してから申告で止まるより、その十数分が結果的に近道になります。同じところで足踏みしている方の参考になれば幸いです。