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

JavaScript injection timing #238

Open
minarja1 opened this issue Oct 9, 2024 · 3 comments
Open

JavaScript injection timing #238

minarja1 opened this issue Oct 9, 2024 · 3 comments
Assignees
Labels
enhancement New feature or request

Comments

@minarja1
Copy link

minarja1 commented Oct 9, 2024

Hi @KevinnZou,

I am trying to use the js bridge to establish communication between native and webview. The implementation works on iOS but not on Android. The problem seems to be in the sequence of operations.

The website loads and expects the js bridge to provide it with authorisation tokens. However, the js bridge is only injected after the url is finished loading. What is the reason behind the decision to inject the bridge after the page is fully loaded as seen in the snippet of WebView.kt:

        if (webViewJsBridge != null && !getPlatform().isDesktop()) {
            LaunchedEffect(wv, state) {
                val loadingStateFlow =
                    snapshotFlow { state.loadingState }.filter { it is LoadingState.Finished }
                val lastLoadedUrFlow =
                    snapshotFlow { state.lastLoadedUrl }.filter { !it.isNullOrEmpty() }

                // Only inject the js bridge when url is changed and the loading state is finished.
                merge(loadingStateFlow, lastLoadedUrFlow).collect {
                    // double check the loading state to make sure the WebView is loaded.
                    if (state.loadingState is LoadingState.Finished) {
                        wv.injectJsBridge()
                    }
                }
            }
        }

My implementation follows the docs with nothing special about it.

This is my logcat output:

2024-10-09 19:51:47.575 30643-30643 ComposeWebView          com.example.app                  D  onPageStarted: https://...
2024-10-09 19:51:47.584 30643-30643 ComposeWebView          com.example.app                  D  doUpdateVisitedHistory: https://...
2024-10-09 19:51:47.584 30643-30643 ComposeWebView          com.example.app                  D  onReceivedTitle: ...
2024-10-09 19:51:47.584 30643-30643 ComposeWebView          com.example.app                  D  onPageFinished: https://...
2024-10-09 19:51:47.584 30643-30643 ComposeWebView          com.example.app                  D  evaluateJavaScript: javascript:var meta = document.createElement('meta');meta.setAttribute('name', 'viewport');meta.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=10.0, minimum-scale=0.1,user-scalable=yes');document.getElementsByTagName('head')[0].appendChild(meta);
2024-10-09 19:51:47.585 30643-30643 ComposeWebView          com.example.app                  D  IWebView injectJsBridge
2024-10-09 19:51:47.585 30643-30643 ComposeWebView          com.example.app                  D  evaluateJavaScript: javascript:window.kmpJsBridge = { ...
2024-10-09 19:51:47.585 30643-30643 ComposeWebView          com.example.app                  D  evaluateJavaScript: javascript:window.kmpJsBridge.postMessage = function (message) {
                                                                                                            window.androidJsBridge.call(message)
                                                                                                        };
2024-10-09 19:51:47.594 30643-30643 chromium                com.example.app                  I  [INFO:CONSOLE(79)] "No KMP JS bridge available ..."

You can see there are only a couple of milliseconds between the reported injection of the bridge and chromium trying to use it and reporting it is as unavailable.

Thanks in advance for your reply and this library!

@KevinnZou
Copy link
Owner

@minarja1 Thanks for your feedback! JsBridge will be cleared when the page is fully loaded, so it will be useless to inject it early.

@KevinnZou KevinnZou self-assigned this Oct 12, 2024
@KevinnZou KevinnZou added the enhancement New feature or request label Oct 12, 2024
@minarja1
Copy link
Author

@KevinnZou Thank you for the reply. Can you please explain in a bit more detail? Why would it be cleared after the page is loaded?

@KevinnZou
Copy link
Owner

@KevinnZou Thank you for the reply. Can you please explain in a bit more detail? Why would it be cleared after the page is loaded?

It's the system behavior

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

No branches or pull requests

2 participants