Communitygithub.com

App Store 事前チェック

読み取り専用のiOS App Store提出前チェック:20のリジェクト要因をスキャンし、Appleのfastlane precheckをラップし、ガイドラインの変更を監視し、提出前に敵対的レビューを実行します。

App Store 事前チェック とは?

このスキルは、iOSアプリをApp Storeに提出する前に、リジェクトのリスクを最小限に抑えるための包括的な事前チェックを提供します。静的分析により最も一般的なリジェクト要因をスキャンし、Apple公式のfastlane precheckツールを統合し、App Storeレビューガイドラインの変更を検出し、Appleのレビュアーを模倣した敵対的レビューを実行します。Claude CodeやCursorなどのAIエージェント上で動作し、読み取り専用でコードやメタデータを変更することなく、結果をレポートしてパストークンを生成します。チェックは5つのフェーズ(ガイドライン変更検出、静的スキャン、Apple公式チェック、敵対的レビュー、結果集約)で構成され、結果はGREEN/YELLOW/REDの3段階で評価され、アップロードガードとして機能します。

対応✓Claude Code~Codex CLI~Cursor
npx skills add berkayturk/appstore-precheck

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

App Store 事前チェック は何をしますか?

すべてのiOS App Store提出の前に実行する、ワンコマンドゲートです。最も一般的なリジェクト要因を静的にスキャンし、Apple公式のメタデータリンターを実行し、ガイドラインの変更を監視し、敵対的レビューをシミュレートすることで、リジェクトのリスクを最小限に抑えます。

このスキルは読み取り専用です。 コード、メタデータ、アセットを編集することはありません。レポートとパストークンの書き込みのみを行います。各リジェクト要因や変更検出の仕組みなど、詳細な方法については references/methodology.md を参照してください。チェックの背景を確認する必要があるときに読んでください。

実行タイミング

  • TestFlight用アーカイブ前
  • App Store Connectで「提出のためにレビュー」を押す前
  • fastlane deliver/release/pilot の前(オプションのアップロードガードフックで制御されます)
  • すべてのポイントリリース時

意図的に実行してください。これは自動的なバックグラウンドステップではなく、人間がトリガーするゲートです。

設定(オプション)

スキャナーは標準的なfastlane + Xcodeのレイアウトを自動検出するため、ほとんどのプロジェクトでは設定は不要です。検出を上書きするには、config.example.json をリポジトリルートに .appstore-precheck.json としてコピーしてください。キー: bundleId(フェーズ2で必須)、iosSourceDir、metadataDir、screenshotsDir、xcstringsPath、paywallGlobs、locales、disclosureKeys.{subscription,trial}、optionalChecks.familyControls、reviewPrepNotes。完全な注釈付きリストは config.example.json を参照してください。

出力契約

スキルは以下の3つの終了状態のいずれかに達します。

状態意味.precheck-pass トークンガードの動作
GREENFAILなし、WARN 2件以下書き込み(有効60分)アップロード許可
YELLOWFAILなし、WARN 3件以上書き込みなしガードがブロック。明示的な確認を要求
RED少なくとも1件のFAIL削除ガードがブロック。FAILリストを表示

ユーザーに判定を提示するときは、Pierre(ピエール)の1行のキャラクターセリフ(フランス人App Review批評家、フェーズ3参照)で始め、その後すぐにプレーンで精密な分析結果に移ってください。この声は薄いラッパーです。その下にあるデータ、FAIL/WARNリスト、file:line 参照、修正方法は、クリーンで機械的に忠実に保ちます。scan.sh の出力を書き換えたり言い換えたりせず、Pierreのセリフは1行に留めてください。

フロー(5フェーズ:0~4)

フェーズ0:ライブガイドライン変更チェック

ライブの App Store レビューガイドライン のセクション番号を guidelines-baseline.json と比較し、最後の調整以降にAppleが追加または削除したセクションを検出します。常に非ブロッキング(最大でもWARN)。 変更は私たちのカバレッジのギャップであり、決してビルドの欠陥ではありません。ページは取得時に切り詰められるため、2パス手法が必要です。正確なプロンプトと調整手順は references/methodology.md を参照してください。ベースラインは自動更新されません。調整は意図的な人間のステップです。

フェーズ1:静的スキャン

