メインコンテンツへスキップ
チュートリアル

AppleはApp Storeの審査なしでLive Updatesを許可している?

はい、制限内であれば可能です。Appleは、アプリの目的が変わらない限り、JavaScriptのような解釈型codeのOTAアップデートを許可しています。以下に、その正確なルールとCapacitorアプリへの適用方法を説明します。

AppleはApp Storeの審査なしでLive Updatesを許可している?

結論から言うと、Appleは制限の範囲内でライブアップデートを認めています。 アプリの性質自体が変わらない限り、App Storeの審査を通さずに新しいJavaScript、HTML、CSSをiOSアプリに配信できます。ただし、ネイティブのcodeをダウンロードすることはできません。

混乱の多くは、インタプリタで実行されるcodeのライブアップデート(許可)と、新しい実行可能なcodeのダウンロード(禁止)という、2つの異なる概念の混同に起因します。このページでは規約を引用し、その境界線がどこにあるのか、Appleがそれをどう執行しているのかを解説します。

これは法的助言ではありません。現時点で規約がどう読めるか、そして数千ものアプリが本番環境でそれをどう使っているかを示したものです。

Appleの規約の真実

重要なのは2つの条文です。1つ目は、 App Store Review Guideline 2.5.2:

アプリは自身のbundle内で完結している必要があり、指定されたコンテナ領域外のデータの読み書き、および他のアプリを含むアプリの機能や動作を変更・追加するcodeのダウンロード、インストール、実行は禁止されています。

これだけを読むと禁止されているように聞こえますが、例外はもう一つの条文、つまりすべての開発者が署名する Apple Developer Program ライセンス契約の第3.3.1(B)項に記載されています:

解釈可能なcodeは、以下のcodeを満たす場合に限り、アプリケーションにダウンロードできます。(a) App Storeに提出した際の意図や広告内容と矛盾する機能を提供することで、アプリケーションの主な目的を変更しないこと、(b) 他のcodeやアプリケーションのためのストアまたは storefront を作成しないこと、(c) OSの署名、sandbox、またはその他のセキュリティ機能をバイパスしないこと。

つまり、ルールは「ダウンロードされた code は禁止」ということではありません。「ダウンロードされたものは禁止」なのです。 ネイティブ 「code、およびcodeの解釈は、以下の3つの条件を満たす場合に限られます」

CapacitorアプリのWebレイヤーは、JavaScript、HTML、CSSで構成され、 WKWebViewこれはApple独自のWebKitエンジンです。codeとして解釈されるため、例外規定に該当します。ガイドライン4.7でも同様に、バイナリに埋め込まれていないHTML5やJavaScriptコンテンツの実行は、Appleによって明示的に許可されています。

境界線はどこにあるか

live updateなら許可 live updateは許可されない
JavaScript、HTML、CSSのバグ修正 Swift、Objective-C、またはコンパイル済みバイナリのダウンロード
既存のWebスタックにおけるUI変更、テキスト変更、新規画面の追加 アプリを別の製品へ変更すること(メモアプリをカジノアプリにするなど)
Web codeのA/Bテストや段階的なロールアウト App Review時に隠していた機能のアンロック
画像、翻訳、設定の更新 他のアプリや code をインストールするストアの構築
不具合のあるリリースのロールバック iOSのサンドボックス、署名、権限の回避

Capgo は左側のカラムのみを配信します。これはアプリ内のウェブバンドルを置き換えるものです。新しい Capacitor プラグイン、新しい権限、または SDK のアップグレードなど、ネイティブに関する変更は、引き続き通常の App Store リリースが必要です。Capgo の バージョン・ターゲティング は、新しいネイティブ code を必要とするバンドルが、古いバイナリに配信されないようにします。

Appleによる制限の仕組み

Appleが判断するのは技術ではなく、その実態です。タイポの修正を OTA で行うことで問題になることはありません。Appleが問題視するのは、審査時はある状態だったアプリが、その後別のものに変貌してしまうパターンです。これはガイドライン 2.5.2 だけでなく、2.3.1(隠れた機能や未記載の機能の禁止)にも該当します。

実践的なアプローチ:

  • 本来提出するはずだったものを、より速く配信するだけです。
  • すべてのアップデートを、App Store の説明文に記載された目的の範囲内に収めてください。
  • 大規模な新機能のリリースは App Review を通じて行い、リリース間の修正や改善には Live Update を活用しましょう。
  • 審査員が確認していない挙動を有効にするために、live update を決して使用しないでください。

そのルールに従えば、Live UpdateはiOSアプリのリリースで当たり前に使われるものです。React NativeのチームはCodePushやExpo Updatesで何年も前から行っていますし、CapacitorのチームはCapgoで行っています。

iOSでそれができるスタックはどれですか?

iOSアプリでOTAアップデートを配信できるかは、1つの問いにかかっています。アプリのロジックは実行時に解釈されるか? JavaScriptなどのインタープリタ型codeなら可能です。Swift、Objective-C、C++のようにマシンcodeにコンパイルされるものは不可です。FlutterのようなAOTコンパイル型フレームワークは、インタープリタ経由でのみ可能です。

スタック別のiOS live update互換性

