我使用HybridWebView from XLabs构建了一个可以与C#代码通信的HybridWebView。我已经构建了自定义渲染器来执行此操作。简单来说,我有:
的iOS
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, WKWebView>, IWKScriptMessageHandler
{
const string JavaScriptFunctionTemplate = "function {0}(){{window.webkit.messageHandlers.invokeAction.postMessage('{0}|' + JSON.stringify(arguments));}}";
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
userController = new WKUserContentController();
foreach (var f in Element.RegisteredFunctions.Where(ff => !ff.IsInjected))
{
var script = new WKUserScript(new NSString(string.Format(JavaScriptFunctionTemplate, f.Name)), WKUserScriptInjectionTime.AtDocumentEnd, false);
userController.AddUserScript(script);
f.Injected();
}
userController.AddScriptMessageHandler(this, "invokeAction");
var config = new WKWebViewConfiguration { UserContentController = userController };
var webView = new WKWebView(Frame, config)
{
NavigationDelegate = new CustomWKNavigationDelegate(this.Element)
};
SetNativeControl(webView);
}
if (e.OldElement != null)
{
userController.RemoveAllUserScripts();
userController.RemoveScriptMessageHandler("invokeAction");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
}
if (e.NewElement != null)
{
Load(Element.Uri);
}
}
public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
{
var bits = message.Body.ToString().Split('|');
if (bits.Count() == 2)
{
var result = Element.InvokeFunction(bits[0], bits[1]);
//How do I return result back to Javascript function?
}
}
InvokeFunction
方法返回值为result
的字符串。
如何将此字符串result
返回到已注入的javascript函数?
修改
我是否需要修改JavaScriptFunctionTemplate
我在XLabs中注意到他们有类似的template,但在end附加了一些内容
答案 0 :(得分:1)
你有什么理由不能简单地“重新打电话”。使用方法described here?
的函数他们的例子:
void OnCallJavaScriptButtonClicked (object sender, EventArgs e)
{
...
int number = int.Parse (numberEntry.Text);
int end = int.Parse (stopEntry.Text);
webView.Eval (string.Format ("printMultiplicationTable({0}, {1})", number, end));
}
所以你的会是这样的:
const string JavaScriptFunctionTemplate = "function {0}(){{window.webkit.messageHandlers.invokeAction.postMessage('{0}|' + JSON.stringify(arguments));}}";
public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
{
var bits = message.Body.ToString().Split('|');
if (bits.Count() == 2)
{
var result = Element.InvokeFunction(bits[0], bits[1]);
webView.Eval(string.Format ("JavaScriptFunctionTemplate({0})", result)); // or however your parameter structure is.
}
}
修改强>
只想加入OP发现的LINK,因为它看起来是Objective-C中解决方案的坚实指南,这很容易转换为Xamarin C#。