コンテンツにスキップ

ネイティブと Cocos のハイブリッド開発

本ドキュメントでは、ネイティブと Cocos のハイブリッド開発シナリオにおける SDK 導入方法について説明します。対象は、Android/iOS のネイティブページを中心としつつ、一部のページで Cocos Creator を使用するアプリです。ネイティブホストがオブザーバビリティ SDK の初期化を担当し、Cocos は自身のページが表示されている間のみ、Cocos レイヤーの RUM View、自動収集、Session Replay の画面キャプチャを引き継ぎます。

現在の自動管理範囲は、独立した Cocos Activity または UIViewController のみをサポートしています。ネイティブページの一部領域に埋め込まれた Cocos Surface では、ホストが RUM View を手動で管理する必要があり、ホストページの View を自動的に置き換えて復元することはできません。

導入の境界

独立した Cocos アプリと、ネイティブと Cocos のハイブリッド開発アプリでは、異なる初期化エントリポイントを使用します:

シナリオ 初期化エントリポイント 設定の所有者 終了方法
アプリ全体が Cocos によって駆動される guanceSdk.start() Cocos guanceSdk.shutdown()
ネイティブアプリの一部で Cocos を使用 ネイティブ SDK の初期化後に guanceSdk.attach() を呼び出す ネイティブホスト Cocos ページが guanceSdk.leaveCocos() を呼び出す

start()attach() は排他的です。Hybrid モードに入ると、SDK は Cocos 側の mobile.start()rum.start()logger.start()trace.start()replay.start()replay.stop()shutdown() の呼び出しを拒否し、ネイティブホストが保持する SDK の重複初期化やシャットダウンを防ぎます。ユーザーバインド、RUM イベント、ログ書き込み、Trace Header などの非初期化 API は引き続き bridge 経由で使用できます。

このページの Replay サンプルでは、withSessionReplay(baseSdk) が返す guanceSdk を使用します。まずアプリ導入に従って、同じバージョンの 2 つの npm パッケージをインストールし、--replay を指定して実行してください。具体的なインポート方法は、後述のCocos ライフサイクルの導入を参照してください。Cocos の RUM、Log、Trace のみを収集する場合は、基本パッケージの attach({ autoTrack }) を直接使用でき、Replay のインストールは不要です。

attach() は Cocos のキャプチャと自動収集の設定のみを受け取ります:

guanceSdk.attach({
  replay: {
    captureFps: 1,
    maxImageDimension: 720,
    touchPrivacy: 'show',
  },
  autoTrack: {
    scenes: true,
    actions: true,
    errors: true,
    network: true,
  },
});

attach()FTCocosBridge を通じてネイティブホストがすでに SDK を初期化していることを確認し、ネイティブのグローバルコンテキストに sdk_package_cocos のバージョン情報を追加します。データ送信先アドレス、RUM App ID、サンプリングレートは渡されず、ネイティブモジュールも再初期化されません。

Replay と RUM のサンプリング判断、セッション、データストレージ、グローバル設定は引き続きネイティブ SDK が管理します。

touchPrivacy は、Cocos ページの Replay でタッチ位置を記録するかどうかのみを制御します。ネイティブページでは引き続きホストの Session Replay プライバシー設定が使用されます。選択可能な値、デフォルトの動作、プライバシーに関する注意事項は Cocos Creator セッションリプレイ を参照してください。

ネイティブホストは現在の SDK バージョン構成を使用します。対応する Android/iOS SDK は Hybrid Replay をサポートしており、Cocos ページへの進入時と離脱時に、ネイティブと Cocos の画面キャプチャを切り替えられます。

ネイティブホストの初期化

Cocos npm/ZIP インストールパッケージには TypeScript API、Creator 拡張機能、Android/iOS の FTCocosBridge がすでに含まれているため、ホストプロジェクトに初期化ヘルパークラスを追加する必要はありません。オプションの Replay パッケージは FTCocosReplayBridge と画像処理コードを提供します。2 つの Bridge は、ホストが使用する同じバージョンのネイティブ SDK を共有します。

Android/iOS アプリは、それぞれのネイティブ SDK の導入要件に従って、必要な RUM、Logger、Trace、Session Replay を初期化し、最初の guanceSdk.attach() 呼び出しまでに初期化を完了してください。具体的な設定は以下を参照してください:

