Reputation: 980
I am trying to create a hybrid webview which is going to get its html data from the web api, the data which api is returning is in the form of string. The problem which i am facing right now i am not able to bind or load the url of web on my hybrid webview i am not able to understand where the thing has to be change.
Here is the code which i have tried till now but could not make it work
here is custom control
public class HybridWebView : View
{
Action<string> action;
public static readonly BindableProperty UriProperty = BindableProperty.Create(
propertyName: "Uri",
returnType: typeof(string),
declaringType: typeof(HybridWebView),
defaultValue: default(string));
public string Uri
{
get { return (string)GetValue(UriProperty); }
set { SetValue(UriProperty, value); }
}
public void RegisterAction(Action<string> callback)
{
action = callback;
}
public void Cleanup()
{
action = null;
}
public void InvokeAction(string data)
{
if (action == null || data == null)
{
return;
}
action.Invoke(data);
}
}
Here is my custom renderer for Android
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, Android.Webkit.WebView>
{
const string JavascriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
Context _context;
public HybridWebViewRenderer(Context context) : base(context)
{
_context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var webView = new Android.Webkit.WebView(_context);
webView.Settings.JavaScriptEnabled = true;
webView.SetWebViewClient(new JavascriptWebViewClient($"javascript: {JavascriptFunction}"));
webView.Settings.BuiltInZoomControls = true;
webView.Settings.DisplayZoomControls = false;
webView.Settings.LoadWithOverviewMode = true;
webView.Settings.UseWideViewPort = true;
Control.LoadUrl($"{Element.Uri}");
SetNativeControl(webView);
}
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
}
if (e.NewElement != null)
{
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
///Control.LoadUrl($"{Element.Uri}");
}
}}
Here is my IOS Renderer
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, WKWebView>, IWKScriptMessageHandler
{
const string JavaScriptFunction = "function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";
WKUserContentController userController;
protected override void OnElementChanged (ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged (e);
if (Control == null) {
userController = new WKUserContentController ();
var script = new WKUserScript (new NSString (JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
userController.AddUserScript (script);
userController.AddScriptMessageHandler (this, "invokeAction");
var config = new WKWebViewConfiguration { UserContentController = userController };
var webView = new WKWebView (Frame, config);
SetNativeControl (webView);
}
if (e.OldElement != null) {
userController.RemoveAllUserScripts ();
userController.RemoveScriptMessageHandler ("invokeAction");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup ();
}
if (e.NewElement != null) {
string fileName = Path.Combine (NSBundle.MainBundle.BundlePath, string.Format ("Content/{0}", Element.Uri));
Control.LoadRequest (new NSUrlRequest (new NSUrl (fileName, false)));
}
}
public void DidReceiveScriptMessage (WKUserContentController userContentController, WKScriptMessage message)
{
Element.InvokeAction (message.Body.ToString ());
}
}
here is the code reference from i took this this
this is where i am giving a source to webview from my webapi in my common library
var ee = await PolicyService.GetPrivacyPolicy();
var et = await PolicyService.GetTermsPolicy();
var htmlprivarcy = new HtmlWebViewSource
{
Html = ee
};
var htmlforterms = new HtmlWebViewSource
{
Html = et
};
Privacy.Uri = ee;
Upvotes: 0
Views: 1002
Reputation: 14956
hybrid webview which is going to get its html data from the web api
You get HTML data, not a url, so
Android:
you shouldn't use Control.LoadUrl($"{Element.Uri}");
method when you load it,change it to Control.LoadData($"{Element.Uri}","text/html","utf-8");
ios:
change Control.LoadRequest
to Control.LoadHtmlString($"{Element.Uri}", null);
Upvotes: 1