Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9703

Xamarin.Forms ガワネイティブアプリで、C# から JavaScript へのリクエスト~レスポンスを Taskにする

$
0
0

メモ書きなので雑。

シナリオ

  • Xamarin.Forms + WebView(HTML, JavaScript な SPA) のガワネイティブアプリである
  • Android アプリの BACK キーの有効無効を、WebView 内のページ状態によって切り替えたい
    • データ編集中(未保存)なので Back キーで history.back やアプリ終了されたら困る、とか

流れ

1. [Forms側] Action<TaskCompletionSource<bool>> OnRequestIsEnableBackKey { get; set; }を生やす

2. [Forms側] WebViewEx(WebViewを拡張したもの)に Task<bool> IsEnableBackKeyAsync()も生やす。実装は次のように。

publicTask<bool>IsEnableBackKeyAsync(){varcomp=newTaskCompletionSource<bool>();if(OnRequestIsEnableBackKey!=null){OnRequestIsEnableBackKey.Invoke(comp);}else{comp.SetResult(false);}returncomp.Task;}

3. [Android側] WebViewRenderer を拡張した MyWebViewRenderer を作る。

4. Xamarin.Forms の WebView で JavaScript 連携を行う(with iOS/Android共通化) - Qiitaを参考に JavaScriptHandler も作る。コンストラクタで Control に加え e.NewElement as WebViewExも渡す。引数の名前は WebViewEx outerとする。AddJavascriptInterface の第2引数は GawaAppとでもしておく。

5.JavaScriptHandler のコンストラクタで OnRequestIsEnableBackKey を受信するコードを書く。

privateTaskCompletionSource<bool>isEnableBackKeyComp=null;publicJavaScriptHandler(Android.Webkit.WebViewwebView,WebViewExouter){outer.OnRequestIsEnableBackKey=comp=>{isEnableBackKeyComp=comp;// メインスレッドから呼ばないとエラーwebView.Post(()=>{webView.EvaluateJavascript("window.requestIsEnableBackKey()",null);// webView.LoadUrl("javascript:window.requestIsEnableBackKey();"); ←これでもOKっぽい});};}

ここまでの処理で、Forms 側で await webViewEx.IsEnableBackKeyAsync()が呼び出されたら、JavaScript の window.requestIsEnableBackKey()関数が呼び出される。

6.JavaScriptHandler 内に onResultCanExitApp を生やす。JavaScript側 から結果が通知されるメソッドである。次のように。

[Export][Android.Webkit.JavascriptInterface]publicvoidonResultIsEnableBackKey(boolvalue){isEnableBackKeyComp?.SetResult(value);isEnableBackKeyComp=null;// one shot}

JavaScript 側で GawaApp.onResultIsEnableBackKey(true or false)を呼び出すと、このメソッドがコールバックされる。
TaskCompletionSource である isEnableBackKeyComp に値を設定すれば、Forms 側の await webViewEx.IsEnableBackKeyAsync()の結果が返される。

7.JavaScript 側はきっとこんな感じ

window.requestIsEnableBackKey=()=>{// 何かの処理GawaApp.onResultIsEnableBackKey(trueorfalse);}

途中まで実装したけど、面倒になって(JavaScript→C# に単方向の方がシンプルでいいやと思って)やめちゃったので、アイデアだけ残しておきます。


Viewing all articles
Browse latest Browse all 9703

Trending Articles