iOS ホストは SPM 導入の説明 に従って依存関係の管理方法を切り替えることができます。ホストと Cocos Bridge は同じネイティブ SDK を使用してください。CocoaPods と SPM の両方で導入しないようにしてください。リポジトリ内の Hybrid サンプルは同じ cocos-sdk.config.json を読み取ります。ローカル拡張機能を更新して iOS プロジェクトを再生成した後、サンプル本来の native:install コマンドを実行します。インストーラーは SPM を介して Bridge と HybridSampleHost を関連付けます。ホストの初期化と Cocos の attach() フローは変更されません。

独立した Cocos Activity または UIViewController の場合、Hybrid 導入のためにネイティブ SDK の初期化フローを書き換える必要はありません。Cocos ページの表示時と離脱時に、それぞれ enterCocos()leaveCocos() を呼び出して、RUM View と Replay のキャプチャ元を切り替えます。

Session Replay を有効にする場合、ネイティブホストはデフォルトのネイティブ recorder モードで初期化する必要があります。external-only に設定しないでください。Cocos 側では attach() に画面キャプチャ設定のみを渡します。

Android ネットワーク収集の推奨設定

HttpURLConnection の自動収集は、Android Agent 1.7.6-alpha03 と Android Gradle Plugin 1.3.9-alpha01 の組み合わせからサポートされます。どちらのコンポーネントもこのバージョン以上を使用する必要があります。

Cocos の autoTrack.network: true を有効にし、ネイティブの HttpURLConnection 自動収集はオフのまま(デフォルトでオフ)にすることを推奨します。ネイティブホストで RUM を初期化する前に設定します:

rumConfig.setEnableTraceUserResource(true);
rumConfig.setEnableHttpURLConnectionResource(false);

これにより、Cocos の JS レイヤーがネットワークリクエストを収集しつつ、ネイティブの Resource 全体のスイッチは維持され、ホストの OkHttp などのリクエストに使用できます。

競合の原因:Android 上の Cocos JS XHR は、基盤でエンジンの HttpURLConnection ラッパーを経由します。Creator 2 では Cocos2dxHttpURLConnection、Creator 3 では CocosHttpURLConnection が対応します。JS とネイティブの HttpURLConnection 収集を同時に有効にすると、同じリクエストに対してそれぞれ Resource が報告されます。2 つのレイヤー間に重複排除はなく、Trace Header を同時に注入すると、Resource の Trace 情報がサーバーが受信したリクエストヘッダーと一致しなくなる可能性があります。

iOS ネットワーク収集の推奨設定

iOS SDK 1.6.8-alpha.5 で、NSURLConnection の自動 Resource 収集と Trace 関連付けが追加されました。FTRumConfig.enableTraceURLConnectionResourceFTTraceConfig.enableAutoTraceURLConnection でそれぞれ有効にし、デフォルトはどちらも NO です。これらのスイッチは、NSURLSession 用の enableTraceUserResource および enableAutoTrace とは独立しています。バージョンをアップグレードするだけ、または既存のスイッチをオンにするだけでは、NSURLConnection 収集は有効になりません。

現在のエンジンの実際のリクエスト実装を確認してから、収集レイヤーを選択してください:

iOS のリクエストパス ネイティブ Resource スイッチ ネイティブ Trace スイッチ
Creator 2.4.9 / 2.4.15 XHR:NSURLConnection enableTraceURLConnectionResource enableAutoTraceURLConnection
Creator 3.8.8 XHR:NSURLSession enableTraceUserResource enableAutoTrace

同じ Cocos XHR が autoTrack.network と対応するネイティブ Resource 収集の両方でカバーされると、JS とネイティブレイヤーがそれぞれ Resource を報告します。現在、レイヤー間の重複排除はありません。Trace Header が同じでも、Resource が重複排除されたことにはなりません。NSURLConnection 収集は認識できる既存の Trace Header を再利用するため、Android のように両方を有効にすると Trace Header が上書きされるという結論をそのまま適用しないでください。

Creator 2 では、Cocos の autoTrack.network: true を維持し、ネイティブの専用スイッチをオフにしたまま、ホストの独立した NSURLSession 収集を残すことを推奨します:

rumConfig.enableTraceUserResource = YES;
rumConfig.enableTraceURLConnectionResource = NO;
traceConfig.enableAutoTrace = YES;
traceConfig.enableAutoTraceURLConnection = NO;

