RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/開発ツール
開発ツール/2026-04-30中級

Rork で iOS アプリ申請を通すための App Tracking Transparency 実装

Rork で作った iOS アプリが ATT(App Tracking Transparency)周りで App Store 審査に落ちないようにする実装手順を、Info.plist の説明文・プロンプトを出す位置・拒否されたときの後続フローまで含めて整理しました。

Rork515App Tracking Transparency3ATT9iOS108App Store 審査expo-tracking-transparencyプライバシー10

App Store 審査で意外と落ちるのが ATT 周りです

Rork でアプリを作って TestFlight まで動かし、いざ App Store に申請したら「App Tracking Transparency の説明が足りません」と返されて何日かロスする — これは私が3度ほど経験したパターンです。コードはちゃんと動くのに、Info.plist の文言と、プロンプトを出すタイミングと、ユーザーが拒否したときの分岐の3点が揃っていないと、Apple のレビュアーは納得してくれません。

ATT は iOS 14.5 から必須化されたプライバシー機構で、IDFA(広告識別子)など他社アプリ・サイトをまたいだトラッキング情報を取得する場合は、ユーザーから明示的な許可を取る必要があります。AppsFlyer / Adjust / Google Mobile Ads など、広告系・アトリビューション系の SDK を入れている時点で、ほぼ全員が対象になります。

ここでは Rork(React Native + Expo ベース)でアプリを開発している前提で、expo-tracking-transparency を組み込んで審査を一発で通すための手順をまとめます。コードと一緒に、申請文の書き方・タイミング設計・拒否時のフォールバックまで踏み込んで解説します。

ATT が必要になる典型的な3パターン

まず最初に、自分のアプリに ATT 実装が必要かを判断しておきましょう。次のいずれかに該当するなら必須です。

  • 広告 SDK を使う: AdMob、Meta Audience Network、Unity Ads、AppLovin など、ほぼすべての広告ネットワーク
  • アトリビューション SDK を使う: AppsFlyer、Adjust、Branch、Singular など、インストール元を追跡するもの
  • アナリティクス SDK で IDFA を扱う: Firebase Analytics で広告 ID を有効化している場合、Mixpanel の一部設定など

逆に、自社サーバーに保存する独自の UUID だけで済んでいて、IDFA を一切触らないアプリは ATT プロンプトを出す必要がありません。とはいえ Apple は「触っていないと言いつつ間接的に触っているケース」を厳しく見るので、SDK のドキュメントで IDFA 利用の有無を必ず確認してください。

Step 1: Info.plist に説明文を追加する

Rork プロジェクトでは app.json(または app.config.js)に ios.infoPlist を追加し、NSUserTrackingUsageDescription キーを設定します。

{
  "expo": {
    "ios": {
      "bundleIdentifier": "com.example.myapp",
      "infoPlist": {
        "NSUserTrackingUsageDescription": "あなたに合った広告を表示し、サービスを無料で提供し続けるために、利用状況の情報を使わせていただけませんか。許可しなくてもアプリのすべての機能はそのままお使いいただけます。"
      }
    }
  }
}

ここで重要なのが説明文の中身です。Apple のレビュアーは次の3点を見ています。

  1. 何のために使うかが具体的か: 「広告のため」「分析のため」だけでは弱く、ユーザーにとっての利益が伝わる必要があります
  2. 拒否しても利用に支障がないと明記しているか: 必須権限のような書き方は審査で弾かれます
  3. 誤解を招く表現がないか: 「機能改善のため」だけだと曖昧で、実態(広告 ID 利用)と齟齬があると判断されます

私が通った文面は、上記サンプルのように「広告」「無料提供」「拒否しても全機能使える」の3点を必ず入れる構成です。

Step 2: expo-tracking-transparency でプロンプトを呼ぶ

Rork はプロジェクトに Expo モジュールを追加できるので、expo-tracking-transparency を使うのがいちばん安全です。生成されたコードに次のように手を入れます。

// app/_layout.tsx などのエントリ付近
import {
  getTrackingPermissionsAsync,
  requestTrackingPermissionsAsync,
} from 'expo-tracking-transparency';
import { Platform } from 'react-native';
import { useEffect } from 'react';
 
export async function ensureTrackingPermission(): Promise<boolean> {
  // iOS のみ実行(Android は対象外)
  if (Platform.OS !== 'ios') return true;
 
  // 14.5 未満は API 自体が存在しないので true 扱い
  const current = await getTrackingPermissionsAsync();
  if (current.status === 'granted') return true;
  if (current.status === 'denied') return false;
 
  // undetermined の場合だけプロンプトを出す
  const result = await requestTrackingPermissionsAsync();
  return result.status === 'granted';
}

ここで気をつけたいのが、undetermined(未決定)のときだけ requestTrackingPermissionsAsync を呼ぶ点です。一度ユーザーが「許可しない」と答えた状態で再度呼んでもプロンプトは表示されず、純粋に denied が返るだけ。再表示するには「設定」アプリを開いてもらう必要があります。

Step 3: プロンプトを出すタイミングを設計する