bash skills/appstore-precheck/scripts/scan.sh

20のリジェクト要因をカバーする FAIL: / WARN: / PASS: 行を出力します。プライバシーマニフェストのパリティ(5.1.1(v))、目的文字列(5.1.1)、ATT(5.1.2)、他プラットフォームへの言及(2.3.10)、メタデータ制限(2.3.1)、ローカライズのパリティ(2.3.7)、スクリーンショット(2.3.3)、トライアル&自動更新の開示(3.1.2)、復元/利用規約/プライバシーリンク(3.1.2)、プライベートAPI(2.5.1)、最低限の機能(4.0)、Appleでサインインのパリティ(4.8)、外部購入リンク(3.1.1(a))、オプトインのスクリーンタイム/FamilyControlsの正当化(5.1.5)、ATTプロンプトのないトラッキング/IDFA SDK(5.1.2)、輸出コンプライアンスキー(ITSAppUsesNonExemptEncryption)、fastlaneメタデータのサポート/プライバシーURL(2.3)、分析SDKとPrivacyInfoデータタイプ(5.1.1)、プレースホルダー/ダミーメタデータコピー(2.1)。アプリ内購入のシグナルがない場合、IAPチェック(8~10)は自動的にスキップされます。完全なチェックテーブルは references/methodology.md を参照してください。

スキャナーはポータブルBashであるため、エージェントの外部で直接実行して、迅速なCIまたはpre-commitチェックとして使用することもできます。

フェーズ2:Apple公式の fastlane precheck

設定に bundleId が必要です(または app_identifier を直接渡す)、およびApp Store Connect APIの認証情報が必要です。キーをコミットしないでください。 バンドルされたラッパーは環境からASC APIキーJSONを構築し、precheckを実行し、終了時にキーを削除します(--dry-run を使用して認証情報なしでコマンドをプレビューできます)。

ASC_KEY_ID=… ASC_ISSUER_ID=… ASC_P8_PATH=/path/AuthKey.p8 \
  bash skills/appstore-precheck/scripts/phase2-precheck.sh com.example.app

または手動で実行します。環境からキーJSONを生成し、precheckを実行し、その後削除します。

fastlane run precheck \
  app_identifier:"<YOUR_BUNDLE_ID>" \
  api_key_path:"/tmp/asc-key.json" \
  include_in_app_purchases:false \
  default_rule_level:":error"
rm -f /tmp/asc-key.json   # すぐにシークレットを削除

Apple独自のルールエンジンは、URL、GitHubへの言及、不適切な表現、Apple商標、価格設定の文言、ベータキーワードをチェックします。Result: true → PASS。違反行があればFAIL。IAPはすでにフェーズ1でカバーされているため、include_in_app_purchases:false によりAPIキーのIAP制限を回避します。

フェーズ3:敵対的レビュー(最も重要)

サブエージェントをディスパッチし、Pierre、フランス人批評家の厳格な味覚を持つ懐疑的なApple Appレビュアーのロールプレイを行います。以下のプロンプトをそのまま使用し、アプリの詳細を記入してください。

You are Pierre, a veteran Apple App Reviewer who critiques like a French critic. You have seen ten thousand rejections and are impressed by none of them. A new submission just landed on your desk. Your job is to realistically try to reject it, with no approval bias. Pick 5 random guideline items with a spread across sections (one 2.x, two 3.x weighted toward paywall, one 4.x, one 5.x); choose a different combination each run (include a seed line so reruns vary). For each item: (Pass A) grep the relevant files for at least 2 concrete pieces of evidence: metadata for 2.3.x; the paywall view + String Catalog for 3.1.x; Core/navigation for 4.x; Info.plist + PrivacyInfo for 5.1.x. (Pass B) ask "as a reviewer, on what basis would I flag this?" (Pass C) write a rejection draft in Apple's real voice (Guideline X.Y.Z – Category / We noticed… / Specifically… / Next Steps… / Resources…). Assign each item a risk: REJECT-CERTAIN / REJECT-RISK / WARN / PASS. End with a submit recommendation (HOLD / SUBMIT WITH WARNINGS / GO) and the single most critical fix. Read-only: never modify files; if you can't find evidence, say so rather than inventing it. Keep it under 500 words. Include at least one PASS and at least one risk-bearing item, to give a realistic distribution.

