-
Notifications
You must be signed in to change notification settings - Fork 24.9k
Exported a callback for native webview delegate method shouldStartLoadWithRequest #3643
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
Exported a callback for native webview delegate method shouldStartLoadWithRequest #3643
Conversation
By analyzing the blame information on this pull request, we identified @nicklockwood, @donyu and @vjeux to be potential reviewers. |
Since RN is asynchronous, it's really hard to expose this |
I would rather have the ability for a JS callback to return a promise to the native delegate, but I didn't see how to do this. Any feedback or help on that is appreciated, as that would be the correct implementation. In this implementation, setting HTML/URL causes the delegate to fire again, and the _forceReload flag skips the JS callback, and returns YES. I'll have to check if this messes with the web view history and breaks the back/forward. |
You could consider blocking the main thread this (I believe the underlying webkit call is actually async), and waiting for the JS side to return. We haven't used that pattern anywhere else yet but I'd be curious to see if it works out. On onShouldStartLoadWithRequest, create a new NSCondition with a certain identifier and call the JS block passing that identifier. While you wait for the JS to return, block the main thread using |
Tried your suggested approach, but blocking the main thread with NSCondition or NSConditionLock blocks RN. Here's what I tried: In RCTWebView.m:
In RCTWebViewManager.m:
I put a breakpoint in RCTWebViewManager.m, and [view startLoadWithRequest:result]; is only called after waitUntilDate: times out. I tried firing the JS callback on a different thread, but this didn't seem to have any effect. |
|
9b8ae4d
to
694af52
Compare
@pjcabrera updated the pull request. |
@javache I replaced the call to |
…StartLoadWithRequest:navigationType:
694af52
to
ec8bccb
Compare
@pjcabrera updated the pull request. |
@javache @nicklockwood any interest in further review of this PR? I made the changes that were suggested. |
@facebook-github-bot import |
Thanks for importing. If you are an FB employee go to https://our.intern.facebook.com/intern/opensource/github/pull_request/189349541404275/int_phab to review. |
Thanks @pjcabrera. I iterated on this a bit more, and we're now discussing internally if this is a good way forward for implementing synchronous API's. |
Summary: public Original github title: Exported a callback for native webview delegate method shouldStartLoadWithRequest We have a requirement in our app, to open in mobile Safari, any http:// and https:// links displayed in a web view. Our web view is not full screen and is loaded with an HTML string from the backend. Displaying external content in that web view is outside of the scope of our app, so we open them in mobile Safari. I've forked the WebView component and added a callback property, shouldStartLoadWithRequest, and modified the RCTWebView implementation of `webView:shouldStartLoadWithRequest:navigationType:` to check if the shouldStartLoadWithRequest property is set. If the property is set, `webView:shouldStartLoadWithRequest:navigationType:` passes the URL & navigationType to the callback. The callback is then able to ignore the request, redirect it, open a full screen web view to display the URL content, or even deep link to another app with LinkingIOS.openURL(). Original author: PJ Cabrera <[email protected]> Closes facebook#3643 Reviewed By: nicklockwood Differential Revision: D2600371 fb-gh-sync-id: 14dfdb3df442d899d9f2af831bbc8d695faefa33
Summary: public Original github title: Exported a callback for native webview delegate method shouldStartLoadWithRequest We have a requirement in our app, to open in mobile Safari, any http:// and https:// links displayed in a web view. Our web view is not full screen and is loaded with an HTML string from the backend. Displaying external content in that web view is outside of the scope of our app, so we open them in mobile Safari. I've forked the WebView component and added a callback property, shouldStartLoadWithRequest, and modified the RCTWebView implementation of `webView:shouldStartLoadWithRequest:navigationType:` to check if the shouldStartLoadWithRequest property is set. If the property is set, `webView:shouldStartLoadWithRequest:navigationType:` passes the URL & navigationType to the callback. The callback is then able to ignore the request, redirect it, open a full screen web view to display the URL content, or even deep link to another app with LinkingIOS.openURL(). Original author: PJ Cabrera <[email protected]> Closes facebook#3643 Reviewed By: nicklockwood Differential Revision: D2600371 fb-gh-sync-id: 14dfdb3df442d899d9f2af831bbc8d695faefa33
Are there any plans to match this API on Android? |
i think you need not to add this method ,if you want to shouldStartLoadWithRequest before you open a webview , you can open a html with js request, then you got response and redirect |
We have a requirement in our app, to open in mobile Safari, any http:// and https:// links displayed in a web view. Our web view is not full screen and is loaded with an HTML string from the backend. Displaying external content in that web view is outside of the scope of our app, so we open them in mobile Safari.
I've forked the WebView component and added a callback property, shouldStartLoadWithRequest, and modified the RCTWebView implementation of
webView:shouldStartLoadWithRequest:navigationType:
to check if the shouldStartLoadWithRequest property is set.
If the property is set,
webView:shouldStartLoadWithRequest:navigationType:
passes the URL & navigationType to the callback. The callback is then able to ignore the request, redirect it, open a full screen web view to display the URL content, or even deep link to another app with LinkingIOS.openURL().