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

shouldInterceptRequest Method Not Working on iOS - Need Alternative Solution #2507

Open
1 of 2 tasks
zitob9 opened this issue Jan 18, 2025 · 5 comments
Open
1 of 2 tasks
Labels
bug Something isn't working

Comments

@zitob9
Copy link

zitob9 commented Jan 18, 2025

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

The shouldInterceptRequest method only works on Android platforms. When attempting to intercept media URLs on iOS, this method does not function

Expected Behavior

Ideally, shouldInterceptRequest should work consistently across both Android and iOS platforms, providing a unified way to intercept network requests, particularly for media URL detection.

Steps with code example to reproduce

InAppWebView(
  initialUrlRequest: URLRequest(url: WebUri(url)),
  initialSettings: settings,
  shouldInterceptRequest: (controller, request) async {
    String url = request.url.toString();
    if (isVideoUrl(url)) {
      print("Found video URL: $url");
      // This works on Android but not on iOS
    }
    return null;
  },
)

Stacktrace/Logs

nothing

Flutter version

3.27.2

Operating System, Device-specific and/or Tool

macos; 3.27.2

Plugin version

6.1.5

Additional information

Currently trying to intercept background requests on iOS is challenging as shouldInterceptRequest only works on Android. While combining onLoadResource, shouldInterceptAjaxRequest, and shouldInterceptFetchRequest provides partial coverage, some requests might still be missed.
Could you suggest any other iOS-specific solutions or methods to reliably intercept all background requests? Perhaps there are iOS WebKit capabilities or alternative approaches that could be implemented to provide functionality similar to Android's shouldInterceptRequest?
Looking forward to your guidance on the best approach for iOS request interception.

Self grab

  • I'm ready to work on this issue!
@zitob9 zitob9 added the bug Something isn't working label Jan 18, 2025
@laishere
Copy link

laishere commented Jan 20, 2025

I don't think it's a bug. iOS WKWebView just doesn't support it.
You can try to register a service worker by injecting the js to intercept the requests.

@zitob9
Copy link
Author

zitob9 commented Jan 21, 2025

I don't think it's a bug. iOS WKWebView just doesn't support it. You can try to register a service worker by injecting the js to intercept the requests.

The funny thing is that onLoadResource works on iOS to get us m3u8 links, but on Android, it doesn't fetch those links—it only retrieves JS and CSS files. Only shouldInterceptRequest gets us the m3u8 links.

@laishere
Copy link

onLoadResource is natively supported on iOS. However, it is implemented via js on Android, you can check this:

public static String ON_LOAD_RESOURCE_JS_SOURCE() {
return
"window." + FLAG_VARIABLE_FOR_ON_LOAD_RESOURCE_JS_SOURCE() + " = true;" +
"(function() {" +
" var observer = new PerformanceObserver(function(list) {" +
" list.getEntries().forEach(function(entry) {" +
" if (" + FLAG_VARIABLE_FOR_ON_LOAD_RESOURCE_JS_SOURCE() + " == null || " + FLAG_VARIABLE_FOR_ON_LOAD_RESOURCE_JS_SOURCE() + " == true) {" +
" var resource = {" +
" 'url': entry.name," +
" 'initiatorType': entry.initiatorType," +
" 'startTime': entry.startTime," +
" 'duration': entry.duration" +
" };" +
" window." + JavaScriptBridgeJS.get_JAVASCRIPT_BRIDGE_NAME() + ".callHandler('onLoadResource', resource);" +
" }" +
" });" +
" });" +
" observer.observe({entryTypes: ['resource']});" +
"})();";

As I tested on my pc using same method, it catches all network activities.
But it may not quite the same on Android WebView. I think it may be caused by the injection time.
You should check if your WebView version supports injecting js before page start loading. Otherwise it may miss some network resources.
Also it depends on inappwebview js bridge, which may not be ready too. But if you can manage to inject the js script before the page start loading, you can always save it in js variables and evaluate the results later when js bridge is ready.

@laishere
Copy link

laishere commented Jan 22, 2025

https://developer.android.com/reference/androidx/webkit/WebViewCompat#addDocumentStartJavaScript(android.webkit.WebView,java.lang.String,java.util.Set%3Cjava.lang.String%3E)

If your webview is released after November 29, 2023, it should support addDocumentStartJavaScript. Check it via developer tools.

@laishere
Copy link

My advice is you can use both onLoadResource and shouldInterceptRequest if you mean to get the network requests other than block them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants