Skip to content

Commit

Permalink
[iOS] Fix crash closing Popup with WebView (#21923)
Browse files Browse the repository at this point in the history
* [iOS] Fix crash closing Popup with WebView (#21718)

* Added repro sample

* Fix the issue

* Added UI Test

* Updated csproj

* More changes

* Removed sample and test

* More changes

* Removed unnecesary changes

* Added UITest

* Update Issue21846.xaml.cs

* Update Issue21846Modal.xaml.cs

* Update Issue21846.cs

---------

Co-authored-by: Javier Suárez <[email protected]>
  • Loading branch information
PureWeen and jsuarezruiz authored Apr 18, 2024
1 parent 9fd58d7 commit 94d4aa2
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.Issues.Issue21846"
xmlns:ns="clr-namespace:Maui.Controls.Sample.Issues">
<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Button
x:Name="TestButton"
AutomationId="OpenModalButton"
Text="Open"
Clicked="OnButtonClicked" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using Microsoft.Maui;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.Xaml;

namespace Maui.Controls.Sample.Issues
{
[XamlCompilation(XamlCompilationOptions.Compile)]
[Issue(IssueTracker.Github, 21846, "Fix crash closing Popup with WebView", PlatformAffected.iOS)]
public partial class Issue21846 : ContentPage
{
public Issue21846()
{
InitializeComponent();
}

async void OnButtonClicked(object sender, System.EventArgs e)
{
await Navigation.PushModalAsync(new Issue21846Modal());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.Issues.Issue21846Modal"
xmlns:ns="clr-namespace:Maui.Controls.Sample.Issues">
<ScrollView>
<Grid
RowDefinitions="*, Auto"
Padding="30,0">
<WebView
x:Name="TestWebView"
Source="https://www.microsoft.com"/>
<Button
Grid.Row="1"
AutomationId="CloseModalButton"
Text="Close"
Clicked="OnButtonClicked" />
</Grid>
</ScrollView>
</ContentPage>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using Microsoft.Maui;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.Xaml;

namespace Maui.Controls.Sample.Issues
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Issue21846Modal : ContentPage
{
public Issue21846Modal()
{
InitializeComponent();

BindingContext = this;
}

async void OnButtonClicked(object sender, System.EventArgs e)
{
if (TestWebView is IElement visualElement)
{
if (visualElement.Handler != null)
{
if (visualElement.Handler is IDisposable disposableHandler)
disposableHandler.Dispose();

visualElement.Handler.DisconnectHandler();
}
}

await Navigation.PopModalAsync();
}
}
}
28 changes: 28 additions & 0 deletions src/Controls/tests/UITests/Tests/Issues/Issue21846.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.AppiumTests.Issues
{
public class Issue21846 : _IssuesUITest
{
public Issue21846(TestDevice device) : base(device)
{
}

public override string Issue => "Fix crash closing Popup with WebView";

[Test]
[Category(UITestCategories.WebView)]
public void WebViewNoCrashPopup()
{
this.IgnoreIfPlatforms([TestDevice.Android, TestDevice.Windows]);

App.WaitForElement("OpenModalButton");
App.Click("OpenModalButton");

App.WaitForElement("CloseModalButton");
App.Click("CloseModalButton");
}
}
}
41 changes: 32 additions & 9 deletions src/Core/src/Platform/iOS/MauiWebViewNavigationDelegate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@ public MauiWebViewNavigationDelegate(IWebViewHandler handler)
public void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
var handler = Handler;

if (handler is null || !handler.IsConnected())
return;

var platformView = handler?.PlatformView;
var virtualView = handler?.VirtualView;

if (handler == null || virtualView == null)
if (platformView is null || virtualView is null)
return;

handler.PlatformView?.UpdateCanGoBackForward(handler.VirtualView);
platformView.UpdateCanGoBackForward(virtualView);

if (webView.IsLoading)
return;
Expand All @@ -47,49 +52,67 @@ public void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
if (handler is WebViewHandler webViewHandler)
webViewHandler.ProcessNavigatedAsync(url).FireAndForget();
else
handler.PlatformView?.UpdateCanGoBackForward(virtualView);
platformView.UpdateCanGoBackForward(virtualView);
}

[Export("webView:didFailNavigation:withError:")]
public void DidFailNavigation(WKWebView webView, WKNavigation navigation, NSError error)
{
var handler = Handler;

if (handler is null || !handler.IsConnected())
return;

var platformView = handler?.PlatformView;
var virtualView = handler?.VirtualView;

if (handler == null || virtualView == null)
if (platformView is null || virtualView is null)
return;

var url = GetCurrentUrl();

virtualView.Navigated(_lastEvent, url, WebNavigationResult.Failure);

handler.PlatformView?.UpdateCanGoBackForward(virtualView);
platformView.UpdateCanGoBackForward(virtualView);
}

[Export("webView:didFailProvisionalNavigation:withError:")]
public void DidFailProvisionalNavigation(WKWebView webView, WKNavigation navigation, NSError error)
{
var handler = Handler;

if (handler is null || !handler.IsConnected())
return;

var platformView = handler?.PlatformView;
var virtualView = handler?.VirtualView;

if (handler == null || virtualView == null)
if (platformView is null || virtualView is null)
return;

var url = GetCurrentUrl();

virtualView.Navigated(_lastEvent, url, WebNavigationResult.Failure);

handler.PlatformView?.UpdateCanGoBackForward(virtualView);
platformView.UpdateCanGoBackForward(virtualView);
}

// https://stackoverflow.com/questions/37509990/migrating-from-uiwebview-to-wkwebview
[Export("webView:decidePolicyForNavigationAction:decisionHandler:")]
public void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction, Action<WKNavigationActionPolicy> decisionHandler)
{
var handler = Handler;

if (handler is null || !handler.IsConnected())
{
decisionHandler.Invoke(WKNavigationActionPolicy.Cancel);
return;
}

var platformView = handler?.PlatformView;
var virtualView = handler?.VirtualView;

if (handler == null || virtualView == null)
if (platformView is null || virtualView is null)
{
decisionHandler.Invoke(WKNavigationActionPolicy.Cancel);
return;
Expand Down Expand Up @@ -130,7 +153,7 @@ public void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction,
var lastUrl = request.Url.ToString();

bool cancel = virtualView.Navigating(navEvent, lastUrl);
handler.PlatformView?.UpdateCanGoBackForward(virtualView);
platformView.UpdateCanGoBackForward(virtualView);
decisionHandler(cancel ? WKNavigationActionPolicy.Cancel : WKNavigationActionPolicy.Allow);
}

Expand Down

0 comments on commit 94d4aa2

Please sign in to comment.