Cordovaプラグインへの組み込み
同じnpmパッケージ、Swiftライブラリ、Android AARがCapacitorとCordovaに対応します。Engineはプラグインのメンテナーが使うライブラリであり、個別に登録するCordovaプラグインではありません。Cordovaアプリに@capacitor/coreやCapacitorのネイティブSDKは不要です。
ネイティブビューと対応するDOMの配置、サイズ、重なり順は、利用側プラグインが引き続き管理します。native-adや#playerなどの既存セレクターを指定してください。DOMは初期化後に追加しても構いません。画像準備、スクロール処理、オーバーレイ、復元には共通のEngine実装を使います。
要件
標準WebViewを使用したcordova-ios 8.1.1とcordova-android 15.1.0で組み込みを検証しています。Engine自体にはiOS 15以上とAndroid API 23以上が必要ですが、CordovaホストやSDKがさらに高い最小バージョンを要求する場合があります。Androidの合成済みキャプチャにはAPI 26以上が必要です。
依存関係
Webパッケージとネイティブライブラリで、同じEngineリリースを使います。APIは1.0未満の段階なので、バージョンを固定し、依存関係のロックファイルを保持してください。
npm install --save-exact @webview-native-ui/engine@0.0.1
利用側プラグインでもネイティブ依存を宣言します。npmのインストールだけでは、いずれのネイティブライブラリもリンクされません。
Swift Package Managerの場合:
.package(url: "https://github.com/webview-native-ui/engine.git", exact: "0.0.1")
// プラグインターゲットの依存関係:
.product(name: "WebViewNativeUIEngine", package: "engine")
プラグインのAndroid Gradle設定の場合:
dependencies {
implementation 'io.github.webview-native-ui:engine:0.0.1'
}
利用側ビルドの依存リポジトリにgoogle()とmavenCentral()を含めてください。
iOS
CordovaのSwiftPMプラグインでは、プラグインターゲットの依存としてCordovaとEngineの両方を宣言します。どちらのフレームワークもEngineターゲットの依存にはなりません。プラグインの既存SwiftPMプロダクトとソースファイルの宣言を維持します。
アプリからの最初の呼び出し前にレンダラーを表示する必要がある場合は、plugin.xmlのiOSプラットフォームセクションでプラグインを起動時に登録します。
<platform name="ios" package="swift">
<config-file target="config.xml" parent="/*">
<feature name="ExamplePlugin">
<param name="ios-package" value="ExamplePlugin" />
<param name="onload" value="true" />
</feature>
</config-file>
<!-- プラグインの既存ソースファイル宣言を維持します。 -->
</platform>
プラットフォームセクションを重複追加せず、既存セクションへこれらの設定を統合してください。組み込み検証用の構成には、plugin.xml、SwiftPM、Gradleの完全な設定があります。
例では既存のレンダラーを拡張します。nativeViewは接続・配置済みのビューであり、Engineが作成するビューではありません。
import Cordova
import WebKit
import WebViewNativeUIEngine
@objc(ExamplePlugin)
class ExamplePlugin: CDVPlugin {
private var projection: NativeUIProjection?
private var nativeView: UIView?
override func pluginInitialize() {
// 既存のレンダラーでnativeViewをここで作成・接続・配置します。
do {
projection = try NativeUIProjection(
webView: webView as? WKWebView,
plugin: "ExamplePlugin",
projectionSelector: "#player",
receiveListeners: .init(
update: ["contentChanged"],
projection: .init(native: ["shown"], web: ["covered"], none: ["hidden"])
),
runtime: .cordova,
view: { [weak self] in self?.nativeView }
)
} catch {
// 登録が利用できない場合は既存のWebフォールバックを維持します。
NSLog("Native UI projection unavailable: %@", String(describing: error))
}
}
override func dispose() {
projection?.destroy()
projection = nil
super.dispose()
}
}
iOSレンダラーを後から読み込む場合は、ビューを接続してから登録を作成します。レンダラーを置き換える前に、古い登録を破棄してください。
プラグインの既存の表示・コンテンツ通知を、projection?.receive("shown")、receive("hidden")、receive("contentChanged")で転送します。既存のコールバック・イベント送信箇所、またはプラグインの共通通知メソッドに追加してください。receiveはEngineセッションだけを更新し、アプリへ2回目のコールバックを送信しません。JS起動前に送信された、一致する投影先は初回接続用に保持されます。
Cordova iOS組み込みのWkWebView.convertFilePathが準備済みPNGを配信します。Engineが内部で解決するため、ファイルプラグイン、追加権限、開発者によるURL変換関数は不要です。既定の許可オリジンにはapp://localhostが含まれます。アプリのスキームやホスト名を変更した場合は、実際に信頼するオリジンを渡してください。
Android
既存のCordovaプラグインのGradle設定にMaven依存を宣言します。CordovaPluginPathHandlerのシグネチャを使う場合は、implementation 'androidx.webkit:webkit:1.14.0'も宣言してください。Cordova内部のWebKit依存は、プラグインのコンパイルクラスパスに公開されません。最初のWebViewナビゲーション前に初期化されるよう、プラグインのplugin.xmlのAndroidプラットフォームセクションに次の登録を統合します。
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="ExamplePlugin">
<param name="android-package" value="com.example.ExamplePlugin" />
<param name="onload" value="true" />
</feature>
</config-file>
<!-- 既存のソースファイルとGradleフレームワークの宣言を維持します。 -->
</platform>
import android.view.View
import android.webkit.WebView
import io.github.webview_native_ui.engine.NativeUIProjection
import org.apache.cordova.CordovaPlugin
import org.apache.cordova.CordovaPluginPathHandler
class ExamplePlugin : CordovaPlugin() {
private var projection: NativeUIProjection? = null
private var nativeView: View? = null
override fun pluginInitialize() {
val web = webView.view as WebView
projection = runCatching {
// One origin-restricted channel per WebView, shared with later registrations.
NativeUIProjection.install(web)
// Existing renderer creates, attaches and positions nativeView here.
NativeUIProjection(
window = cordova.activity.window,
webView = web,
plugin = serviceName,
projectionSelector = "#player",
receiveListeners = NativeUIProjection.ReceiveListeners(
update = listOf("contentChanged"),
projection = NativeUIProjection.ReceiveListeners.Projection(
native = listOf("shown"), web = listOf("covered"), none = listOf("hidden")
)
),
runtime = NativeUIProjection.Runtime.CORDOVA,
view = { nativeView }
)
}.onFailure {
android.util.Log.e(javaClass.simpleName, "Native UI projection unavailable", it)
}.getOrNull()
}
override fun getPathHandler() = CordovaPluginPathHandler { path ->
projection?.handleResource(path)
}
override fun onDestroy() {
projection?.close()
projection = null
super.onDestroy()
}
}
iOSと同様に、既存の通知箇所でprojection?.receive(eventName, data)を使います。ネイティブビューの作成と配置はUIスレッドで行います。レンダラーを非同期に読み込む場合は、install(web)をpluginInitialize()に残し、ビューの準備後に登録を作成してください。そのレンダラーを置き換える前に、古い登録を閉じます。
PathHandlerは同一オリジンの画像リクエストをEngineへ委譲します。アプリ専用キャッシュストレージにある、その登録のPNGだけを配信し、無関係なパスにはnullを返します。プラグインに既存ハンドラーがある場合は、projection?.handleResource(path) ?: existingHandler.handle(path)で組み合わせます。登録が複数ある場合は、一致する所有者へ委譲します。ハンドラーはWebViewの生存期間中、インストールされたままにしてください。WebViewClientの置き換えやストレージ権限は不要です。
既定値はCordovaのhttps://localhostとhttp://localhostに対応します。ホスト名を変更する場合は、installと各登録に同じ明示的なオリジン集合を渡してください。この組み込みでは、ワイルドカードオリジンとfile://のアプリオリジンには対応しません。
生存期間と検証
WebViewの生存期間中は登録を保持します。Engineはドキュメント再読み込み後に再接続し、古いドキュメントの画像状態を消去します。プラグインがonResetでネイティブUIを破棄する場合は、ビュープロバイダーを更新して適切な投影先を通知してください。破棄済みビューを指す登録を残してはいけません。プラグイン・WebViewを破棄するときに登録を解放します。
Capacitorの登録は既存の既定値を維持します。Cordovaの組み込みには標準のCordova WebViewリソースハンドラーが必要です。Capacitorアプリ内でCordovaプラグインを動かす構成はこの組み込みの対象外で、ホストはCapacitor向けの組み込みを使う必要があります。セレクター、レイアウト、キャプチャの規則は共通のDOMとネイティブサーフェスの要件を参照してください。Ionicオーバーレイ対応は任意で、通常のCordovaアプリでは有効化不要です。
組み込み検証用の構成は、Cordova CLI 13、cordova-ios 8.1.1、cordova-android 15.1.0と標準WebViewを使います。JSブリッジのモックだけでなく、実際のPNG受け渡し、ネイティブ復元、ドキュメント再読み込み後の非表示状態の保持を検証します。古いCordovaリリースやカスタムWebViewエンジンは、別途検証が必要です。
起動済みのシミュレーター・エミュレーターで、実際の利用側のチェックを実行します。
npm run test:cordova -- ios SIMULATOR_UDID
npm run test:cordova -- android emulator-5554
スクリプトは使い捨てのアプリを作成し、ローカルのSwiftPM・MavenのEngineアーティファクトを使って、表示された一時ディレクトリにアプリの実行結果を記録します。npmやMavenへの公開は行いません。AndroidにはJDK 21以上、SDK 36、ANDROID_HOMEが、iOSにはXcodeが必要です。