There is a blazor webassembly website and I need to store the latest url that user displays in a webview in a MAUI app.
I created a WebViewRenderer and gave a new custom webviewclient via SetWebViewClient method. But unfortunately no method in the WebViewclient is triggered/hit.
The app hits the ConnectHandler so it means that I can successfully connect to handler. I give you anyway my code but not sure if it really helps.
[assembly: ExportRenderer(typeof(Microsoft.Maui.Controls.WebView), typeof(MyWebViewRenderer))]
namespace MiniApp.Platforms.Android
{
public class MyWebViewRenderer : WebViewHandler
{
CustomWebViewClient webclient;
public MyWebViewRenderer()
{
webclient = new CustomWebViewClient();
}
protected override void ConnectHandler(global::Android.Webkit.WebView platformView)
{
//platformView.SetWebViewClient(new CustomWebViewClient());
base.ConnectHandler(platformView);
}
protected override global::Android.Webkit.WebView CreatePlatformView()
{
var platformView = base.CreatePlatformView();
platformView.SetWebViewClient(webclient);
return platformView;
}
}
public class CustomWebViewClient : WebViewClient
{
public override void OnPageStarted(global::Android.Webkit.WebView? view, string? url, Bitmap? favicon)
{
base.OnPageStarted(view, url, favicon);
}
public override void DoUpdateVisitedHistory(global::Android.Webkit.WebView? view, string? url, bool isReload)
{
base.DoUpdateVisitedHistory(view, url, isReload);
}
public override void OnFormResubmission(global::Android.Webkit.WebView? view, Message? dontResend, Message? resend)
{
base.OnFormResubmission(view, dontResend, resend);
}
public override void OnLoadResource(global::Android.Webkit.WebView? view, string? url)
{
base.OnLoadResource(view, url);
}
public override void OnPageCommitVisible(global::Android.Webkit.WebView? view, string? url)
{
base.OnPageCommitVisible(view, url);
}
public override void OnPageFinished(global::Android.Webkit.WebView? view, string? url)
{
base.OnPageFinished(view, url);
}
public override void OnReceivedClientCertRequest(global::Android.Webkit.WebView? view, ClientCertRequest? request)
{
base.OnReceivedClientCertRequest(view, request);
}
public override bool OnRenderProcessGone(global::Android.Webkit.WebView? view, RenderProcessGoneDetail? detail)
{
return base.OnRenderProcessGone(view, detail);
}
public override bool ShouldOverrideUrlLoading(global::Android.Webkit.WebView? view, IWebResourceRequest? request)
{
return base.ShouldOverrideUrlLoading(view, request);
}
public override bool ShouldOverrideUrlLoading(global::Android.Webkit.WebView? view, string? url)
{
return base.ShouldOverrideUrlLoading(view, url);
}
public override void OnUnhandledInputEvent(global::Android.Webkit.WebView? view, InputEvent? e)
{
base.OnUnhandledInputEvent(view, e);
}
public override void OnScaleChanged(global::Android.Webkit.WebView? view, float oldScale, float newScale)
{
base.OnScaleChanged(view, oldScale, newScale);
}
public override void OnSafeBrowsingHit(global::Android.Webkit.WebView? view, IWebResourceRequest? request, [GeneratedEnum] SafeBrowsingThreat threatType, SafeBrowsingResponse? callback)
{
base.OnSafeBrowsingHit(view, request, threatType, callback);
}
}
}
Is there a way to catch the url when user navigates?
PS: I use vs 2022 and .net 8.0 framework
I created a new project and reproduce your problem. It appears to be a new issue in the .net 8.0. You can report it on the github repo.
In addition, you can try to use the custom handler in the page's OnHandlerChanged method as a workaround.
In the xaml:
<Webview x:Name="webview" Source=""/>
And in the code behind:
protected override void OnHandlerChanged()
{
base.OnHandlerChanged();
#if ANDROID
(webview.Handler.PlatformView as Android.Webkit.WebView).SetWebViewClient(new Platforms.Android.MyClient());
#endif
}
And the WebViewClent class:
namespace MauiApp.Platforms.Android
{
public class MyClient : WebViewClient
{
public override bool ShouldOverrideUrlLoading(global::Android.Webkit.WebView? view, IWebResourceRequest? request)
{
var url = request.Url.ToString();
// this is the url
return base.ShouldOverrideUrlLoading(view, request);
}
}
}
Furthermore, the [assembly: ExportRenderer(typeof(Microsoft.Maui.Controls.WebView), typeof(MyWebViewRenderer))]
should be delete because it is used in xamarin.forms not maui.
Update:
For the windows, you can use the webview's navigated event to do that:
In the xaml:
<WebView Navigated="webview_Navigated" HeightRequest="800" x:Name="webview"
In the code behind:
private void webview_Navigated(object sender, WebNavigatedEventArgs e)
{
#if WINDOWS
var webview2 = webview.Handler.PlatformView as Microsoft.UI.Xaml.Controls.WebView2;
var url = webview2.Source.ToString();
#endif
}
Update2:
For the iOS, you can refer to this case: Capture redirect url in wkwebview in ios, or just debug to check which method of the WKNavigationDelegate
will be called.
And for the Windows, you can check the official document: Navigation events for WebView2 apps. And you can also debug to check which event will be called. Such as:
protected override void OnHandlerChanged()
{
base.OnHandlerChanged();
#if ANDROID
(webview.Handler.PlatformView as Android.Webkit.WebView).SetWebViewClient(new Platforms.Android.MyClient());
#elif WINDOWS
var webview2 = webview.Handler.PlatformView as Microsoft.UI.Xaml.Controls.WebView2;
var url = webview2.Source.ToString();
webview2.CoreWebView2.HistoryChanged += (s,e) =>
{
var url = s.Source;
};
webview2.CoreWebView2.SourceChanged += (s, e) =>
{
var url = s.Source;
};
// and the other event
#endif
}
Solution:
For the android, use the custom handler above and over ride the DoUpdateVisitedHistory method.
For the windows, use the webview2's event above.
For the iOS, refer to op's solution on the github.