It would be nice if there was a possibility to set custom user agent forWebView in Xamarin.Forms. Thanks to that we could easily differentiate between WebView and mobile browser on the webpage.
On this website it is described how to set custom user agent on Android
https://mobiforge.com/research-analysis/webviews-and-user-agent-strings
In order to set custom user agent for a webview with x:Name ="webView" we could write something like this:
webView.setUserAgentString("My funky UA string")
This should work for Android and iOS
Thanks to that feature we would be able to easily differentiate between webview traffic and browser traffic.
Does anyone knows a workaround to implement this?
Really there is no solution?
On iOS this is possible via CustomUserAgent property
https://docs.microsoft.com/en-us/dotnet/api/webkit.wkwebview.customuseragent?view=xamarin-ios-sdk-12
Thanks for the suggestion! It seems indeed that there is no way to do this right now. If it's something we can do for all platforms we might be able to easily do this. An issue that is also linked to this is #6340 which will allow you to add your own delegates without breaking the Xamarin.Forms navigation events etc.
@jfversluis
If it's something we can do for all platforms we might be able to easily do this.
I think it is easy to implement that feature on Android and iOS.
On iOS WKWebView has CustomUserAgent property.
On Android it is also easy:
webview.Setting.UserAgentString = "my custom user agent"
@Mikilll94 I'll gladly see that PR incoming 😉
Do you have any idea about UWP?
@jfversluis
I have no idea about UWP. I don't use UWP. But I have found these links:
https://www.pedrolamas.com/2017/03/21/setting-a-custom-user-agent-in-the-uwp-webview-control/
https://stackoverflow.com/questions/39490430/change-default-user-agent-in-webview-uwp
I think setting custom user agent for UWP is much harder than for iOS and Android. Maybe we can just skip UWP if there is no clean way to implement this?
Implementing a solution like this will require to support at least Android, iOS and UWP
@jfversluis
I think there is no easy solution to set custom user agent for WebView. Maybe you can just give user a possibility to set this property in any way, i.e. platform specific, property which does have no effect on UWP? The problem is that right now there is no way set custom user agent, because of #8708. Even when using custom renderer, you cannot set this property without breaking navigation events.
@jfversluis
Or maybe you know some workaround to set custom user agent on Android and iOS without breaking navigation events?
I'm afraid there is no real workaround for the time being, at least not one that I can see right now. Sorry about that.
@jfversluis
Hello,
I have partially solved my problem. I have successfully set custom agent for Android WebView without breaking navigation events.
Here is the custom renderer for Android:
using Android.Content;
using App2.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(WebView), typeof(CustomWebViewRenderer))]
namespace App2.Droid
{
public class CustomWebViewRenderer : WebViewRenderer
{
private readonly Context _context;
public CustomWebViewRenderer(Context context) : base(context)
{
_context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
Control.SetWebViewClient(GetWebViewClient());
Control.Settings.UserAgentString = "Custom user agent!";
}
}
}
}
Here is the full project:
App2.zip
However, I don't know how to implement something like this for WKWebView on iOS. Maybe you have an idea? :)
Actually... Isn't it just as simple as
using System;
using App2.iOS;
using WebKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(WebView), typeof(CustomWebViewRenderer))]
namespace App2.iOS
{
public class CustomWebViewRenderer : WkWebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
CustomUserAgent = "Super Secret Agent 007";
}
}
}
}
If you are happy I think I might have a solution to the UWP part of this from a prior project and as the Droid and IOS look fairly simple I might be able to sumbit a PR for all 3.
Can you show me as taking a swing at this one unless anyone else is already doing it.
@CliffAgius
Feel free to submit a PR. Nobody has started this feature.
However, in my recent project, I have implemented a custom user agent for Android and iOS WebView and I noticed one thing which needs to be considered in the PR.
I think in most cases people would like to just append a custom string to the existing user agent string instead of completely replacing user agent string with a custom one. Thus using "CustomUserAgent" on iOS property is not ok, because it replaces the whole user agent string with someting different. Instead on iOS I have used "ApplicationNameForUserAgent" property in "WKWebViewConfiguratio" which just appends a custom string to the user agent string.
@Mikilll94 good idea I hadn't thought of that adds a different slant.
The API change suggestion at the top says:
webView.setUserAgentString("My funky UA string")
So do you think this should be for setting the UA so it's on the Dev to worry about the exisiting UA string or maybe a SetUserAgentString and another BindableProperty that is AppendUserAgentString that adds to the exisiting.
The reason I ask is that my project requires that the UA is set to a known value not appended to the current hence the idea.
Thoughts?
@CliffAgius
It would be great to have two Bindable Properties: UserAgentString
and UserAgentStringAppend
In my case, I wanted to append user agent string because i.e. Facebook website looks very strange on mobiles if you completely replace user agent string.
Skipping over the implementation details, but just confirming; @CliffAgius if you want to take this, please feel free to do so :)
I found a way to change UserAgent with customized "Xam.Plugin.Webview."
void SetupControl()
{
_navigationDelegate = new FormsNavigationDelegate(this);
_contentController = new WKUserContentController();
_contentController.AddScriptMessageHandler(this, "invokeAction");
_configuration = new WKWebViewConfiguration {
UserContentController = _contentController
};
var wkWebView = new WKWebView(Frame, _configuration)
{
Opaque = false,
UIDelegate = this,
NavigationDelegate = _navigationDelegate
};
wkWebView.CustomUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15"; // You can change UserAgent like this.
FormsWebView.CallbackAdded += OnCallbackAdded;
SetNativeControl(wkWebView);
OnControlChanged?.Invoke(this, wkWebView);
}
Most helpful comment
@jfversluis
I think it is easy to implement that feature on Android and iOS.
On iOS WKWebView has CustomUserAgent property.
On Android it is also easy: