今回はちょっと番外編的にMetroStyleApp入門 vol6.HTTP通信その2のアプリをWindowsPhoneに移植してみます。
Windows8では非同期処理をawaitを用いて記述することで、あたかも同期処理のように書けます。
これは非常に便利ですが、WindowsPhoneにはawaitが無いので、当然書き換えが必要です。
今回の場合Windows8で該当するコードは以下、
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(uri); Request.Method = "POST"; HttpWebResponse Response = (HttpWebResponse)await Request.GetResponseAsync(); StreamReader ResponseDataStream = new StreamReader(Response.GetResponseStream()); var result = ResponseDataStream.ReadToEnd();
WindowsPhone版は以下
String uri_str = "http://coelacanth.heteml.jp/smoothlist/url/setUrl"; System.Uri uri = new Uri(uri_str); var request = WebRequest.Create(uri); Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)() .Select(res => { using (var stream = res.GetResponseStream()) using (var sr = new StreamReader(stream)) { return sr.ReadToEnd(); } }) .ObserveOnDispatcher() .Subscribe(text => { System.Xml.Linq.XElement doc = System.Xml.Linq.XElement.Parse(text); var list = from c in doc.Descendants("value") select new MovieItem { name = c.Element("name").Value, description = c.Element("description").Value, url = c.Element("url").Value }; this.movieList_ListBox.ItemsSource = list; } );
WebClientクラスを利用する場合は
var client = new WebClient(); client.DownloadStringCompleted += (sender, ev) => { var result = ev.Result; System.Xml.Linq.XElement doc = System.Xml.Linq.XElement.Parse(result); var list = from c in doc.Descendants("value") select new MovieItem { name = c.Element("name").Value, description = c.Element("description").Value, url = c.Element("url").Value }; this.movieList_ListBox.ItemsSource = list; }; client.DownloadStringAsync(new Uri("http://coelacanth.heteml.jp/smoothlist/url/setUrl"));
XAMLの方でもちょっとした書き換えが発生する。
ListBoxコントロールのイベントがMetroStyleAppの場合Tappedで、WindowsPhone版はTapなので、書き換えてあげる。
SmoothStreamingのクラスが違うのでいろいろ書き換え
ここはPlayer Frameworkの差異なので詳しく書かないが利用するクラスが違ってきて、コードもそこそこ書き替えが発生する。
それでもなぜか動かない?
さぁ、これでコンパイルもとおり実行できているのだけどなぜか動かない。
Windows8側のコードとWindowsPhone側のコードを比較するが同じ・・・
結果は単純だったんだけど同じコードと思い込むとなかなか解決できないもので、
エラー内容を見ると、
‘System.MethodAccessException’ の初回例外が mscorlib.dll で発生しました。
と書いてある。
Windows8では
class MovieItem { public string name { get; set; } public string description { get; set; } public string url { get; set; } }
で動いていたけど、WindowsPhoneは
public class MovieItem { public string name { get; set; } public string description { get; set; } public string url { get; set; } }
publicをつけてあげないといけない。
記述しない場合のスコープの挙動が違うのだろうか?
見た目は画面サイズに合わせて変えてあげる必要があるけど、
あとは同じコードの移植で動作しました。
Please give us your valuable comment