Skip to content

Commit

Permalink
Merge pull request #8 from Axemasta/Fix/7
Browse files Browse the repository at this point in the history
Fixed Crash On iOS When Changing WebView Source
  • Loading branch information
Axemasta authored Jun 23, 2021
2 parents 6afa315 + 9fa7287 commit c7f5b69
Showing 1 changed file with 32 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using CoreFoundation;
using Foundation;
using WebKit;
using Xamarin.Forms;
Expand Down Expand Up @@ -189,6 +190,7 @@ public override void DecidePolicy(WKWebView webView, WKNavigationAction navigati
if (!args.DeferralRequested)
{
decisionHandler(WKNavigationActionPolicy.Allow);
return;
}
}

Expand Down Expand Up @@ -246,22 +248,44 @@ async Task NavigatingDeterminedCallback(SuperWebNavigatingEventArgs args, Action
* Completion handler passed to -[Xamarin_Forms_Platform_iOS_WkWebViewRenderer_CustomWebViewNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:] was not called
*/

Func<Task> navigationTask = () => Task.Run(() => DetermineNavigating(args, decisionHandler));
/*
* The previous implementation was causing a crash when the UI invoked a url change by performing
* an action like pressing a Button and updating the SuperWebView source.
*
* The crash had very limited diagnostics but here is a diagnostic from the simulator:
* 10:06:35.541054+0100 com.apple.CoreSimulator.SimDevice.00000000-0000-0000-0000-000000000000
* (UIKitApplication:com.axemasta.SuperWebViewSample[f025][rb-legacy][86754])
* Service exited due to SIGTRAP
*
* I found the following xamarin-macios posts:
* https://github.com/xamarin/xamarin-macios/issues/4130
* https://github.com/xamarin/xamarin-macios/pull/4312/files
*
* It looks like when blocking a thread, it must be released back on the main thread otherwise the WKWebView
* will crash. I have updated the implementation to directly access the iOS threads because Device.BeginInvoke...
* was still causing the issue to occur
*/

Action action = () => DetermineNavigating(args, decisionHandler);

if (NSThread.IsMain)
{
action.Invoke();
return;
}

if (Device.IsInvokeRequired)
await Device.InvokeOnMainThreadAsync(navigationTask);
else
await navigationTask();
DispatchQueue.MainQueue.DispatchSync(action);
}

void DetermineNavigating(SuperWebNavigatingEventArgs args, Action<WKNavigationActionPolicy> decisionHandler)
{

var action = args.Cancelled ? WKNavigationActionPolicy.Cancel : WKNavigationActionPolicy.Allow;

if (action == WKNavigationActionPolicy.Cancel)
WebView.SendNavigationCancelled(new NavigationCancelledEventArgs(args.Url));

decisionHandler(action);
}
}
decisionHandler(action);
}
}
}

0 comments on commit c7f5b69

Please sign in to comment.