スタック iOSでcodeが動作する仕組み ライブアップデートは可能? ツール
Capacitor WKWebView (WebKit) 上の JavaScript, HTML, CSS はい Capgo
Ionic (Capacitor で) Capacitor と同様 はい Capgo
Cordova WKWebView 上の JavaScript はい Capacitor への移行後の Capgo, レガシーな Cordova プラグイン
React Native / Expo Hermes または JavaScriptCore 上の JavaScript bundle はい、JavaScriptのみ Expo Updates、自前運用のCodePush代替案
NativeScript 組み込みエンジン上のJavaScript はい、JavaScriptのみ 限定的、主に自作によるもの
Flutter DartをマシンコードにAOTコンパイルしたcode インタプリタ経由のみ Shorebird (パッチ用Dartインタプリタ)
ネイティブのSwift / Objective-C マシンcode ネイティブ code は不可、WebKit/JavaScriptCore 上の JS は可 リモートコンフィグとサーバー駆動 UI
.NET MAUI / Xamarin マシン code に AOT コンパイルされた C# いいえ リモートコンフィグのみ
Kotlin / Compose Multiplatform マシン code にコンパイルされた Kotlin/Native いいえ リモートコンフィグのみ
Unity / Unreal IL2CPP または C++ でコンパイルされた C# code はNG、コンテンツならOK アセットバンドル、スクリプトコンテンツ (Lua)
Webラッパー (リモートURL) WebViewで読み込まれるウェブサイト 常にライブ更新可能だが、審査リスクあり 不要、下記の注釈を参照

Capacitor、Ionic、Cordova:完全にカバー

アプリのWeb UIとJavaScriptのビジネスロジックは、 WKWebView次で実行されます。ネイティブシェルとプラグインはネイティブのままです。Apple Developer Program License Agreementのセクション3.3.1(B)では、ダウンロードされた解釈可能な code は、アプリの主な目的を維持し、code のようなストアを作成せず、OSのセキュリティを回避しない場合にのみ許可されています。ガイドライン4.7では、HTML5やJavaScriptのミニアプリを提供するアプリを別途規定しており、追加の要件があります。

live update はWebバンドルを置き換えます。ネイティブシェル、プラグイン、権限はAppleが審査したものと同じです。そのため、Capgo は設計上コンプライアンスを遵守しています。たとえ意図したとしても、ネイティブの code を変更することはできません。新しいネイティブプラグインや権限の追加には、引き続きApp Storeでのリリースが必要です。

React NativeとExpo:JavaScriptはOK、ネイティブモジュールはNG

React Nativeは、HermesまたはJavaScriptCore上でJavaScriptバンドルを実行します。そのバンドルは解釈可能な code であり、OTAで更新可能です。これはExpo UpdatesやMicrosoft CodePush(2025年に終了)が実現しようとしていたことです。 CodePushから移行するチームが 代替手段を求めています。

ネイティブモジュールやReact Nativeのバージョンを変更する場合、 Info.plist 新しいバイナリが必要です。

Flutter: インタープリタ経由のみ可能

iOSでは、FlutterはDartを事前にARMマシン用 code にコンパイルします。新しいマシン用 code のダウンロードは禁止されているため、標準のFlutterではlive updatesを利用できません。Shorebirdは、パッチを当てたDart code をインタープリタで実行することでこれを解決し、解釈可能な code の例外規定に適合させています。詳細は Flutterアプリ向けのlive updates.

Native Swift, .NET MAUI, Kotlin Multiplatform: ネイティブ code 更新は不可

これらのスタックはネイティブなマシン用 code を生成します。そのため、代替となるネイティブ code をダウンロードすることはできません。ただし、Appleの条件を満たしていれば、JavaScriptCore経由のJavaScriptのような、解釈可能な code をダウンロードして実行することは可能です。また、OTAで変更可能なものとして、リモート設定、レビュー済みの機能のフィーチャーフラグ、サーバー駆動UI、画像、テキストなどがあります。

Unityおよびゲームエンジン: コンテンツはOK、code はNG

ゲームの code はコンパイルされています。アセットバンドル(レベル、アート、バランス調整データ)はコンテンツであり、ダウンロード可能です。Luaのような組み込みスクリプト言語は解釈可能な code であり、JavaScriptと同じルールに従います。

リモートURLラッパー: 実現可能だが、審査のリスクあり

WebViewでウェブサイトを表示するだけのアプリは、サイトをデプロイするたびに「更新」されていることになります。問題はガイドライン2.5.2ではなく、4.2(最小限の機能性)です。Appleは単にウェブサイトをフレーム内に表示しているだけのアプリをリジェクトします。Capacitorでウェブアプリをバンドルし、ネイティブ機能を追加してLive Updateを活用することで、この問題を回避できます。

iOSにおいて、どのスタックでも不可能なこと

どのフレームワークを使用していても、live updateでは以下ができません:

  • ネイティブのcode、フレームワーク、または動的ライブラリのダウンロード
  • 新しい権限(Permissions)やEntitlementsの追加
  • App Storeの掲載内容と異なるアプリへの変更
  • App Review時に隠していた機能の有効化

次のステップ

レビュー待ちではなく、今日中に修正をリリース

Capgo Live Updates チャネル、ロールバック、差分アップデート、エンドツーエンド暗号化を備え、JavaScript、HTML、CSSの変更を数分でCapacitorアプリにpushできます。オープンソースでセルフホストも可能です。

bunx @capgo/cli@latest init

最初のアップデートを送信するには、 クイックスタート に従ってください。

Capacitor アプリ向けの Live Updates

Web レイヤーのバグが本番で発生したら、App Store の審査を何日も待たずに Capgo で修正を配信しましょう。ネイティブの変更は通常の審査フローに残したまま、ユーザーはバックグラウンドでアップデートを受け取れます。

最新のブログ記事

Capgoは、真にプロフェッショナルなモバイルアプリを作るために必要な最高のインサイトを提供します。