我正在开发 Xamarin.Forms应用程序,在这里我需要集成WebView
来通过外部URL 管理预订。
所以基本上我已经做到了这一点:
我想管理用户在打开此页面时可能会遇到的一些错误:无互联网访问,超时,服务器不可用,...<WebView x:Name="webView" Source="{Binding BookingUrl}"
WidthRequest="1000" HeightRequest="1000">
为此,我使用了EventToCommandBehavior
来访问 ViewModel 中的事件Navigating
和Navigating
。
所以我的 XAML 看起来像这样:
ViewModel 像这样:<WebView x:Name="webView" Source="{Binding AvilaUrlBooking}"
WidthRequest="1000" HeightRequest="1000">
<WebView.Behaviors>
<behaviors:EventToCommandBehavior
EventName="Navigating"
Command="{Binding NavigatingCommand}" />
<behaviors:EventToCommandBehavior
EventName="Navigated"
Command="{Binding NavigatedCommand}" />
</WebView.Behaviors>
</WebView>
如果我使用正确的URL,则在iOS和Android上都可以正常使用。public ICommand NavigatingCommand
{
get
{
return new Xamarin.Forms.Command<WebNavigatingEventArgs>(async (x) =>
{
if (x != null)
{
await WebViewNavigatingAsync(x);
}
});
}
}
private Task WebViewNavigatingAsync(WebNavigatingEventArgs eventArgs)
{
if (!IsConnected)
ServiceErrorKind = ServiceErrorKind.NoInternetAccess;
IsBusy = true;
return Task.CompletedTask;
}
public ICommand NavigatedCommand
{
get
{
return new Xamarin.Forms.Command<WebNavigatedEventArgs>(async (x) =>
{
if (x != null)
{
await WebViewNavigatedAsync(x);
}
});
}
}
private Task WebViewNavigatedAsync(WebNavigatedEventArgs eventArgs)
{
IsBusy = false;
IsFirstDisplay = false;
switch (eventArgs.Result)
{
case WebNavigationResult.Cancel:
// TODO - do stuff here
break;
case WebNavigationResult.Failure:
// TODO - do stuff here
break;
case WebNavigationResult.Success:
// TODO - do stuff here
break;
case WebNavigationResult.Timeout:
// TODO - do stuff here
break;
default:
// TODO - do stuff here
break;
}
return Task.CompletedTask;
}
bool isFirstDisplay;
public bool IsFirstDisplay
{
get { return isFirstDisplay; }
set { SetProperty(ref isFirstDisplay, value); }
}
public BookingViewModel()
{
_eventTracker = new AppCenterEventTracker();
IsFirstDisplay = true;
Title = "Booking";
IsConnected = Connectivity.NetworkAccess == NetworkAccess.Internet;
Connectivity.ConnectivityChanged += OnConnectivityChanged;
}
但是,如果我使用“错误的” URL(例如,缺少字符),则仅适用于 Android :WebNavigationResult.Failure
是在WebViewNavigatedAsync()
中捕获的情况,但我没有在 iOS 上输入WebViewNavigatedAsync()
。
=>这正常吗?
我已经实现了“刷新”按钮来管理“无法访问”错误。可通过ToolBarItem
访问此按钮,就像在 ViewModel 中这样:
但是在这种情况下,在激活飞行模式后,我也有两种不同的行为:public void Refresh(object sender)
{
try
{
var view = sender as Xamarin.Forms.WebView;
view.Reload();
}
catch (Exception ex)
{
}
}
上的WebViewNavigatedAsync()
,并且我单击“刷新”按钮,我只通过了WebViewNavigatingAsync()
上的WebViewNavigatedAsync()
,并且当互联网再次可用时,我单击“刷新”按钮,我同时通过了WebViewNavigatingAsync()
和WebViewNavigatedAsync()
=>这正常吗?有适当的方法来解决这个问题吗?
最佳答案
is this normal?
根据我的测试。是的,我得到了相同的结果,如果我们输入错误的URL,则Webview在iOS中始终为空白 View 。因此
NavigatedCommand
无法执行。如果我们使用正确的url,则webview可能会执行
NavigatedCommand
,并产生如下屏幕截图所示的运行结果。Is there a proper way to manager this?
我们可以在iOS中为Webview使用自定义渲染器来处理这种情况。
[assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))]
namespace MyCarsourlView.iOS
{
[Obsolete]
class CustomWebViewRenderer : WebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.OldElement == null) { Delegate = new CustomWebViewDelegate(); }
}
}
}
internal class CustomWebViewDelegate : UIWebViewDelegate
{
#region Event Handlers
public override bool ShouldStartLoad(UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType)
{
//Could add stuff here to redirect the user before the page loads, if you wanted to redirect the user you would do the redirection and then return false
return true;
}
public override void LoadFailed(UIWebView webView, NSError error)
{
Console.WriteLine("\nIn AppName.iOS.CustomWebViewRenderer - Error: {0}\n", error.ToString()); //TODO: Do something more useful here
//Here, you can test to see what kind of error you are getting and act accordingly, either by showing an alert or rendering your own custom error page using basic HTML
}
public override void LoadingFinished(UIWebView webView)
{ //You could do stuff here such as collection cookies form the WebView }
#endregion
}
}
如果我输入了错误的URL,则可以执行LoadFailed
。关于c# - WebView和错误管理,怎么了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64615003/