ネイティブレイヤーで NSURLConnection を収集する場合は、ネイティブ RUM / Trace の初期化前に上記 2 つの専用スイッチを YES に設定し、Cocos の autoTrack.network をオフにします。他のリクエストを JS で収集する必要がある場合は、ネイティブの resourceUrlHandler を使用して URL ごとに重複するリクエストを除外し(YES を返すと Resource を収集しない)、Trace 注入ポリシーは別途確認してください。Resource フィルタリングによって Trace 注入は無効になりません。

Creator 3.8.8 / iOS の実際の XHR 比較では、JS とネイティブの両方を有効にすると、HTTP リクエスト 3 回に対して Resource が 6 件生成されました。どちらか一方のみを有効にした場合は、どちらも 3 件です。両方有効にした場合、2 件のレコードの Trace ID / Span ID は異なり、サーバーが受信するのはネイティブレイヤーが注入したリクエストヘッダーです。

Creator 3.8.8 では、NSURLConnection の専用スイッチをオフにしても、NSURLSession パスの重複は避けられません。ホストで NSURLSession 自動収集が有効な場合、Cocos の autoTrack.networkfalse に設定し、ネイティブレイヤーに統合して収集させることができます。JS 収集を残す場合は、ネイティブの Resource 収集が同じリクエストをカバーしないようにしつつ、ホストの他のネットワークリクエストの収集要件も維持する必要があります。

startResource / stopResource / addResource を手動で呼び出す場合も、ネイティブの自動収集と同じリクエストを避ける必要があります。JS SDK でラップされていない XHR メソッドを保存して呼び出しても、JS の自動収集を迂回できるだけで、ネイティブ収集は迂回できません。

検証時は、各リクエストに一意の request_id を追加し、実際の HTTP リクエスト数とアップロードされた Resource 数を 1 対 1 で対応付けます。HTTP ステータス、所要時間、Trace ID / Span ID も確認してください。ページにリクエスト成功と表示されても、Resource の自動収集が成功したことにはなりません。

Cocos ライフサイクルの導入

以下示例は Creator 3 を使用します。Creator 2 では、基本パッケージと Replay パッケージのインポートパスを両方 /creator2 に変更する必要があります。

import { guanceSdk as baseSdk } from '@cloudcare/cocos-sdk/creator3';
import { withSessionReplay } from '@cloudcare/cocos-session-replay/creator3';

export const guanceSdk = withSessionReplay(baseSdk);


export function attachObservability(camera?: unknown): void {
  if (camera) guanceSdk.setReplayCamera(camera);
  guanceSdk.attach({
    replay: {
      captureFps: 1,
      maxImageDimension: 720,
      touchPrivacy: 'show',
    },
    autoTrack: {
      scenes: true,
      actions: true,
      errors: true,
      network: true,
    },
  });
}

export function enterCocos(viewName = 'Cocos'): void {
  guanceSdk.enterCocos({ viewName });
}

export function leaveCocos(): void {
  guanceSdk.leaveCocos();
}

Cocos ページコンポーネントでライフサイクルをバインドします:

onLoad(): void {
  attachObservability();
}

onEnable(): void {
  enterCocos('Game');
}

onDisable(): void {
  leaveCocos();
}

onDestroy(): void {
  leaveCocos();
}

デフォルトでは、現在のシーンで見つかった最初の Camera が使用されます。複数の Camera があるプロジェクトでは、リプレイに使用する Camera を attachObservability(camera) に渡してください。メインの Camera を切り替えた後は、再度 guanceSdk.setReplayCamera(camera) を呼び出します。

attach()、すでに進入した後の enterCocos()、すでに離脱した後の leaveCocos() はすべて冪等操作です。破棄パスでは、異常終了や重複コールバックをカバーするために leaveCocos() を再度呼び出すことができます。

recorder の切り替えに失敗した場合、関連する呼び出しはエラーをスローします。Native SDK のバージョンや初期化の問題を除外した後、現在のライフサイクルメソッドを再度呼び出して進入または離脱を完了してください。ネイティブホストが保持するインスタンスをクリーンアップするために shutdown() を使用しないでください。

autoTrack.scenesfalse の場合、enterCocos() には viewName を渡す必要があります。SDK が手動で Cocos View を作成します。シーン自動追跡を有効にすると、viewName は進入時の初期 View として使用され、以降のシーン切り替えはシーン名が引き継ぎます。

