# ガイドライン2.3.1：隠し機能とOTAアップデート

> ガイドライン2.3.1は隠し機能や審査メモにない機能を禁止します。リモートで変えてよいことと新ビルドが必要なことを解説します。

元のページ：[ガイドライン2.3.1：隠し機能とOTAアップデート](https://devoria.fr/ja/blog/guideline-2-3-1-hidden-features-ota-updates)
著者：[Mehdi Azizi](https://devoria.fr/ja/mehdi-azizi)
公開日：2026-11-04
内容の最終更新：2026-11-04


ガイドライン2.3.1は、隠された機能、休眠状態の機能、文書化されていない機能を禁止しています。アプリがすることはすべて、ユーザーにも審査担当者にも見えていなければなりません。新しい機能はひとつ残らず、審査メモで具体的に説明します。**リモートアップデートでできるのは、Appleが見たものを修正することだけです。Appleが見ていないものを追加することは決してできません。**

僕はiOSアプリをExpoで公開していて、どのアプリにも最初のビルドからEAS Updateを組み込んで修正を配信しています。僕のルールは「バージョンが審査中の間はリモートアップデートを一切出さない」です。このガイドは、Appleのガイドライン本文、ライセンス契約、Expoのドキュメント、そして公開されているリジェクト事例をもとにしています。

## ガイドライン2.3.1には何が書かれている？

2.3.1は、[App Review Guidelines](https://developer.apple.com/app-store/review/guidelines/#2.3.1)のセクション2「Performance」にある2.3「Accurate Metadata」の最初の項目です。本文はこう始まります。「Don't include any hidden, dormant, or undocumented features in your app; your app's functionality should be clear to end users and App Review.」つまり、隠したもの、眠らせたもの、説明のないものは一切ダメということです。

続く部分は、毎回の提出が対象です。「All new features, functionality, and product changes must be described with specificity in the Notes for Review section of App Store Connect (generic descriptions will be rejected) and accessible for review.」**新しい機能はすべて審査メモで具体的に説明し、審査担当者が実際に触れる状態にしておく必要があります。**「バグ修正と改善」だけでは足りません。

同じ項目は、誤解を招くマーケティングも対象にしています。存在しないコンテンツやサービスを約束したり、偽の価格を表示したりすることです。App Store内でも外でも同じです。

この部分はNoleraで役に立ちました。リリース前にストアページを読み直したところ、検証できない文が2つ見つかりました。すでに事実でなくなっていた「インターフェースはフランス語のみ」と、まだ一度も公開していないアプリなのに書いていた「いちばん選ばれているパック」です。審査担当者へのメモも、古い状態のプロダクトを説明していました。まさにこの項目が狙っているケースです。一方、[2.3.10](https://devoria.fr/ja/blog/guideline-2-3-10-accurate-metadata-rejection)は主にストアページが対象です。

## 2.3.1のリジェクトメッセージは何を意味する？

リジェクトのタイトルは「Guideline 2.3.1 - Performance」で、後ろに「Hidden Features」が付くこともあります。React Nativeの開発者が公開したメッセージを2つ紹介します。

- **2024年3月**、[CodePushのGitHub issue](https://github.com/microsoft/react-native-code-push/issues/2680)より。「The app contains hidden features.」とだけ書かれていて、詳しい説明はありません。開発者が詳細を求めると、2.5.2としての補足が返ってきました。「Your app, extension, or linked framework appears to contain code designed explicitly with the capability to change the app's behavior or functionality after App Review approval.」その後アプリが通ったかどうかは、issueには書かれていません。
- **2023年2月**、[別のissue](https://github.com/microsoft/react-native-code-push/issues/2434)では、Appleはバイナリ内の「CodePush-related remote code downloading/updating support」を問題にしています。

僕の解釈はこうです。**審査担当者に見えているのはアップデートそのものではなく、アップデートを受け取れるコードです。**この2件はどちらもCodePushが対象です。EAS Updateを対象にした最近の公開リジェクト事例は見つかりませんでしたが、だから安全という証明にはなりません。

## リモートアップデート：2.5.2とライセンス契約が認めていること

[ルール2.5.2](https://developer.apple.com/app-store/review/guidelines/#2.5.2)は、[バックグラウンドモード](https://devoria.fr/ja/blog/guideline-2-5-4-background-mode-rejected)のガイドでも触れていますが、アプリが「download, install, or execute code which introduces or changes features or functionality of the app」ことを禁止しています。

[Apple Developer Program License Agreement](https://developer.apple.com/support/terms/apple-developer-program-license-agreement/#b331)の第3.3.1(B)条は、ダウンロードした実行可能コードを禁止していますが、「Interpreted code may be downloaded to an Application」とも明記しています。条件は3つです。そのコードがアプリの主な目的を変えないこと、署名、サンドボックス、OSのセキュリティ機能を回避しないこと、他のアプリのストアを作らないことです。

ExpoアプリのJavaScriptはインタプリタで実行されるコードです。僕の考えでは、EAS Updateはこの枠内に収まります。EAS Updateの[ドキュメント](https://docs.expo.dev/eas-update/introduction/)も、アップデートはApp Storeのルールに従うこと、そして「changes to your app's behavior need to be reviewed」ことを明記しています。重大なバグについてExpoが勧めているのは、まずリモートで修正を配信し、その修正を含めた新しいバージョンを提出する流れです。

**僕の線引き：今あるものを直す、調整するのはOK。アプリの中身や売っているものを変えるのはNGです。**

## リモートで変えられること、新しいビルドが必要なこと

僕が使っている基準表です。ここで引用しているAppleとExpoのページをもとにしています。「無料から有料へ」の行と最後の2行は、僕自身の解釈です。

| 変更内容                         | 方法                   | 理由                       |
| -------------------------------- | ---------------------- | -------------------------- |
| JavaScriptのバグ                 | リモートアップデート   | Expoが想定している使い方   |
| テキスト、翻訳、スタイル         | リモートアップデート   | Expoが想定している使い方   |
| サブスクリプションの価格         | App Store Connect      | コードの変更なし           |
| プロモーションテキスト           | App Store Connect      | 再提出が不要               |
| 承認済みタイプの課金アイテム     | 課金アイテムだけの審査 | App Store Connectのルール  |
| あるタイプで初めての課金アイテム | 新しいバージョン       | App Store Connectのルール  |
| 新機能                           | 新しいバージョン       | 2.3.1と2.5.2               |
| 無料から有料へ                   | 新しいバージョン       | ストアページとメモの見直し |
| 権限、Info.plist                 | 新しいビルド           | バイナリ内のファイル       |
| ネイティブモジュール、Expo SDK   | 新しいビルド           | ネイティブコードの変更     |
| 機能をオフにするスイッチ         | リモート設定           | 一時的なら許容される       |
| 機能を表に出すスイッチ           | 禁止                   | 審査されていない機能       |

プロモーションテキストは「without requiring an updated submission」で変更できると、Appleの[バージョン情報](https://developer.apple.com/help/app-store-connect/reference/app-information/platform-version-information)のページに書かれています。各タイプで最初の課金アイテムは新しいバージョンと一緒に提出し、2つ目以降は単独で提出できます。これは[課金アイテムの提出](https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/submit-an-in-app-purchase)に関するヘルプに書かれています。Expoは、ネイティブコード、権限、SDKのバージョンを新しいバイナリが必要なものとしています。[ITMS-90683](https://devoria.fr/ja/blog/itms-90683-missing-purpose-string-expo)と同じ扱いです。故障した機能をオフにするスイッチは、何も新しいものを追加しません。ただし、サブスク会員がお金を払ったものを取り上げない限りです。

## リジェクトされないリモートスイッチの使い方

リモートスイッチ、つまりフィーチャーフラグは、それ自体が禁止されているわけではありません。何を隠しているかで決まります。僕のルールです。

- **スイッチで表示できるものはすべてアプリに入っていて、審査担当者向けにはオンになっている**こと。そして審査メモに名前を書いておくこと。
- A/Bテストでは、審査担当者が見られる2つのバリエーションを比べます。審査済みのバリエーションと未審査のバリエーションを比べることは絶対にしません。
- **審査中かどうかを検知して挙動を変えるコードは書かない。**それこそが隠し機能の定義そのものです。
- リモートで制御するペイウォールには承認済みのプロダクトだけを表示し、どのバリエーションも[ルール3.1.2](https://devoria.fr/ja/blog/guideline-3-1-2-subscription-rejection)を守ること。

## デモモードとテストアカウント

[ガイドライン2.1](https://devoria.fr/ja/blog/guideline-2-1-app-store-rejection-fix)は、ログイン機能があるアプリにデモアカウントを求めています。サーバーも動いている必要があります。法律やセキュリティ上の理由でアカウントを用意できない場合は、アプリ内のデモモードで代えることもできます。ただしそれは「with prior approval by Apple」の場合に限られ、すべての機能を見せる必要があります。Appleのバージョン情報のページには、さらにこう書かれています。アカウントは期限切れにならないこと、追加のアカウントはメモに書くこと、メモは4,000バイトまでであることです。

2.3.1との関係はこうです。**デモモードやテストアカウントで、普段は見えない画面が開くなら、それを説明しなければなりません。**秘密のジェスチャー、コード、特別なアカウントを申告していなければ、それは隠し機能です。特別なアクセス方法はすべて、何が開くのかも含めてメモに書きましょう。

## 僕のルール：審査中はリモートアップデートを出さない

僕がどのアプリにもEAS Updateを入れている理由を話します。目覚ましアプリのSolysで、効果音の再生が1回失敗しただけでアプリが無音になるJavaScriptのバグがありました。修正はたった3行でしたが、配信するにはフルビルドと審査が必要でした。それ以来、全アプリで最初のビルドからexpo-updatesを組み込んでいます。これはネイティブモジュールなので、これなしでコンパイルしたバイナリは何も受け取れません。`app.json`の設定はこうです。

```json
{
  "expo": {
    "runtimeVersion": { "policy": "fingerprint" },
    "updates": { "fallbackToCacheTimeout": 0, "checkAutomatically": "ON_LOAD" }
  }
}
```

`fingerprint`を使うと、アップデートはネイティブコードが一致するバイナリにだけ届きます（[ランタイムバージョン](https://docs.expo.dev/eas-update/runtime-versions/)）。それでも、バージョンが審査待ちや審査中の間は何も公開しません。理由は2つです。

1. **審査担当者には修正が見えないからです。**`fallbackToCacheTimeout`が0の場合、新規インストールは組み込まれたコードで起動し、アップデートは次回起動時に適用されます（[expo-updatesのドキュメント](https://docs.expo.dev/versions/latest/sdk/updates/)）。審査担当者はインストールして1回起動し、バイナリをテストします。Noleraは、すでにリモートで修正を配信していたのにリジェクトされました。この話は2.1のガイドに書いています。
2. **審査担当者がテストするものは、ユーザーが受け取るものと同じでなければならないからです。**審査中に挙動を変えると、審査されたバージョンと配信されたバージョンの間にズレが生まれます。

## 具体的な審査メモ

2.3.1は一般的な説明を受け付けません。僕ならこのテンプレートを英語で使います。

```text
What's new in this version:
- [Feature]: [where to find it, how to test it].

Remote configuration:
- "[flag]" controls [feature]. It is ON for review.

Over-the-air updates:
- The app uses expo-updates for bug fixes only.
  No update will be published during this review.

Demo account: see Sign-in information. It never expires.
```

## 2.3.1のリジェクトにどう返信する？

App Store Connectで返信します。そこで[App Reviewのメッセージに返信](https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/reply-to-app-review-messages/)できます。

- **メッセージがあいまいなまま**：2024年のissueの開発者のように、どの機能が対象なのか聞きましょう。
- **実在する機能の説明が不十分**：正確な操作手順と短い動画を送り、メモを補足しましょう。
- **スイッチが未審査の機能を表に出している**：スイッチを削除するか、オンにして説明を書き、ビルドし直しましょう。
- **アップデート用のコードが問題になっている**：修正のためだけに使っていて、第3.3.1(B)条の範囲内だと説明しましょう。2023年のissueでは、Appleはそのコードの削除を求めていました。

## 提出前の2.3.1チェックリスト

- このバージョンの新機能はすべて、操作手順とあわせてメモに書いてある。
- リモートスイッチはすべて審査向けにオンになっていて、メモに名前が書いてある。
- 審査担当者向けに挙動を変えるコードはない。
- デモモード、テストアカウント、ジェスチャーなどの特別なアクセス方法を説明してある。
- ストアページとペイウォールは、ビルドにできないことを約束していない。
- 審査中にリモートアップデートを公開していない。

## 提出前に申請内容をチェックする

[Review Kit](https://devoria.fr/ja/kits/app-review)には、僕の提出前チェックリスト、審査担当者向けメモのテンプレート、プロジェクトを読み直してくれるClaude Codeのスキルが入っています。人の目で確認したい場合は、[僕と1時間のセッションを予約](https://devoria.fr/ja/coaching)してください。審査メモとアップデートの設定を、ビデオ通話で一緒に見直します。全体の進め方は[Appleにリジェクトされたアプリ](https://devoria.fr/ja/expertise/app-rejected-by-apple)のページにまとめています。

初めてのリリースを準備中ですか？[無料の診断を受けてみてください](https://devoria.fr/ja/diagnostic)。やるべきステップを正しい順番に並べ、僕のAppleリジェクト対策チェックリストもお送りします。

## よくある質問

### 「Guideline 2.3.1 - Performance - Hidden Features」とはどういう意味？

Appleが、アプリに隠された機能、休眠状態の機能、または審査メモに書かれていない機能があると判断したということです。審査後にアプリを変更できるコードが対象になることもあり、その場合は2.5.2のリジェクトが一緒に来ることもあります。

### EAS UpdateはAppleに認められている？

ライセンス契約は、アプリの主な目的を変えない限り、インタプリタで実行されるコードのダウンロードを認めています。修正はOKです。審査されていない機能の追加はNGです。

### iOSアプリでフィーチャーフラグは使える？

使えます。ただし、フラグで表示できるものがすべて審査済みであることが条件です。審査向けにはすべてのスイッチをオンにして、メモに説明を書きましょう。

### デモモードは審査担当者に申告する必要がある？

あります。アプリ内のデモモードにはAppleの事前承認が必要で、すべての機能を見せる必要があります。

### 審査中にリモートアップデートを公開してもいい？

はっきり禁止している規定はありません。ただ、審査担当者は初回起動時にそのアップデートを見ることができず、審査されたバージョンとのズレも生まれます。僕は毎回控えています。


## あなたのプロジェクト

[Review Kit](https://devoria.fr/ja/kits/app-review)：私のApp Store審査チェックリスト、修正済みのAppleのリジェクト事例、Google Play用チェックリスト、Claude Codeのスキル3つ。￥8,500。

[iOS & Android Kit](https://devoria.fr/ja/kits/ios)：Claude CodeでiPhoneとAndroidのアプリを作りましょう。私のアプリのスターターコード、ストア公開までの手順、すべてのキットが揃っています。￥17,500。

[診断：あなたとiPhoneアプリの間にあるもの](https://devoria.fr/ja/diagnostic)：7つの質問、60秒。iPhoneアプリの公開を本当に妨げているもの、4ステップのロードマップ、あなたに合ったキットがわかります。
