-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Hi all,
I'm building a simple WebView for an online magazine both for Android and for iOS.
webview_flutter: ^1.0.7
The online magazine runs on Wordpress.
The Wordpress site also has clickable display ads in it.
My main goal is to avoid the WebView itself from navigation away from the BaseUrl.
But the user shall be able to launch external links (like external links in articles or even ads).
On Android it was fairly easy creating a NavigationDelegate like this
navigationDelegate: (NavigationRequest request) {
if (request.url.startsWith(baseUrl)) {
print('allowing navigation to $request');
return NavigationDecision.navigate;
} else {
print('blocking navigation to $request}');
launchUrl(request.url);
return NavigationDecision.prevent;
}
im using the
url_launcher: ^5.7.10
dependency to launch external Urls in a separate browser.
This totally worked fine on Android.
But moving on to iOS all the external loaded links via JavaScript etc. triggered the NavigationDelegate to fire each and every time.
Luckily I got rid of it by using the variable isForMainFrame, so I adopted my NavigationDelegate a bit.
navigationDelegate: (NavigationRequest request) {
if (request.url.startsWith(baseUrl) {
print('allowing navigation to $request');
return NavigationDecision.navigate;
} else if (request.isForMainFrame) {
print('allowing navigation to $request');
launch(request.url);
return NavigationDecision.prevent;
} else {
print('blocking navigation to $request}');
return NavigationDecision.prevent;
}
},
the request.isForMainFrame is returned true if I explicitly click on an external link, which starts not with the baseUrl. And all the Sideloading thing is blocked by the else block.
The next challenge I encountered is, that the online magazine uses a third party consent management platform which auto loads via JavaScript but runs the else-block.
As a result of that I needed to adjust the very first line of the NavigationDelegate in order to allow the baseUrl AND the url of the third party site to function properly in my WebView.
So far so good ...
But today I noticed, that all embeds like YouTube / Twitter etc.(via iFrame or so) within an article are also triggering navigationDelegate resulting from the code above into a NavigationDecision.prevent and the embed won't appear in the WebView at all.
As a workaround I created a simple handler method which manages a WhiteList so that my NavigationDelegate looks like this
navigationDelegate: (NavigationRequest request) {
if (isWhiteListed(request.url)) {
print('allowing navigation to $request');
return NavigationDecision.navigate;
} else if (request.isForMainFrame) {
print('allowing navigation to $request');
launch(request.url);
return NavigationDecision.prevent;
} else {
print('blocking navigation to $request}');
return NavigationDecision.prevent;
}
}
The problem that I see here is the general maintainability of the App since I need to either create a huge whitelist beforehand, create something like a cloudConfig. Or always create a breaking change version of the app, when something new needs to be whitelisted.
Is this behavior intended on iOS, that the NavigationDelegate is triggered much more than on Android?