メインコンテンツへスキップ

Capgo における Live Updates の仕組み

Capgo におけるライブアップデートの技術的な実装を深掘りし、iOS と Android の両方で内部の仕組みがどう動作するかを理解します。

「CapgoにおけるLive Updateの仕組み」Capgo ブログイラスト

Capgo における Live Updates の理解

Capacitor Live Updates (OTA) アプリ内のWeb bundleを置き換えることで、ストアのバイナリを出すことなくJavaScript、HTML、CSSの変更を配信できます。Live UpdatesはCapacitorアプリで最も強力な機能の一つであり、App Storeへの申請なしにリアルタイムのアップデートを可能にします。では、Capgoがこの機能をどう実装しているのか、詳しく見ていきましょう。

コアコンセプト

Capacitorアプリは、主に2つのレイヤーで構成されています:

  1. Webレイヤー: WebViewで読み込まれるHTML、CSS、JavaScriptファイル
  2. Nativeレイヤー: プラットフォーム固有のcode(AndroidはJava/Kotlin、iOSはSwift)

これらのファイルはアプリのバイナリにコンパイルされないため、Capgoのlive updateシステムは実行時にWebレイヤーを置き換えることで動作します。

技術的な実装

Capacitorにおけるサーバーパス

Capgoは、2つの重要なパスを管理しています:

  • 現在のサーバーパス: 現在WebViewにロードされているファイルを指します
  • 次のサーバーパス: 次回のアプリ再起動時にロードされるファイルを指します

Androidでの実装

Androidでは、Capgo は以下の方法でパスを管理します:

// Store next server path
private void setNextCapacitorServerPath(String path) {
    SharedPreferences prefs = context.getSharedPreferences("CapWebViewSettings", Activity.MODE_PRIVATE);
    SharedPreferences.Editor editor = prefs.edit();
    editor.putString("serverBasePath", path);
    editor.apply();
}

// Update current path and reload
private void setCurrentCapacitorServerPath(String path) {
    bridge.setServerBasePath(path);
    bridge.reload();
}

iOSでの実装

iOSでは、パスは以下の方法で管理されます:

// Store next server path
private func setNextCapacitorServerPath(path: String) {
    KeyValueStore.standard["serverBasePath"] = path
}

// Update current path
private func setCurrentCapacitorServerPath(path: String) {
    bridge.viewController.setServerBasePath(path: path)
}

セキュリティ対策

Capgo はエンドツーエンド暗号化による軍事レベルのセキュリティを実装しており、開発からデプロイまでアプリのアップデートを完全に保護します。当社の暗号化システムは、従来の code 署名にとどまらず、真のゼロ知識セキュリティを提供します。

エンドツーエンド暗号化アーキテクチャ

  1. エンドツーエンド暗号化(E2EE): すべてのアップデート bundle は、開発環境を離れる前に AES-256-GCM で暗号化されます。この軍事レベルの暗号化により、配信プロセス全体を通じてアプリのアップデートのプライバシーと安全性が完全に保たれます。

  2. ゼロナレッジアーキテクチャ:他のOTA更新ソリューションが更新を署名するだけなのに対し、Capgo は真のゼロナレッジ暗号化を採用しています。つまり:

    • 更新内容はアップロード前に暗号化されます
    • Capgo サーバーは暗号化されたデータのみを保存します
    • 復号はエンドユーザーのデバイス上でのみ行われます
    • 中間者による更新内容へのアクセスは不可能です
  3. 安全な鍵管理:

    • 暗号化鍵はCI/CD環境内で安全に生成・保存されます
    • 秘密鍵はCapgoのサーバーに一切触れません
    • 各アプリバージョンで独自の暗号化鍵を使用できます
    • セキュリティ強化のための鍵ローテーションに対応

詳細なガイドで暗号化システムについて詳しく見る: Capgo Live Updatesにおけるエンドツーエンド暗号化

アップデートのセキュリティプロセス

  1. アップロード前の暗号化:

    • 更新はCI/CDパイプライン内で暗号化されます
    • 各ファイルが個別に暗号化されます
    • メタデータも暗号化され、完全なプライバシーを確保します
  2. セキュアストレージ:

    • 暗号化されたバンドルは Capgo のグローバル CDN に保存されます
    • プレーンテキストのデータはサーバーに一切触れません
    • サーバーが侵害された場合でも、データは安全に保たれます
  3. セキュアな配信:

    • 更新は暗号化されたチャネルを通じて配信されます
    • 各アプリインスタンスが暗号化の完全性を検証
    • 復号失敗時の自動リトライメカニズム
  4. クライアントサイドのセキュリティ:

    • インストール前にアップデートを検証
    • 復号失敗時に自動ロールバックを実行
    • アプリの保護されたストレージへの安全なキー保存

この包括的なセキュリティアプローチにより、アプリのアップデートは以下の脅威から保護されます:

  • 中間者攻撃
  • サーバー側の侵害
  • 不正な変更
  • リプレイ攻撃
  • コンテンツの改ざん

アップデートのライフサイクル

Capgo の更新プロセスは、デフォルトで自動実行されるよう設計されています。自動プロセスの仕組みは以下の通りです:

1. アップデートの自動チェック

プラグインは、以下の状況で自動的に更新を確認します:

  • アプリ起動時

この動作は autoUpdate 設定で制御されます:

// capacitor.config.json
{
  "plugins": {
    "CapacitorUpdater": {
      "autoUpdate": true // Enable automatic updates
    }
  }
}

また、 getLatest()

2. 自動ダウンロード

