Xamarin.FormのWebViewのクッキー取扱について
Xamarin.FormのWebViewについて
Androidはクッキー(cookie)の取得が出来たりできなかったり不安定です。
webview.Cookies = new CookieContainer();
この行があるだけで挙動が不安定でクッキーが取れたり取れなかったりします。
Androidはこの行を処理しないようにする必要が有ります。
iPhoneの場合は通常の通りクッキーを取得できます。次のソースコードをtest.csにコピーします。
using System;
using System.Net;
using Xamarin.Forms;
namespace test
{
//iPhone・Androidのプラットフォームからクッキーを取得する。
public interface PfCookies
{
CookieContainer CurCookies(string url);
}
public class MainPage : ContentPage
{
public MainPage()
{
WebView webview = new WebView()
{
Source = new Uri("https://www.yahoo.co.jp"),
VerticalOptions = LayoutOptions.FillAndExpand
};
//iPhonen & macはクッキーをセットする。
switch (Device.RuntimePlatform)
{
case Device.iOS:
webview.Cookies = new CookieContainer();
break;
case Device.macOS:
webview.Cookies = new CookieContainer();
break;
}
webview.Navigated += (s, e) => {
CookieContainer cookies = new CookieContainer();
switch (Device.RuntimePlatform)
{
case Device.iOS:
//iPhonen & macはWebViewのクッキーを取得する。
cookies = webview.Cookies;
break;
case Device.Android:
//Androidは直接はinterfaceよりクッキーを取得する。
cookies = DependencyService.Get<PfCookies>().CurCookies(e.Url);
break;
}
//クッキーをコンソールに列挙する。
foreach (Cookie c in cookies.GetCookies(new Uri(e.Url)))
Console.WriteLine(c.Name + "=" + c.Value);
};
Content = webview;
}
}
}
次にAndroidのプラットフォームにinterfaceを追加します。
空のクラスを追加します。ファイル名はPfCookies.csとでもしておきましょう。
using System;
using System.Linq;
using System.Net;
using Xamarin.Forms;
using Android.Webkit;
[assembly: Dependency(typeof(test.Droid.DroidCookieStore))]
namespace test.Droid
{
class DroidCookieStore : PfCookies
{
private readonly object _refreshLock = new object();
public CookieContainer CurCookies(string url)
{
return RefreshCookies(url);
}
private CookieContainer RefreshCookies(string _url)
{
lock (_refreshLock)
{
CookieContainer cookies = new CookieContainer();
//クッキーの取得
var allCookiesForUrl = CookieManager.Instance.GetCookie(_url);
if (!string.IsNullOrWhiteSpace(allCookiesForUrl))
{
var cookiePairs = allCookiesForUrl.Split(' ');
foreach (var cookiePair in cookiePairs.Where(cp => cp.Contains("=")))
{
int con = cookiePair.IndexOf("=");
cookies.Add(new Uri(_url), new Cookie(cookiePair.Substring(0, con), cookiePair.Substring(con + 1, cookiePair.Length - con - 2)));
}
}
return cookies;
}
}
}
}
これでAndroidとiPhoneそれぞれクッキーを取得できるWebViewが完成しました。
iPhone用のinterfaceは不要ですね!ソースがすっきりしていい感じになりました。
ディスカッション
コメント一覧
まだ、コメントがありません