View と Replay の所有権

ページ切り替え時の所有権の順序は次のとおりです:

タイミング RUM View Session Replay のキャプチャ元
ネイティブページが表示されている ネイティブの自動または手動 View ネイティブ recorder
enterCocos() を呼び出す 存在する可能性があるコンテナ View を停止し、Cocos View を開始する ネイティブ recorder を一時停止してから、Cocos Canvas のキャプチャを開始する
Cocos ページが表示されている Cocos シーンまたは指定された View Cocos external recorder
leaveCocos() を呼び出す Cocos View を停止する Cocos のキャプチャと処理中のフレームを停止してから、ネイティブ recorder を再開する
ネイティブページに戻る ネイティブの自動または手動 View ネイティブ recorder

ネイティブの全画面ポップアップ、ログインページ、その他のページは、Cocos ページを破棄していなくても、Cocos を完全に覆う場合は、表示前にビジネスのライフサイクルを介して Cocos に leaveCocos() を呼び出させる必要があります。ポップアップが閉じて Cocos が再び表示されたら enterCocos() を呼び出します。Cocos のレンダリングを一時停止するだけでは、RUM View と Replay の所有権の移行は完了しません。

同時に有効な RUM View は 1 つ、Replay のキャプチャ元は 1 つだけである必要があります。ネイティブの自動追跡と Cocos の自動追跡の両方で専用の Cocos コンテナを記録させないでください。また、attached Replay を制御するために guanceSdk.replay.start()stop() を手動で呼び出さないでください。

埋め込み型 Cocos Surface

Cocos がネイティブの Activity または UIViewController の一部領域のみを占める場合、現在の Native SDK はホストコントローラーの View を自動的に一時停止・再開できません。このシナリオでは、ホストがそのページのネイティブ自動 View 追跡をオフにし、手動の RUM API を使用してホスト View と Cocos View の前後関係を管理する必要があります。進入前にホスト View を終了し、離脱後にホスト View を再開します。

Native SDK がスコープ化された View の抑制・復元インターフェースを提供するまでは、Cocos エンジンの一時停止・復元コールバックだけを根拠に View の所有権を推定しないでください。

導入の検証

Android と iOS の実機で、それぞれ少なくとも 3 回 ネイティブページ -> Cocos ページ -> ネイティブページ のフローを実行することを推奨します:

  1. Cocos に進入する前に毎回 enterCocos() を呼び出し、離脱または完全にカバーされる前に leaveCocos() を呼び出します。
  2. ネイティブログに、SDK の重複初期化、Hybrid recorder インターフェースの欠如、Replay がネイティブモードで初期化されていない、といったエラーがないことを確認します。
  3. RUM エクスプローラーで、各時間帯に View が 1 つだけであること、Cocos シーンに同名のネイティブコンテナ View がないことを確認します。
  4. Session Replay を開き、ネイティブページと Cocos ページが連続して再生できること、境界に二重画面、空白フレーム、離脱後の Cocos 残存フレームがないことを確認します。
  5. Cocos の Action、Resource、Error、および RUM に関連付けられた Log と Trace データを確認します。

よくあるエラー:

エラー 対処方法
The native host must install the native SDK before FTCocosSDK.attach() ネイティブ SDK の初期化を attach() より前に移動します。
The native host must initialize the native SDK before FTCocosSDK.attach() iOS ネイティブ SDK の初期化を attach() より前に移動します。
The native host owns ... in Hybrid mode Cocos 側の SDK/RUM/Logger/Trace の初期化または停止呼び出しを削除し、ネイティブの初期化と attach() のみを残します。
Hybrid Replay is managed by enterCocos() and leaveCocos() guanceSdk.replay.start()stop() を直接呼び出さず、Cocos ページのライフサイクルで制御します。
does not support Hybrid recorder switching 現在の SDK バージョン構成 に従ってネイティブ依存関係を確認し、ネイティブプロジェクトを再生成・再コンパイルします。
Session Replay must be initialized by the native host in native recorder mode ネイティブホストで Replay を初期化し、external-only モードをオフにします。
Call attach() before enterCocos() Cocos ページの読み込み段階で attach() を必ず 1 回呼び出します。
enterCocos.viewName is required when scene tracking is disabled viewName を渡すか、autoTrack.scenes を有効にします。

フィードバック

このページは役に立ちましたか?