新しいバージョンが検出された場合、 autoUpdate が有効な場合:

  1. ダウンロードが自動的に開始されます
  2. 進捗は内部で管理されます
  3. ダウンロード失敗時はアプリ起動時に自動リトライ
  4. ダウンロード成功時はアプリのストレージに保存

以下のイベントでプロセスを監視できます:

CapacitorUpdater.addListener('download', (info: DownloadEvent) => {
  console.log('Auto-download progress:', info.percent);
});

CapacitorUpdater.addListener('downloadComplete', (info: DownloadCompleteEvent) => {
  console.log('Auto-download complete:', info.bundle);
});

3. 自動インストール

インストールのタイミングは設定によって異なります:

// capacitor.config.json
{
  "plugins": {
    "CapacitorUpdater": {
      "autoUpdate": true,
      "directUpdate": false // install update on app backgrounding
      "resetWhenUpdate": true, // reset live updates on native update (true by default)
      "autoDeleteFailed": true, // Auto cleanup failed updates (true by default)
      "autoDeletePrevious": true // Auto cleanup old versions (true by default)
    }
  }
}

インストールが実行されるのは:

  • 以下の条件で即時実行: directUpdate が true の場合
  • 以下の条件で、次回アプリがバックグラウンドに移行したとき: directUpdate が false の場合
  • インストール失敗時は自動ロールバック

また、プラグインはストレージも自動で管理します:

  • 失敗したアップデートを削除する条件: autoDeleteFailed が true の場合
  • 古いバージョンをクリーンアップする条件: autoDeletePrevious が true の場合

アップデートの遅延

遅延条件を使って、アップデートのインストールタイミングを制御できます:

// Delay until app goes to background
await CapacitorUpdater.setDelay({
  kind: 'background'
});

// Delay until specific date
await CapacitorUpdater.setDelay({
  kind: 'date',
  value: '2024-03-20T10:00:00.000Z'
});

// Delay until next native version
await CapacitorUpdater.setDelay({
  kind: 'nativeVersion'
});

// Multiple conditions
await CapacitorUpdater.setMultiDelay({
  delayConditions: [
    {
      kind: 'background'
    },
    {
      kind: 'date',
      value: '2024-03-20T10:00:00.000Z'
    }
  ]
});

利用可能な遅延条件:

  • バックグラウンド: アプリがバックグラウンドに移行したときにインストール
  • 日付: 指定した日時以降にインストール
  • ネイティブバージョン: 次回のネイティブアップデート後にインストール
  • kill: アプリがkillされた後にインストール

主な活用シーン:

  • オフピーク時間帯へのアップデート予約
  • ユーザーのアクティビティに合わせた更新
  • スムーズなアップデート体験の提供
  • 重要なタスク中の割り込み防止

アップデートの状態

自動処理の間、bundleは以下の状態に遷移します:

  1. ダウンロード中: ダウンロード中
  2. 保留中: ダウンロード完了、インストール待ち
  3. 成功:更新がインストールされ、有効になりました
  4. エラー:更新に失敗しました(自動ロールバックがトリガーされます)

ストアのコンプライアンス

Apple App Store ✅

Live Update は Apple App Store のポリシーに完全に準拠しています。Apple Developer Program License Agreement には以下のように記載されています:

「インタプリタで実行されるcodeはアプリケーションにダウンロードできますが、そのcodeが次の条件を満たす場合に限ります: (a) App Storeに提出した際のアプリケーションの意図された目的および宣伝されている目的と矛盾する機能や機能性を提供することで、アプリケーションの主な目的を変更しないこと、(b) 他のcodeやアプリケーション向けのストアまたはストアフロントを作成しないこと、(c) OSの署名、サンドボックス、その他のセキュリティ機能をバイパスしないこと。」

Capgo の更新は、すべてのプラットフォームのセキュリティ境界を尊重しながら、Web レイヤーのみを変更します。

Google Play Store ✅

Live Update は Google Play ポリシーに準拠しています。Device and Network Abuse ポリシーには特に以下のように記載されています:

「この制限は、仮想マシンまたはインタープリタ上で動作し、そのいずれかがAndroid APIへの間接的なアクセスを提供する code には適用されません(WebViewやブラウザ上のJavaScriptなど)。」

Capgo は WebView のコンテンツのみを更新するため、これらの許可されたガイドラインの範囲内にあります。

ベストプラクティス

  1. 段階的なロールアウト:段階的にアップデートをデプロイ
  2. バージョン管理:デプロイ済みバージョンをすべて追跡
  3. ロールバック対応:問題からの迅速な復旧
  4. 差分アップデート: 変更されたファイルのみをダウンロード

Live Updates の活用シーン

最適なユースケース:

  • バグ修正
  • UI の改善
  • コンテンツの更新
  • フィーチャートグル

不向きなケース:

  • Native code の変更
  • メジャーバージョンのアップデート
  • ネイティブ変更を伴うセキュリティパッチ

次へ: Capgo での Live Updates の仕組み

使用している場合 Capgo における Live Updates の仕組み ネイティブプラグインの作業を計画するには、次と連携してください: Capgo プラグインディレクトリ Capgo プラグインディレクトリのプロダクトワークフローについては、 Capgo による Capacitor プラグイン Capgo による Capacitor プラグインの実装詳細については、 プラグインの追加または更新 プラグインの追加または更新に関する実装詳細については、 Ionic Enterprise プラグインの代替案 Ionic Enterprise Plugin Alternatives のプロダクトワークフロー、および Capgo Native Build Capgo Native Builds のプロダクトワークフローについては、

Capacitor アプリ向けの Live Updates

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

最新のブログ記事

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