投影の契約とライフタイム
組み込みの契約とプラットフォームの制約を確認するためのリファレンスです。まず概念と組み込み方式の選択で、Engineが対象のUIに適しているか判断します。ネイティブ初期化で必須入力、任意の設定、高度なAPIを区別してから、Capacitor、Cordova、レンダラーのいずれかのガイドに従ってください。
このページではDOMのライフタイム、投影先の優先順位、ホストの要件、ネイティブの適格性を扱います。キャプチャの詳細はプラットフォームの制約、表示意図の属性は投影状態、HTML/Ionicのホストはコンテナの対応状況を参照してください。
画面遷移をまたいで何を維持すべきか判断する際に、この契約を使います。たとえば、ネイティブの復元応答がまだ届いていない間にモーダルが閉じ、フレームワークがページのDOMを置き換える場合です。古い応答が退場済みページのコントロールを再表示してはいけません。以下のライフタイムと投影先のルールが、その境界を定めます。
DOMとページのライフタイム
ネイティブ登録はJavaScriptフレームワークに依存しません。セレクターは現在のドキュメント内の1つのフォールバックコンテナを識別します。コンテナは登録後に現れてもかまいません。フレームワークがコンテナを削除・置換すると、Engineは古い投影を破棄し、現在一致する要素にバインドします。離脱したコンテナの保留中のドラッグやネイティブ描画の確認応答が、置換先を待たせてはいけません。同じ要素を別の親へ移すとスクロールバインディングが更新され、プラグインによる再登録は不要です。
HTML全体のナビゲーションは、新しいドキュメントとランタイムセッションを作成します。ネイティブ登録は新しいドキュメントにランタイムをインストールし、プラグインが明示した投影先を維持します。画像と応答は元のドキュメントに属します。フレームワークのページイベントごとに登録を作り直すのではなく、ネイティブレンダラーのライフタイム中は保持してください。
これらのルールは、セレクターに基づくネイティブ登録に適用されます。低レベルのcreateWebProjectionScope(element)は意図的に特定の要素にバインドします。要素を変更した際のスコープの置換は、引き続きレンダラーの責務です。
Engineは、すべてのフレームワークの画面遷移やモーダルの意味をDOM変更から推定できません。それらの遷移には既存の投影通知を使い、必要なら明示的なオーバーレイ連携を追加します。Ionic対応は任意であり、通常のDOMライフタイム処理には不要です。フレームワーク固有のイベントは自動では追加されません。ネイティブビューの作成、レイアウト制約、SDKのライフサイクルは引き続きプラグインが所有します。
投影の契約
通知が指定するのはキャプチャの方法ではなく、サーフェスの表示先です。プラグインが投影状態の別コピーを持たなくても、Engineがプラットフォームごとのハンドオフを選択します。
| 意図する投影先 | 必要な動作 |
|---|---|
native |
確認済みのジオメトリで操作可能なネイティブビューを表示します。移動中は、対応するネイティブ追従または準備済み画像を使います。 |
web |
ネイティブ投影を取り除いて、上を覆うWebレイヤーの下にネイティブコンテンツを保ちます。準備済み画像またはプラグインのWebフォールバックを使います。 |
none |
ネイティブコンテンツ、投影画像、フォールバックコンテンツを退場させます。後から来る更新・キャプチャのコールバックで再表示してはいけません。 |
オーバーレイの被覆は、一時的にnativeをwebへ変えられますが、noneは上書きしません。キャプチャの失敗で意図した投影先は変わりません。failedFallback: nativeは、ネイティブ配置を自ら維持する利用側にのみ有効で、明示的なweb、none、オーバーレイの被覆を上書きしません。
Engineは画像の準備完了と復元の確認応答を管理します。代替ピクセルの準備前にネイティブのピクセルを隠したり、ネイティブの復元成功前に代替ピクセルを破棄したりしてはいけません。位置だけの移動では準備済みコンテンツを再利用し、外観、サイズ、レンダラーの識別情報が変わると無効化します。画像がない場合、遷移中のキャプチャを待たず、宣言したフォールバックを直ちに使います。
登録と通知の転送は、起動と再接続をまたいで最新の意図を維持し、業務イベントを再実行しません。破棄すると登録とキャッシュ画像を退場させます。通知は意図であり、完了の保証ではありません。非表示の完了を約束するAPIは、DOMとネイティブサーフェスの要件で説明する、明示的な退場完了の確認応答を待つ必要があります。
CSSの可視性を確認する既存レンダラーは、npmパッケージのgetUnprojectedVisibility(element)を呼べます。Engineの非表示ルールを除外して、現在の指定・継承された可視性を読み取り、戻る前に投影の所有権を復元します。利用側のプラグインでEngineのマーカー属性から投影の所有権を推定したり、それらを変更したりしないでください。Engine所有の変更をレンダラーの無効化から除外する方法は、レンダラーのDOM連携を参照してください。このヘルパーはスタイルを読み取り、属性監視を起動する場合があります。計測や転送のコストをなくすものではありません。
DOMとネイティブサーフェスの要件
projectionSelectorは必須です。有効なCSSセレクターを使い、投影開始時に存在する1つのコンテナに一致する必要があります。ID、クラス、属性、子孫セレクターに対応します。一致が0件または複数なら、ネイティブは非表示のままです。Engineはフォールバックコンテナを作らず、サイズ、配置、レイヤー、z-indexも選びません。コンテナの通常のレイアウトと操作可能なWebコントロールを維持してください。空でサイズ0のプレースホルダーは、利用可能なフォールバックではありません。これは固定のスコープであり、探索の起点ではありません。
登録時にコンテナが存在する必要はありません。DOMがなければネイティブを表示せずに待機し、置換されれば新しくバインドして古い画像を破棄します。Engineはコンテナの子、リスナー、値を維持します。viewにはネイティブビュー自体を渡します。複数のコントロールをまとめる場合は、共通のネイティブコンテナを使えます。内部識別子はEngineが管理するため、IDリストやビュー辞書は不要です。独立したサーフェスには別々の登録を使います。
Web Componentのホストを投影先にできます。例はprojectionSelector: 'native-ad[placement="home"]'です。ホストにはレイアウト領域(display: blockと意図した寸法)を与えます。Engineは挿入、削除、セレクター属性の変更を監視します。セレクターはドキュメント内で実行され、shadow root内部は探索しません。投影中、Engineはlight DOMと開かれたshadow root内のフォールバックコンテンツと疑似要素を抑制します。閉じたshadow rootのコンテンツは調べられないため、ホストのvisibilityを継承する必要があります。挿入画像を表示できるshadow/slot構造のコンテナを提供してください。
HTMLとIonicの全要素の表、サイズの条件、ラッパーの例は、投影コンテナの対応状況を参照してください。
ネイティブサーフェスの要件
スクロールフィード内の複数の広告など、個別に動くネイティブビューをプラグインが複数表示する場合、ビューごとに別の登録を作り、それぞれ固有のDOMコンテナに一致するセレクターを与えます。これにより、1つのビューの移動、非表示、置換が別のビューの投影を変えません。
それらの登録がプラグイン通知を共有する場合、receiveListeners.matchで各通知を対象の登録に振り分けます。一致判定のフィールドはプラグインが選ぶものであり、Engineの予約識別子ではありません。たとえば、表示する項目を識別するviewKeyと、その項目で順次読み込まれるインスタンスを区別するinstanceIdを含めます。
match: ["viewKey": viewKey, "instanceId": instanceId]
match = mapOf("viewKey" to viewKey, "instanceId" to instanceId)
通知のペイロードにも同じフィールドを含めます。読み込み済みコンテンツを置き換える際は、ネイティブコンテナを再利用していても古い登録を破棄し、以前のインスタンスへの通知が置換先に影響しないようにしてください。
サードパーティSDKのビューでは、読み込みと操作の処理をプラグインに残します。canCaptureで、SDKのルールと組み込み側が対応する条件のもとで、現在のコンテンツをキャプチャしてよいかを返します。たとえば広告SDKでは、動画と静的コンテンツで扱いを変える必要があるかもしれません。EngineはSDKコンテンツのキャプチャを許可するものではなく、クリックやインプレッションの処理も置き換えません。
同等のWebフォールバックを持たないSDK利用側は、iOSではfailedFallback: .native、AndroidではfailedFallback = NativeUIProjection.FailedFallback.NATIVEを指定します。デフォルトは.web / WEBで、既存の利用側の動作を維持します。自動的な移動で準備済み画像を使えない場合(未準備、未対応のキャプチャ、ハンドオフの拒否)、nativeはライブのネイティブビューを維持してフォールバックDOMを隠します。利用側はそのビューの配置を継続しなければなりません。この設定はAndroidにネイティブスクロール追従を追加しません。明示的なweb、none、オーバーレイの被覆が優先されます。この設定によって、意図的に上を覆うWebレイヤーよりもネイティブビューが手前に出ることはありません。
Androidで、非同期の非表示メソッドがすべてのピクセルの消失を保証する場合、利用側はprojection.hide { completed -> ... }を呼び、completedがtrueのときだけ完了させます。ネイティブのハンドオフ複製は直ちに消えますが、完了はWebプロキシの同期的な退場を待ちます。タイムアウトは成功ではなく失敗を報告します。再表示するときは通常のプラグインイベントに加え、projection.show()を呼びます。イベント購読の起動途中でも、これにより表示意図を維持できます。
スクロール監視は、割り当てられたslotを含め、composed treeの祖先を追います。Ionicのshadow tree内のnon-composedなスクロールイベントは、発生元で監視します。アプリ側で追加のリスナーや合成ドキュメントイベントを用意する必要はありません。リスナーはホストの親変更やslotの再割り当てに追従し、終了処理時に解除されます。
スクロールは内部で処理します。iOSでは利用可能なら一意に一致するネイティブスクロールバインディングを使います。それ以外はAndroidも含め、スクロール中は準備済み画像を一時的に使い、動きが落ち着いてからネイティブコンテンツを復元します。自動スクロール処理は明示的なwebやnoneを上書きしません。キャプチャやジオメトリが未対応なら通常のDOMフォールバックを維持し、遷移経路で新しいキャプチャを待ちません。最新の明示的な投影先はWebViewの再読み込みをまたいで維持され、古いドキュメントへの応答が新しいドキュメントの要求を完了させることはありません。
デフォルトでは、内部チャネルはCapacitorのlocalhostオリジン上のメインフレームに限定されます。別のオリジンを設定したアプリでは、完全一致するallowedOriginsを渡してください。AndroidではWebViewのWEB_MESSAGE_LISTENERとDOCUMENT_START_SCRIPTが必要で、未対応のWebView実装では登録が明示的に失敗します。リモートへ移動可能なWebViewでワイルドカードのオリジンを使わないでください。
キャプチャモード、半透明サーフェス、画像の色、プライベートストレージは、キャプチャとプラットフォームの制約を参照してください。カスタムレンダラーのブリッジとスクロールバインディングは、ネイティブのハンドオフで説明しています。