PM-3349 Implemented HybridWebViewHandler for iOS

This commit is contained in:
Dinis Vieira 2023-10-07 23:44:24 +01:00
parent c92cd90a97
commit d63a219272
No known key found for this signature in database
GPG key ID: 9389160FF6C295F3
3 changed files with 86 additions and 2 deletions

View file

@ -15,6 +15,7 @@
}, },
handlers => handlers =>
{ {
handlers.AddHandler(typeof(Bit.App.Controls.HybridWebView), typeof(Bit.App.Handlers.HybridWebViewHandler));
#if ANDROID #if ANDROID
Bit.App.Handlers.EntryHandlerMappings.Setup(); Bit.App.Handlers.EntryHandlerMappings.Setup();
Bit.App.Handlers.EditorHandlerMappings.Setup(); Bit.App.Handlers.EditorHandlerMappings.Setup();
@ -29,7 +30,6 @@
Bit.App.Handlers.ButtonHandlerMappings.Setup(); Bit.App.Handlers.ButtonHandlerMappings.Setup();
handlers.AddHandler(typeof(Bit.App.Pages.TabsPage), typeof(Bit.App.Handlers.CustomTabbedPageHandler)); handlers.AddHandler(typeof(Bit.App.Pages.TabsPage), typeof(Bit.App.Handlers.CustomTabbedPageHandler));
handlers.AddHandler(typeof(Bit.App.Controls.HybridWebView), typeof(Bit.App.Handlers.HybridWebViewHandler));
#else #else
iOS.Core.Utilities.iOSCoreHelpers.ConfigureMAUIHandlers(handlers); iOS.Core.Utilities.iOSCoreHelpers.ConfigureMAUIHandlers(handlers);
#endif #endif

View file

@ -25,7 +25,7 @@ namespace Bit.App.Handlers
public static void MapUri(HybridWebViewHandler handler, HybridWebView view) public static void MapUri(HybridWebViewHandler handler, HybridWebView view)
{ {
if (view != null && view.Uri != null) if (view != null && view?.Uri != null)
{ {
handler?.PlatformView?.LoadUrl(view.Uri); handler?.PlatformView?.LoadUrl(view.Uri);
} }

View file

@ -0,0 +1,84 @@
using System.Diagnostics.CodeAnalysis;
using Bit.App.Controls;
using CoreGraphics;
using Foundation;
using Microsoft.Maui.Handlers;
using WebKit;
namespace Bit.App.Handlers
{
public partial class HybridWebViewHandler : ViewHandler<HybridWebView, WebKit.WKWebView>
{
private const string JSFunction =
"function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";
private WKUserContentController _userController;
public HybridWebViewHandler([NotNull] IPropertyMapper mapper, CommandMapper commandMapper = null) : base(mapper, commandMapper)
{
}
protected override WKWebView CreatePlatformView()
{
_userController = new WKUserContentController();
var script = new WKUserScript(new NSString(JSFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
_userController.AddUserScript(script);
_userController.AddScriptMessageHandler(new WebViewScriptMessageHandler(InvokeAction), "invokeAction");
var config = new WKWebViewConfiguration { UserContentController = _userController };
var webView = new WKWebView(CGRect.Empty, config);
return webView;
}
public static void MapUri(HybridWebViewHandler handler, HybridWebView view)
{
if (handler != null && view?.Uri != null)
{
handler?.PlatformView?.LoadRequest(new NSUrlRequest(new NSUrl(view.Uri)));
}
}
protected override void ConnectHandler(WKWebView platformView)
{
if (VirtualView?.Uri != null)
{
platformView?.LoadRequest(new NSUrlRequest(new NSUrl(VirtualView?.Uri)));
}
base.ConnectHandler(platformView);
}
protected override void DisconnectHandler(WKWebView platformView)
{
_userController.RemoveAllUserScripts();
_userController.RemoveScriptMessageHandler("invokeAction");
platformView?.Dispose();
VirtualView?.Cleanup();
_userController = null;
base.DisconnectHandler(platformView);
}
private void InvokeAction(WKScriptMessage message)
{
if(message?.Body != null)
{
VirtualView?.InvokeAction(message.Body.ToString());
}
}
}
public class WebViewScriptMessageHandler : NSObject, IWKScriptMessageHandler
{
private Action<WKScriptMessage> _messageReceivedAction;
public WebViewScriptMessageHandler(Action<WKScriptMessage> messageReceivedAction)
{
_messageReceivedAction = messageReceivedAction ?? throw new ArgumentNullException(nameof(messageReceivedAction));
}
public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
{
_messageReceivedAction(message);
}
}
}