WebView 에서 JavaScript 실행은 간단히 아래와 같히 펑션을 호출하면 된다.
하지만 리턴이 있는 JavaSecript funtion 실행결과는 저 형태로는 안된다.
따로 Renderer 를 이용해 구현하는 방법을 소개한다.
먼저 .Net Standard 프로젝트에 아래와 같이 WebViewer 를 만든다.
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace Test
{
public class WebViewer : WebView
{
public static BindableProperty EvaluateJavascriptProperty =
BindableProperty.Create(nameof(EvaluateJavascript), typeof(Func<string, Task<string>>), typeof(WebViewer), null, BindingMode.OneWayToSource);
public Func<string, Task<string>> EvaluateJavascript
{
get { return (Func<string, Task<string>>)GetValue(EvaluateJavascriptProperty); }
set { SetValue(EvaluateJavascriptProperty, value); }
}
}
}
이제 위 항목을 상속받아서 각 기기별로 Renderer 를 생성하자.
Android
using System.Threading;
using System.Threading.Tasks;
using Android.Content;
using Android.Webkit;
using Test;
using Test.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(WebViewer), typeof(WebViewRender))]
namespace Test.Droid
{
public class WebViewRender : WebViewRenderer
{
public WebViewRender(Context context) : base(context)
{ }
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement is WebViewer webView)
{
webView.EvaluateJavascript = async (js) =>
{
var reset = new ManualResetEvent(false);
var response = string.Empty;
Device.BeginInvokeOnMainThread(() =>
{
Control?.EvaluateJavascript(js, new JavascriptCallback((r) => { response = r; reset.Set(); }));
});
await Task.Run(() => { reset.WaitOne(); });
return response;
};
}
}
}
internal class JavascriptCallback : Java.Lang.Object, IValueCallback
{
public JavascriptCallback(Action<string> callback)
{
_callback = callback;
}
private Action<string> _callback;
public void OnReceiveValue(Java.Lang.Object value)
{
_callback?.Invoke(Convert.ToString(value));
}
}
}
iOS
using System.Threading.Tasks;
using Test;
using Test.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(WebViewer), typeof(WebViewRender))]
namespace Test.iOS
{
public class WebViewRender : WebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement is WebViewer webView)
{
webView.EvaluateJavascript = (js) =>
{
return Task.FromResult(this.EvaluateJavascript(js));
};
}
}
}
}
UWP
using Test;
using Test.UWP;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
[assembly: ExportRenderer(typeof(WebViewer), typeof(WebViewRender))]
namespace Test.UWP
{
public class WebViewRender : WebViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement is WebViewer webView)
{
webView.EvaluateJavascript = async (js) =>
{
return await Control.InvokeScriptAsync("eval", new[] { js });
};
}
}
}
}
이제 화면에서 아래와 같이 컨트롤을 넣고
아래와 같이 코딩하면 function 의 결과 값을 받아올수 있다.
'C# > Xamarin Maui' 카테고리의 다른 글
Xamarin Forms iOS 12.0.0.15 설치 (0) | 2018.10.09 |
---|---|
Xamarin Forms 에 WPF 프로젝트 추가하기 (0) | 2018.10.07 |
(Error) Detected problems with app native libraries(please consult log for details): libmonosgen-64bit-2.0.so: unauthorized access to "/system/lib64/libsqlite.so" (0) | 2018.09.18 |
(Xamarin.Android) 오레오(oreo) 버전 권한 주기 (0) | 2018.09.01 |
에러)errSecInternalComponent (0) | 2018.08.15 |