developer's diary

最近はc#のエントリが多いです

xamarin.iOSでWebClientを試した。(同期処理の方)

asyncやawaitは使えるのか?と気になり、 async、awaitを利用したDownloadStringTaskAsyncは使えなかった。コンパイル通りません。

DownloadStringAsyncの方はコンパイル通ったんだけども、使い方を間違えているのか動かしてみると、

=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================

となって落ちたので、ひとまず同期処理を試しました。

※このソースのまま動かした場合、オフラインだとアプリが落ちます。

using System;
using System.Drawing;
using MonoTouch.UIKit;

using System.Net;

namespace UIKitExample
{
    public class UIViewExample : UIViewController
    {

        public UIViewExample ()
        {
            this.View.BackgroundColor = new UIColor (1.0f, 1.0f, 1.0f, 1.0f);           

            //WebClient確認用のラベル
            UILabel uilbl = new UILabel (new RectangleF (10.0f, 10.0f, 300.0f, 30.0f));
            uilbl.Text = "init";

            //URLを叩いて、取得した文字をラベルに設定するボタン
            UIButton uiBtn = new UIButton (UIButtonType.RoundedRect);
            uiBtn.Frame = new RectangleF (10.0f, 40.0f, 300.0f, 30.0f);
            uiBtn.SetTitle("download button", UIControlState.Normal);
            uiBtn.TouchUpInside += (sender, e) => {
                WebClient webClient = new WebClient();
                uilbl.Text = webClient.DownloadString(new Uri("http://mitsugeek.net/xamarin/text.txt"));
            };

            //ラベルの文字を初期化するボタン
            UIButton uiBtnClear = new UIButton (UIButtonType.RoundedRect);
            uiBtnClear.Frame = new RectangleF (10.0f, 80.0f, 300.0f, 30.0f);
            uiBtnClear.SetTitle("clear button", UIControlState.Normal);
            uiBtnClear.TouchUpInside += (sender, e) => {
                uilbl.Text = "init";
            };

            //コントロールをviewに追加
            this.View.AddSubviews (uilbl, uiBtn, uiBtnClear);
        }
    }
}

結果は↓の用に。左がボタンを押す前で、右がボタンを押した後です。

f:id:mitsugi-bb:20130304075604p:plain
f:id:mitsugi-bb:20130304075610p:plain

非同期処理はどこかのタイミングで調べてみないと。

http://docs.xamarin.com/recipes/ios/network/web_requests/download_an_image を見る限り、非同期メソッドは動くみたい。

一応↓のようにラベルに値をセットするとエラーになるみたいなので、非同期で取得しておいて、どこかのタイミングで取得結果を表示するとかだと上手く行くかも。

using System;
using System.Drawing;
using MonoTouch.UIKit;

using System.Net;

namespace UIKitExample
{
    public class UIViewExample : UIViewController
    {

        public UIViewExample ()
        {
            this.View.BackgroundColor = new UIColor (1.0f, 1.0f, 1.0f, 1.0f);           

            UILabel uilbl = new UILabel (new RectangleF (10.0f, 10.0f, 300.0f, 30.0f));
            uilbl.Text = "init";

            UIButton uiBtn = new UIButton (UIButtonType.RoundedRect);
            uiBtn.Frame = new RectangleF (10.0f, 40.0f, 300.0f, 30.0f);
            uiBtn.SetTitle("download button", UIControlState.Normal);
            uiBtn.TouchUpInside += (sender, e) => {
                WebClient webClient = new WebClient();
                webClient.DownloadStringCompleted += (object sender2, DownloadStringCompletedEventArgs e2) => {
                    //↓のコメントを外すとGot a SIGABRTとなる。
                    //uilbl.Text = e2.Result;
                };
                //uilbl.Text = 
                webClient.DownloadStringAsync(new Uri("http://mitsugeek.net/xamarin/text.txt"));
            };

            UIButton uiBtnClear = new UIButton (UIButtonType.RoundedRect);
            uiBtnClear.Frame = new RectangleF (10.0f, 80.0f, 300.0f, 30.0f);
            uiBtnClear.SetTitle("clear button", UIControlState.Normal);
            uiBtnClear.TouchUpInside += (sender, e) => {
                uilbl.Text = "init";
            };

            this.View.AddSubviews (uilbl, uiBtn, uiBtnClear);
        }
    }
}