Apple は「適切なタイミングでプロンプトを表示すること」を推奨しており、これを守らないと審査でリジェクトされます。私の経験上、起動直後にいきなり出すのは弱手で、次のような流れが通りやすいです。

  1. 起動直後はオンボーディング画面を見せる(プロンプトは出さない)
  2. オンボーディングの最後で「広告について」を1画面挟み、「このアプリは無料でお届けするため広告を表示します。次の画面で表示される確認に『App にトラッキングを許可』を選んでいただけると、より興味に合った広告をお見せできます」とユーザーに事前説明する
  3. その画面の「次へ」ボタンで requestTrackingPermissionsAsync() を呼ぶ

この 事前説明(プリプロンプト) を入れると、許可率が体感で1.5〜2倍ほど変わります。Apple もこのパターンを公式サンプルで推奨しているので、審査の心象も良くなります。

Step 4: 拒否されたときの後続フロー

ATT で「許可しない」と回答したユーザーに対して、広告を一切出さない・サービスから締め出す、という対応は禁止です(ガイドライン 3.2.2)。やるべきは、IDFA を使わない広告配信に切り替えることです。

import mobileAds from 'react-native-google-mobile-ads';
 
export async function configureAds(): Promise<void> {
  const trackingAllowed = await ensureTrackingPermission();
 
  await mobileAds().setRequestConfiguration({
    // 拒否時は非パーソナライズ広告のみ
    tagForChildDirectedTreatment: false,
    maxAdContentRating: 'T',
  });
 
  if (!trackingAllowed) {
    // npa=1 は AdMob で非パーソナライズ広告を要求するフラグ
    await mobileAds().initialize();
    return;
  }
 
  await mobileAds().initialize();
}

具体的な広告リクエストでは、AdMob の場合 requestNonPersonalizedAdsOnly: !trackingAllowed を渡します。AppsFlyer や Adjust 系のアトリビューション SDK は、disableIDFA のようなオプションが用意されているので、許可状況を渡して切り替えてください。

そして iOS は SKAdNetwork という、IDFA を使わずにインストール計測ができる仕組みを Apple 公式で用意しています。広告主 ID の 1:1 計測は無理ですが、キャンペーン単位の効果測定は可能です。本格的なマーケ予算を投じるアプリなら、SKAdNetwork の対応も合わせて進めるのが現実的な落としどころです。

Step 5: 私が審査で詰まった具体的なポイント

ここまでで実装と設計の話を書きましたが、レビューで実際に詰まった点を共有します。同じ落とし穴を避けるための参考にしてください。

  • 説明文に「広告」と書いていなかった: 「サービス改善のため」とだけ書いて出したら、レビュアーから「広告 SDK が含まれているのに広告と明記されていない」と指摘されました。SDK の中身に応じた具体性が必要です
  • オンボーディング前にプロンプトを出していた: 「ユーザーに何のためか分からない状態でプロンプトが出る UX は不適切」とリジェクト。事前説明画面を1枚挟んで通りました
  • 設定画面に再許可導線がなかった: 一度拒否したユーザーが心変わりしたとき、設定アプリへ誘導する Linking.openURL('app-settings:') を仕込んでいないと、内部レビューで使い勝手が悪い扱いになります

これらは Apple Developer のドキュメントには明示されていない、レビュアーの現場判断の部分です。ただ、リジェクトのフィードバックを読むと、上記3点は繰り返し出てくる定番の指摘でした。

まずは Info.plist の文面から見直してみてください

ATT 対応は「コードを書く前に文面を整える」作業のほうが審査結果を左右します。今すぐ自分のアプリの app.json を開いて、NSUserTrackingUsageDescription に「広告」「無料提供」「拒否しても全機能使える」の3点が含まれているか確認してみてください。それだけで、リジェクト確率はかなり下げられます。

実装の細かい部分でつまずいたら、関連するアトリビューション SDK 側の挙動も合わせて見直す必要があります。アトリビューションの全体設計は Rork で AppsFlyer / Adjust を使ったアトリビューション計測ガイド で、認証関連の権限 UX 全般は Rork アプリに生体認証(Face ID / Touch ID)を実装する完全ガイド でまとめています。申請手順全体を確認したい場合は Rork アプリの App Store 審査チェックリスト も合わせて読むと、提出前の漏れが減ります。

Expo に閉じない、ネイティブ側の知識が補えます。

シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

開発ツール2026-05-07
Rorkで作ったiOSアプリで App Tracking Transparency のダイアログが出ない時の原因と対処法
Rorkで生成したiOSアプリでATT(App Tracking Transparency)のダイアログが表示されない問題を、Info.plist設定・呼び出しタイミング・AdMob連携の3つの観点から実機検証込みで解決します。
開発ツール2026-04-21
Rork アプリの ATT 許可率を引き上げる実装パターン — iOS のトラッキング同意を広告収益につなげる
Rork で作った iOS アプリの App Tracking Transparency(ATT)許可率を高める実装パターンを、AdMob の広告収益を守る観点から具体的に解説します。purpose string の設計、呼び出しタイミング、プリパーミッション画面、cohort 別の効果計測、UMP(GDPR)との呼び出し順序、非パーソナライズ広告のフォールバックまで扱います。
開発ツール2026-06-29
写真の「選択した項目だけ許可」に正しく向き合う設計
iOS の写真ライブラリ限定アクセス(選択した項目だけ許可)に Rork(Expo)アプリで正しく対応します。フルアクセス・限定・拒否の3状態の判定、選んだ写真だけを扱う前提の画面設計、追加選択を促す導線までを実装コードとともに整理します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →