是否可以使用Xamarin.iOS将字符串从C#返回到Javascript?

时间:2017-07-20 10:58:58

标签: javascript c# ios xamarin xamarin.ios

我使用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附加了一些内容

1 个答案:

答案 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#。