Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to set local variable to post message whenever a new one is listened #305

Closed
erdemyerebasmaz opened this issue Jan 24, 2019 · 5 comments

Comments

@erdemyerebasmaz
Copy link

erdemyerebasmaz commented Jan 24, 2019

Hello,

I can listen to post messages on browser like this but I didn't quite understand how I can set a local variable to event.data.

String script1 = 'window.addEventListener("message", receiveMessage, false);' +
                'function receiveMessage(event) {console.log(event.data);}';
widgetWebview.evalJavascript(script);

I tried

String script2 = 'var test = "Hello, World!";'+
                 'function getMessage(val) {return val;}' +
                 'getMessage(test);';
var testLocal = await widgetWebview.evalJavascript(script2);

and you can set testLocal to test but I couldn't apply it to post message.

Also, I tried setting value of test inside script1 and trigger onUrlChanged inside receiveMessage function and access it from script2. The variables in script1 were not accessible by script2.

Can we use a callback function to communicate between app & webview?

Thanks

@erdemyerebasmaz
Copy link
Author

erdemyerebasmaz commented Jan 27, 2019

This is how I solved this issue:

initState() of my Flutter class where I'm using the webview widget.

...
widgetWebview.testStream.listen((value) {
      // whatever you will do with the listened data  
      });
    });
    widgetWebview.onStateChanged.listen((state) async {
      if (state.type == WebViewState.finishLoad) {
        String script = 'window.addEventListener("message", receiveMessage, false);' +
            'function receiveMessage(event) {FlutterJsInterface.getPostMessage(event.data);}';
        widgetWebview.evalJavascript(script);
      }
    });
...

Added this under WebviewManager's constructor:
webView.addJavascriptInterface(new FlutterJsInterface(), "FlutterJsInterface");
Second parameter is how it will be referenced inside javascript code.

and this inside WebviewManager.

public class FlutterJsInterface {
    @JavascriptInterface
    public void getPostMessage(String value){
        Map<String, Object> map= new HashMap<>();
        map.put("postMessage",value);
        FlutterWebviewPlugin.channel.invokeMethod("test", map);
    }
}

and created a stream inside base.dart

final _testStream = StreamController<String>.broadcast();

and added 'test' case under _handleMessages

case 'test':
        _testStream.add(call.arguments['postMessage']);
        break;

You can change the type, parse string to json object on both ends etc. Hope this was helpful.

@erdemyerebasmaz
Copy link
Author

Changes can be seen here

@Yiend
Copy link

Yiend commented Apr 28, 2019

Where is the WebviewManager?

@wackyapps
Copy link

I have updated the code changes in the source files. How do build this now to apply in compiled plugin.

@erdemyerebasmaz
Copy link
Author

I have updated the code changes in the source files. How do build this now to apply in compiled plugin.

@wackyapps
If you upgrade plugins of your project and there was a change in the plugin that references it's own repo, your changes will be overridden.
That's why you fork the plugin, apply the changes and reference that repo in your projects pubspec.yaml such as:

flutter_webview_plugin:
    git:
      url: https://github.com/your_repo_name/flutter_webview_plugin.git

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants