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

Add a way to override URL loading #87

Closed
rhappe opened this issue Jan 19, 2024 · 12 comments · Fixed by #146
Closed

Add a way to override URL loading #87

rhappe opened this issue Jan 19, 2024 · 12 comments · Fixed by #146
Assignees
Labels
enhancement New feature or request

Comments

@rhappe
Copy link

rhappe commented Jan 19, 2024

The android implementation of WebViewClient contains a method that can be used to intercept and override URLs being loaded by the webview: https://developer.android.com/reference/android/webkit/WebViewClient#shouldOverrideUrlLoading(android.webkit.WebView,%20android.webkit.WebResourceRequest)

It would be nice to have something similar here. :)

@rhappe
Copy link
Author

rhappe commented Jan 19, 2024

Didn't look at PRs, but looks like there is one for something like this here: #52 (although it says "do not merge").

@KevinnZou
Copy link
Owner

@rhappe Thank you for your feedback! We have begun working on supporting this feature, but we have encountered some issues. One problem we have encountered is that shouldOverrideUrlLoading does not intercept the first request. Could you please clarify what you specifically want to use shouldOverrideUrlLoading for? You can also check this issue for more information. Thanks!

@KevinnZou KevinnZou self-assigned this Jan 22, 2024
@KevinnZou KevinnZou added the enhancement New feature or request label Jan 22, 2024
@rhappe
Copy link
Author

rhappe commented Jan 22, 2024

@KevinnZou certainly! We have a WebView component in our compose multi-platform app which can list out different resources which we'd like to have launched in an external app (e.g. google docs/external browser). Another use case is the ability to sign out the user from a link/button in the webview, where we'd want the app to reactively navigate to the logged out app state.

It's great news that work has started on a feature like this. Can't wait to see it! I'll take a look at the issue thread you linked to get more context.

@KevinnZou
Copy link
Owner

@rhappe Thanks for your explanation! I understand your needs, and it is also a capability we hope to support. However, I am currently facing some strange issues that may prevent us from supporting this feature in the short term.

The main problem is as follows: on the Android side, I attempted to override shouldOverrideUrlLoading to intercept WebView requests. However, during testing, I found that it can only intercept a very small portion of requests, which is completely different from the behavior I observed in native WebView testing. On the iOS side, I also encountered strange issues. I inherited WKNavigationDelegateProtocol and overrode decidePolicyForNavigationAction to intercept requests. However, it behaves similarly to Android, only randomly intercepting a small portion of requests.

I have been trying to resolve these issues for the past two weeks, but so far, I have made no progress. The only possible reason could be related to using it in Compose, but there is no substantial evidence to prove this yet. In this situation, I may need to invest my time in other tasks and return to researching this problem once they are resolved.

I have pushed my test code to this branch, and if you're interested, you can test it there. You are welcome to post any new discoveries here, and I would greatly appreciate it.

@mikedawson
Copy link

mikedawson commented Jan 30, 2024

If I understand correctly, the objective of this is to override what is being loaded. I have been able to make that work reliably on Android for everything except the video tag preloading and post requests:

https://github.com/UstadMobile/UstadMobile/blob/primary/core/src/androidMain/kotlin/com/ustadmobile/core/domain/contententry/server/ContentEntryVersionServerWebClient.kt

I think the function shouldOverrideUrlLoading is deceptively named. I only use shouldOverrideUrlLoading as a means of catching link clicks. It is only triggered when the url of the webview itself is about to change (not called when scripts/css/images etc load). It also doesn't get called when the url change is via the hash.

I haven't found any need to override shouldOverrideUrlLoading. I just used shouldInterceptRequest.

@KevinnZou
Copy link
Owner

@mikedawson Thanks for your suggestions! Yes, shouldInterceptRequest does work for most URLs. However, it intercepts all the requests including resources. Furthermore, it does not support us in rejecting the URL loading like shouldOverrideUrlLoading does. We actually have discussed this issue before and concluded that shouldOverrideUrlLoading would be a better choice.

Our goal is to intercept URL requests and provide developers with the option to Accept, Modify, or Reject them. The shouldOverrideUrlLoading method fulfills this requirement effectively in a raw Android project. However, it does not work properly in a Compose environment when intercepting most URL requests. If the reason for this issue cannot be identified, I think we can consider using the shouldInterceptRequest method as a backup plan.

@vivaCoda54
Copy link

@KevinnZou is it possible in this case to resend headers when we navigate inside the webview? For my case I need to send an header to specify my website that I come from an mobile app. It works for the first webview, but not for the webview I open when I click inside a button or a link in my first webview.

@KevinnZou
Copy link
Owner

@vivaCoda54 I understand your need. Unfortunately, we cannot add headers for the following navigation before we support shouldOverrideUrlLoading. However, you can try using customUserAgentString in WebSettings to meet your needs. I apologize for any inconvenience caused. Please let me know if you encounter any further issues.

@dilip640
Copy link

What is status of shouldOverrideUrlLoading?

@KevinnZou
Copy link
Owner

@rhappe Thanks for your explanation! I understand your needs, and it is also a capability we hope to support. However, I am currently facing some strange issues that may prevent us from supporting this feature in the short term.

The main problem is as follows: on the Android side, I attempted to override shouldOverrideUrlLoading to intercept WebView requests. However, during testing, I found that it can only intercept a very small portion of requests, which is completely different from the behavior I observed in native WebView testing. On the iOS side, I also encountered strange issues. I inherited WKNavigationDelegateProtocol and overrode decidePolicyForNavigationAction to intercept requests. However, it behaves similarly to Android, only randomly intercepting a small portion of requests.

I have been trying to resolve these issues for the past two weeks, but so far, I have made no progress. The only possible reason could be related to using it in Compose, but there is no substantial evidence to prove this yet. In this situation, I may need to invest my time in other tasks and return to researching this problem once they are resolved.

I have pushed my test code to this branch, and if you're interested, you can test it there. You are welcome to post any new discoveries here, and I would greatly appreciate it.

@dilip640 Unfortunately, the issues mentioned above are yet to be resolved. It appears to be a problem with the Compose system, as it functions properly under the native raw Webview environment. However, without solving these issues, we cannot support shouldOverrideUrlLoading. Thus, I am considering submitting the issue to Compose for an official solution. I apologize for the inconvenience caused by this issue. If you have a solution, please feel free to submit a PR.

@westnordost
Copy link

FWIW, one use case for this feature request is to use the WebView for an in-app OAuth authorization flow: After the user authorized the app on the authorization provider's website, a callback url is called in the user's browser (or in this case: webview) that contains the authorization token. This callback url should not actually be loaded in the browser but passed on to the app that requested it.

@KevinnZou KevinnZou linked a pull request May 3, 2024 that will close this issue
@KevinnZou
Copy link
Owner

Hi all, I have implemented a basic interception in the latest version 1.9.8. Please follow these instructions to conduct a test and let me know if you encounter any issues.

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

Successfully merging a pull request may close this issue.

6 participants