web-dev-qa-db-fra.com

Communication bidirectionnelle Flutter Webview

J'ai un fichier html que je charge dans Flutter webview en utilisant flutter_webview_plugin. J'utilise evalJavascript pour appeler la fonction dans mon code javascript, ce qui signifie flutter (Dart) -> js. Cependant, j'ai également besoin d'un moyen de communiquer quelque chose en arrière à la couche Flutter (Dart), ce qui signifie js-> flutter (Dart).

J'ai essayé d'utiliser - webkit.messageHandlers.native - window.native pour prendre en charge les deux plates-formes (Android, iOS) en vérifiant si celles-ci sont disponibles dans JS. Mais, cela vient comme indéfini. Utilisation du code suivant pour obtenir une instance de gestionnaire natif dans JS.

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

Et même si je reçois cette instance et que je poste un message en l'utilisant, je ne sais pas comment le gérer dans la couche Flutter (Dart). Il se peut que je doive utiliser des canaux de plate-forme. Je ne sais pas si je suis dans la bonne direction.

Existe-t-il un moyen par lequel je peux le faire? J'ai évalué le plugin interactive_webview. Cela fonctionne très bien sur Android. Mais, il a Swift et je ne veux pas aller plus loin avec cela.

Toute aide serait appréciée.

4
shrad

Voici un exemple de communication du code Javascript au flottement.

Dans Flutter, créez votre WebView comme:

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;
              },
            )

et dans votre fichier HTML:

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

Lorsque vous exécutez ce code, vous pourrez voir le journal "Hello World étant appelé à partir du code Javascript" dans la fenêtre LogCat/Run de Android studio.

8
Suresh Kumar

Vous pouvez essayer mon plugin flutter_inappbrowser ( [~ # ~] modifier [~ # ~] : il a été renommé en - flutter_inappwebview ) et utilisez la méthode addJavaScriptHandler({@required String handlerName, @required JavaScriptHandlerCallback callback}) (voir plus ici ).

Un exemple est présenté ci-dessous. Côté 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}");
  },
),

...

Côté JavaScript (par exemple un fichier local assets/index.html dans le dossier des ressources):

<!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>

Sur Android Journaux Studio, vous obtiendrez:

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