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

Allow postMessage to return a JS promise to send a message from JS running in a WebView to the application's Dart code #34594

Open
amirh opened this issue Jun 17, 2019 · 5 comments
Labels
c: new feature Nothing broken; request for a new capability c: proposal A detailed proposal for a change to Flutter customer: dream (g3) p: webview The WebView plugin P2 Important issues not at the top of the work list package flutter/packages repository. See also p: labels. team-ecosystem Owned by Ecosystem team triaged-ecosystem Triaged by Ecosystem team

Comments

@amirh
Copy link
Contributor

amirh commented Jun 17, 2019

Internal: b/343558780

Currently the way to send a message from JS running in a WebView to the application's Dart code is by calling t JavaScriptChannel's postMessage method which has no return value. A response can be sent back from the Dart code to the JS code by calling evaluateJavascript.

User's have expressed interest in making it easier to get a response from a postMessage, the propose solution would be to have the postMessage return a javascript promise and have some convenient wrapper code on the Dart side that takes and return value and calls evaluateJavascript to complete the returned promise.

Not having this feature isn't blocking any use case(users can still explicitly call evaluateJavascript to "return" a value, and users an even implement the mechanism described above externally to the webview plugin).

Availability of JS Promise

According to https://caniuse.com/#feat=promises promise is available starting iOS 8.0 which is what Flutter supports, and starting Android API 20(which is what webview currently support, though technically we can make it support API 19).

@amirh amirh added this to the Goals milestone Jun 17, 2019
@amirh
Copy link
Contributor Author

amirh commented Jun 18, 2019

Some additional thoughts:

Naively I'd think that we want the JS postMessage to always return a promise, but what should happen when we don't need a return value, we could potentially require that the Dart handler has a return value, but that means we always have a JS->Dart->JS roundtrip even if we don't need it(which may involve hopping across 3 or more threads).

We could potentially have 2 "types" of channels(with/without a return value) but it feels like it complicates the API.

We may consider implementing this as helper methods that live outside of WebView/WebViewController and ship the common functionality with the plugin.

Another alternative which I think is reasonable is to completely leave it up to the app developers, we can probably provide sample code that can be reused(in this issue/API docs/codelabs).

@victorherrerod
Copy link

victorherrerod commented Jul 29, 2019

While I agree that not having this feature doesn't block any use case, having to use evaluateJavascript every time you need an answer from the Dart side is a bit clunky in my opinion.

Having the standard JS promise as an option would make it easier to have a Client <-> Server kind of communication between the Webview and the Dart code.

I hope you can work on this issue, it would be really nice for my project!

@jjjachyty
Copy link

+1 I also hope to return promise,I don't want to evaluateJavascript callback function,is there another way todo for now?

@victorherrerod
Copy link

Hey, I understand that this issue might not be of high priority. However, @amirh you wrote:

Not having this feature isn't blocking any use case(users can still explicitly call evaluateJavascript to "return" a value, and users an even implement the mechanism described above externally to the webview plugin).

And I'd just would like to have some pointers on how to do this externally to the webview plugin, I don't really know where to start.
I'd understand if you guys don't have time to explain tho :)

Thanks in advance.

@zoeyfan zoeyfan changed the title Allow postMessage to return a JS promise Allow postMessage to return a JS promise to send a message from JS running in a WebView to the application's Dart code Jan 3, 2020
@kf6gpe kf6gpe added the P2 Important issues not at the top of the work list label May 29, 2020
@Hixie Hixie removed this from the None. milestone Aug 17, 2020
@danagbemava-nc danagbemava-nc added p: first party c: proposal A detailed proposal for a change to Flutter c: new feature Nothing broken; request for a new capability labels Aug 10, 2021
@flutter-triage-bot flutter-triage-bot bot added the package flutter/packages repository. See also p: labels. label Jul 5, 2023
@Hixie Hixie removed the plugin label Jul 6, 2023
@flutter-triage-bot flutter-triage-bot bot added team-ecosystem Owned by Ecosystem team triaged-ecosystem Triaged by Ecosystem team labels Jul 8, 2023
@jeetparte
Copy link

jeetparte commented Nov 17, 2023

Are there any plans for this to be implemented?

I have a use case in our current app which relies on being able to define a Promise visible to JS which should execute Dart code and return the result values in the Promise. That pretty much seems to rely on the ability for postMessage to return a value, as stated here. So unless I find a way to patch together webview_flutter's postMessage and evaluateJavascript into a single Promise, I may have to consider switching to flutter_inappwebview which has this implemented.

There are also other users interested in this. See this StackOverFlow post.

In case anyone's interested in implementing this, here are some details that might help —

  1. On the native side, the WebKit API offers this functionality on iOS 14.0+ via addScriptMessageHandler.
  2. See flutter_inappwebview's implementation of this. It states it uses the above iOS API and addJavascriptInterface on Android.

EDIT: I managed to implement the Promise by combining postMessage with a JS event listener that listens to an event invoked by runJavaScript with the payload data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: new feature Nothing broken; request for a new capability c: proposal A detailed proposal for a change to Flutter customer: dream (g3) p: webview The WebView plugin P2 Important issues not at the top of the work list package flutter/packages repository. See also p: labels. team-ecosystem Owned by Ecosystem team triaged-ecosystem Triaged by Ecosystem team
Projects
None yet
Development

No branches or pull requests

8 participants