Passing data between WebView and host application

ぃ、小莉子 提交于 2020-01-05 04:29:09

问题


I'm starting development of mobile application connected to web project that let's patients take notes of their bleedings. On web the user can click and select certain places on few human figures. One with some selection looks like this

I don't really think this would be easy to achieve using standard controls(?), so I thought it would be the easiest to use a WebView that would host the piece of code that handles selection.

To set the locations e.g when user wants to edit old bleeding I could just follow Xamarin guide on how to call JS from C#, however, the return value is void. I haven't been able to find a way how to get data from Xamarin.Forms.WebView. Any suggestions?


回答1:


This highly depends on what platforms and version of platforms your are trying to target.

If you really want to use a WebView, you might check out the XLabs Hybrid WebView which does something similar I believe.

Other than XLabs' methods, you can easily get back a string from an iOS renderer using the UIWebView.EvaluateJavascript() method and then you can always override WebChromClient.OnJsAlert in a Xamarin Android WebView renderer (link), which I have successfully used back to Android 4.1.

Something like (Let me know if something does not work or is missing, I typed this out and removed extra code so there may be minor issues)...

Xamarin Forms Code:

public class SomethingWebView : WebView { }

iOS WebView Renderer with UIWebViewDelegate:

[assembly: Xamarin.Forms.ExportRenderer(typeof(SomethingWebView), typeof(Your.Droid.Namespace.SomethingWebViewRenderer))]

namespace Your.Droid.Namespace.Renderer {

public class SomethingWebViewRenderer : WebViewRenderer {

    protected override void OnElementChanged(VisualElementChangedEventArgs e) {
        base.OnElementChanged(e);

        if(e.OldElement == null) {
            Delegate = new SomethingWebViewDelegate();
        }
    }
}

internal class SomethingWebViewDelegate : UIWebViewDelegate {

    public override void LoadingFinished(UIWebView webView) {
        string something = webView.EvaluateJavascript("(function() { return 'something'; })()");
    }
}
}

Android WebView Renderer with WebViewClient and WebChromeClient:

[assembly: Xamarin.Forms.ExportRenderer(typeof(SomethingWebView), typeof(Your.iOS.Namespace.SomethingWebViewRenderer))]

namespace Your.iOS.Namespace.Renderer {

public class SomethingWebViewRenderer : WebViewRenderer {

    protected override void OnElementChanged(ElementChangedEventArgs<WebView> e) {

        base.OnElementChanged(e);

        if(e.OldElement == null) {

            Control.Settings.JavaScriptEnabled = true;

            Control.SetWebViewClient(new SomethingWebViewClient());

            Control.SetWebChromeClient(new SomethingWebChromeClient());
        }
    }
}

internal class SomethingWebViewClient : WebViewClient {

    public override void OnPageFinished(Android.Webkit.WebView view, string url) {
        base.OnPageFinished(view, url);

        view.LoadUrl("javascript:{(function() { window.alert('something'); })()};");
    }
}

public class SomethingWebChromeClient : WebChromeClient {

    public override bool OnJsAlert(Android.Webkit.WebView view, string url, string message, JsResult result) {

        if(message.StartsWith("something") { //This is where you would look for your magic string, anything starting with your magic string is what you would extract and/or act on
            //Do something....

            result.Cancel(); //This cancels the JS alert (there are other talked about methods of doing this but this works for me)
            return true; //This tells the WebView "we got this"
        }

        return base.OnJsAlert(view, url, message, result); //Let the WebView handle this since we did not find out special string
    }
}
}

Finally, another method I looked at involved using JavaScript to redirect the page to a new URL, then in the event that is used to tell the WebView whether or not it should go forward with the redirect, you pull out the WebView's current URL and, if you find your magic string, you do something. This would have worked great except for the fact that URLs can only be like 255 characters long so it would not work for my needs.



来源:https://stackoverflow.com/questions/39584576/passing-data-between-webview-and-host-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!