94 lines
3.3 KiB
C#
94 lines
3.3 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
using Bit.App.Controls;
|
|
using CoreGraphics;
|
|
using Foundation;
|
|
using Microsoft.Maui.Handlers;
|
|
using WebKit;
|
|
|
|
namespace Bit.iOS.Core.Handlers
|
|
{
|
|
public class HybridWebViewHandler : ViewHandler<HybridWebView, WebKit.WKWebView>
|
|
{
|
|
private const string JSFunction =
|
|
"function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";
|
|
|
|
private WKUserContentController _userController;
|
|
|
|
public static PropertyMapper<HybridWebView, HybridWebViewHandler> PropertyMapper = new PropertyMapper<HybridWebView, HybridWebViewHandler>(ViewHandler.ViewMapper)
|
|
{
|
|
[nameof(HybridWebView.Uri)] = MapUri
|
|
};
|
|
|
|
public HybridWebViewHandler() : base(PropertyMapper)
|
|
{
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|