フェーズ4:統合+トークン

GREEN/YELLOW/REDの判定とトークンアクションは決定論的であり、FAIL/WARNのカウントのみから導き出されます。scripts/verdict.sh がこれらを計算するため、判定はエージェントの判断だけでなく、機械的にテスト可能です。スキャンの出力をパイプで渡します。

bash skills/appstore-precheck/scripts/verdict.sh < scan-output.txt   # 出力: VERDICT / COUNTS / TOKEN

GREENで終了コード0、REDで1、YELLOWで2を返し、--apply を指定すると .precheck-pass を書き込みまたは削除します(YELLOWは明示的な人間の確認のためにトークンを保持します)。フェーズ0~3の結果は引き続き生成されますが、verdict.shは閾値の計算を固定します。

  1. フェーズ0~3の出力を収集し、FAIL + WARN + PASS を出力契約テーブルに集計します。
  2. 各FAILについて、file:line 参照と修正方法の提案を提供します。
  3. 判定を Pierreの1行 のセリフで始め(実行ごとに言い回しを変え、彼の無表情なフランス人批評家の口調で短く)、その後プレーンな分析結果に移ります。決定:
    • GREEN: Pierre、渋々: "Hmf. I find nothing. Acceptable. Do not make me regret this." その後 date +%s > .precheck-pass && echo "token written" (60分有効)。
    • YELLOW: Pierre: "A few small uglinesses. I would not reject, but I noticed." WARNを平易にリストし、ユーザーに「確認して送信しますか?」と尋ね、確認があった場合のみトークンを書き込みます。
    • RED: Pierre: "Non. {n} faults. Apple would have found fewer. Suivant." トークンなし。その後 file:line と修正を含むプレーンなFAILリスト、および送信がBLOCKEDされていることを明確に示します。 Pierreのセリフは風味付けのみです。その下のFAIL/WARNリスト、file:line、修正はプレーンで外科的であり、言い換えられません。
  4. 最終手動チェックリストを表示します(references/methodology.md を参照)。

ルール

  • 読み取り専用: コードやアセットを変更しないでください。レポートとトークンの書き込みのみを行います。
  • 速度 > 網羅性: scan.sh は並列grep/jqを使用し、数秒で完了します。
  • エラーの飲み込み禁止: スキャンコマンドが失敗した場合、その行はFAILとして報告され、スキャンは続行されます。
  • トークンの場所: リポジトリルートの .precheck-pass。ガードは mmin -60 フィルターでテストします。
  • ローカルのみ: 手動のローカル実行用に設計されています。誤ったシグナルを避けるため、CIでは使用しないでください。

既知の制限

  • ランタイムクラッシュテストはありません。TestFlightとクラッシュレポーターに任せてください。静的解析のみです。
  • いくつかのチェックは、検出されたシグナルに基づくアドバイザリーWARNです(Appleでサインイン 4.8、外部購入 3.1.1(a)、ATTなしのトラッキング/IDFA、分析とプライバシーマニフェスト、メタデータURL、プレースホルダーコピー)。輸出コンプライアンスキーは存在しない場合にフラグが立てられますが、実際の暗号化の回答はApp Store Connectで行う必要があります。
  • 敵対的レビュアーはヒューリスティックシミュレーションであり、Appleの判断を保証するものではありません。
  • ネイティブSwift / SwiftUIで最も正確です。メタデータ、プライバシーマニフェスト、スクリーンショット、輸出コンプライアンスチェックはすべてのiOSアプリに適用されますが、コードレベルのチェックはSwiftソースを読み取るため、React Native(JavaScript)やFlutter(Dart)では誤検出を避けるために過少検出します。
  • iOSのみです。
  • フェーズ0は構造的な変更(追加/削除されたセクション番号)のみを検出します。理由についてはリファレンスを参照してください。

オプション:アップロードガードフック

hooks/fastlane-guard.sh は、新しい .precheck-pass トークンが存在しない場合に fastlane deliver/pilot/release をブロックします。Claude Codeでは hooks/hooks.json を介して自動的に配線されます。その他の環境では、事前コマンドチェックとして自分で配線するか、トークンを手動のゴー/ノーゴーシグナルとして扱ってください。

関連スキル