web-dev-qa-db-ja.com

Flutter webview双方向通信

Flutter_webview_pluginを使用してFlutter webviewに読み込むhtmlファイルがあります。私はevalJavascriptを使用して、javascriptコードで関数を呼び出しています。つまり、flutter(Dart)-> jsです。ただし、何かをflutter(Dart)レイヤーに通信する方法も必要です。つまり、js-> flutter(Dart)です。

私は両方のプラットフォーム(Android、iOS)をサポートするために-webkit.messageHandlers.native-window.nativeを使用して、JSで利用可能かどうかを確認してみました。しかし、それらは未定義です。次のコードを使用して、JSのネイティブハンドラーのインスタンスを取得します。

typeof webkit !== 'undefined' ? webkit.messageHandlers.native : 
window.native;

そして、そのインスタンスを取得してそれを使用してメッセージを投稿しても、flutter(Dart)レイヤーでそれを処理する方法がわかりません。プラットフォームチャネルを使用する必要があるかもしれません。私が正しい方向にいるかどうかはわかりません。

それを行う方法はありますか? Interactive_webviewプラグインを評価しました。 Androidでは問題なく動作します。しかし、Swiftバージョン管理の問題があり、それ以上進めたくありません。

任意の助けいただければ幸いです。

4
shrad

これは、JavaScriptコードからフラッターへの通信の例です。

Flutterで次のようにWebViewを構築します。

WebView(
              initialUrl: url,
              javascriptMode: JavascriptMode.unrestricted,
              javascriptChannels: Set.from([
                JavascriptChannel(
                    name: 'Print',
                    onMessageReceived: (JavascriptMessage message) {
                      //This is where you receive message from 
                      //javascript code and handle in Flutter/Dart
                      //like here, the message is just being printed
                      //in Run/LogCat window of Android studio
                      print(message.message);
                    })
              ]),
              onWebViewCreated: (WebViewController w) {
                webViewController = w;
              },
            )

あなたのHTMLファイルで:

<script type='text/javascript'>
    Print.postMessage('Hello World being called from Javascript code');
</script>

このコードを実行すると、Android studio。のLogCat/Runウィンドウでログ「Javascriptコードから呼び出されているHello World」を確認できるはずです。

8
Suresh Kumar

私のプラグインを試すことができます flutter_inappbrowser[〜#〜] edit [〜#〜]:名前が変更されました- flutter_inappwebview )およびaddJavaScriptHandler({@required String handlerName, @required JavaScriptHandlerCallback callback})メソッドを使用します(詳細は こちら を参照)。

以下に例を示します。 Flutter側:

...

child: InAppWebView(
  initialFile: "assets/index.html",
  initialHeaders: {},
  initialOptions: InAppWebViewWidgetOptions(
    inAppWebViewOptions: InAppWebViewOptions(
        debuggingEnabled: true,
    )
  ),
  onWebViewCreated: (InAppWebViewController controller) {
    webView = controller;

    controller.addJavaScriptHandler(handlerName: "mySum", callback: (args) {
      // Here you receive all the arguments from the JavaScript side 
      // that is a List<dynamic>
      print("From the JavaScript side:");
      print(args);
      return args.reduce((curr, next) => curr + next);
    });
  },
  onLoadStart: (InAppWebViewController controller, String url) {

  },
  onLoadStop: (InAppWebViewController controller, String url) {

  },
  onConsoleMessage: (InAppWebViewController controller, ConsoleMessage consoleMessage) {
    print("console message: ${consoleMessage.message}");
  },
),

...

JavaScript側(たとえば、ローカルファイルassets/index.html(assetsフォルダ内):

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=Edge">
        <title>Flutter InAppBrowser</title>

        ...

    </head>
    <body>

        ...

        <script>
           // In order to call window.flutter_inappwebview.callHandler(handlerName <String>, ...args) 
           // properly, you need to wait and listen the JavaScript event flutterInAppWebViewPlatformReady. 
           // This event will be dispatched as soon as the platform (Android or iOS) is ready to handle the callHandler method. 
           window.addEventListener("flutterInAppWebViewPlatformReady", function(event) {
             // call flutter handler with name 'mySum' and pass one or more arguments
             window.flutter_inappwebview.callHandler('mySum', 12, 2, 50).then(function(result) {
               // get result from Flutter side. It will be the number 64.
               console.log(result);
             });
           });
        </script>
    </body>
</html>

Android Studioのログで次のようになります:

I/flutter (20436): From JavaScript side:
I/flutter (20436): [12, 2, 50]
I/flutter (20436): console message: 64
1