はじめに
今回は、前回 作成したアプリケーションにアクセスするWindows Phoneアプリケーションを作成したいと思います。
前回 までに作成したWindows AzureアプリケーションをWindows Azureにでデプロイするには、Windows Azureの無料お試しのアカウントをご用意していただく必要があります。
Windows Azureアプリケーションのリファクタリング
最初に前々回 に作成したWebロールアプリケーションを少しリファクタリングしたいと思います。作成したプロジェクトを開いておいてください。
作成したアプリケーションでカードを引いても数値が返って来るだけだったのを、Cardオブジェクトが返って来るように変更します。
Cardクラスの作成
ソリューションエクスプローラのModelフォルダを右クリックし、追加>クラスでCardクラスを作成します。
Id、Name、FileNameの3つのプロパティを作成します(propと打ってTab押下すると楽です!) 。
カードとしてintを利用していた部分をCardに置き換える
IGameServiceインターフェースのGetCardメソッドの戻り値の型をintからCardに変更します。また、同インターフェースのGetCardListメソッドの戻り値のGameServiceResponseを開き、中身のCardListプロパティの型をList<int>からList<Card>に変更します。
次に、サービスの実装クラスであるGameServiceを修正していきます。
GetCardメソッドの戻り値の型をintからCardに変更し、実際の処理も下記のように変更します。
public Card GetCard()
{
Card newCard = DataHelper.GetCard();
DataHelper.SaveCard(newCard);
return newCard;
}
GetCardListメソッド側も下記のように修正します。
public GameServiceResponse GetCardList(GameServiceRequest request)
{
GameServiceResponse response = new GameServiceResponse();
List<Card> cardList = DataHelper.SelectCard();
response.CardList = cardList;
return response;
}
カードを引く処理を実際に行っているDataHelper側を下記のように修正します。ここではGetCardメソッド内でCardの名称と画像ファイル名を指定してカードを振り出すようにします。今回はWindowsのマイドキュメントのピクチャにあるサンプル画像をカードの画像として利用しています(C:\Users\Public\Pictures\Sample Picturesにあるサンプル画像) 。
public static Card GetCard()
{
Random random = new Random();
int newCardNumber = random.Next(1, 8);
Card newCard = new Card();
newCard.Id = newCardNumber;
switch (newCard.Id)
{
case 1:
newCard.Name = "菊";
newCard.FileName = "Chrysanthemum.jpg";
break;
case 2:
newCard.Name = "砂漠";
newCard.FileName = "Desert.jpg";
break;
(カード3から7までの処理は省略)
case 8:
newCard.Name = "チューリップ";
newCard.FileName = "Tulips.jpg";
break;
default:
break;
}
return newCard;
}
DataHelper内の他のメソッドのintでやり取りしている部分もCardに修正します。修正が終わりましたら、動作を確認します。アプリケーションを起動し、ブラウザが起動したら、以前同様下記URLにアクセスします。
http://127.0.0.1:81/GameService/getcard
以前は数字だけ出ていたのですが、今回は下記のようなJSONフォーマットのカードデータが表示されます。
{"FileName":"Desert.jpg","Id":2,"Name":"砂漠"}
画像ファイルをBlobにアップロードする
今回はカードを引いた際の画像をWindows AzureのBlobにアップロードしておくことにします。これから作成するWindows Phoneアプリケーションでは、カードを引いた際にBlobにアップロードしてある画像が表示されるようにします。BlobとはWindows Azure版のオンラインストレージで静的な画像ファイルやJSファイルなどの管理に利用されます。
Windows Azureのストレージは実際のWindows Azure上のモノと、ローカルのエミュレータのもの(Storage Emulator)の2つがあります。
Windows AzureのBlobを利用する場合
Windows Azure 管理ポータルにログインし、ストレージアカウントを作成します。「 ホステッドサービス、ストレージアカウント、CDN」を選択し、「 ストレージアカウント」を選択します。上部のリボンから「新規ストレージアカウント」を選択し、ストレージアカウントを作成します。
図1 ストレージアカウントの新規作成
ここで、ストレージアカウント名は適当なものを指定してください。作成したストレージアカウントを選択するとプロパティが右に表示されますので、「 プライマリアクセスキー」と「セカンダリアクセスキー」をメモっておきます。
次にCodePlexで公開されているAzure Storage Explorerをインストールします。これを利用すると、Windows Azureのストレージ機能のコンテンツの管理が可能になります。
Azure Storage Explorerがインストールできたら、起動します。上部のAdd Accountをクリックし、先ほどのストレージアカウントを登録します。
図2 ストレージアカウントの登録
これでWindows Azureでのストレージアカウントの登録は完了です。
ローカルのStorage Emulatorを利用する場合
ローカルでデバッグすると、Webロール等を実行するためのCompute Emulator以外にStorage Emulatorも同時に起動します。デスクトップのタスクバー右下で確認する事が出来ます。青いアイコンがWindows Azureのエミュレータのアイコンです。
図3 Windows Azureエミュレータ
こちらを画像の保存先として利用する場合は、Windows AzureのBlobの場合同様に、Azure Storage Explorerをインストールし、起動します。その後、上部のAdd Accountをクリックし、右上の「Developer Storage」を選択します。
図4 Storage Emulatorの利用
これでStorage Emulatorでのストレージアカウントの登録は完了です。
Blobに画像ファイルをアップロードする
Azure Storage Explorerでまず、画像を格納するコンテナを作成します。コンテナはここではフォルダのようなものであると覚えておいて下さい。コンテナ名はcardとします。
作成したcardコンテナにWindowsの場合だと「C:\Users\Public\Pictures\Sample Pictures」にあるファイルをいったんデスクトップ等にコピーしてそのファイルをアップロードします(ファイル名が日本語から英語に勝手に変更されます) 。
図5 画像ファイルのBlobへのアップロード
その後、アップロードしたファイルをすべて選択してファイルのアクセス権を変更します。ファイル選択後、上部にSecurityをクリックして変更を行います。Container AccessをPublic Blobに変更しておきます。
図6 ファイルのアクセス権の変更
また、ファイル一覧画面で1つのファイルをダブルクリックして、そのファイルを参照するためのURLを取得しておきます。URLは下記のようになっています。
http://127.0.0.1:10000/devstoreaccount1/card/カード名
Windows Phoneプロジェクトの作成
Visual Studio 2010を開き、新しいプロジェクトを作成します。
左のペインからプロジェクトテンプレートとして「Silverlight for Windows Phone」を選択します。プロジェクトの種類は「Windows Phoneアプリケーション」を選択します。
プロジェクト名を「GihyoAzureSampleGame01WP」とします。
「OK」ボタンをクリックすると、Windows Phone OSのバージョンを選ぶダイアログが出ます。
ここではWindows Phone OS 7.1を選択します。
これまでのWindows Azureプロジェクトの入っているソリューションにWindows Phoneのプロジェクトを混ぜることも可能なのですが、今回はWindows Azureプロジェクトとは分けてプロジェクトを作成することにします。
Windows Phoneアプリケーションの作成
今回作成するアプリケーションは最初の画面にカードを引くボタンが配置されていて、そのボタンをタップするとカード詳細画面に遷移する感じのアプリケーションです。
MainPage.xaml
MainPage.xaml を開いて、デザインビューでコードを修正していきます。MainPage.xamlの「マイアプリケーション」というTextBlockのTextを変更します(例:gihyo.jp Azure×WP連載) 。「 ページ名」TextBlockのTextを「カードを引く」に変更します。
次に、画面下部にGridが配置されている事を確認します。ここに「カードを引くボタン」を配置します。ツールボックスからButtonを選択してGrid内に適当に配置します。配置したButtonのプロパティに関して、HorizontalAlign、VerticalAlignをCenterにし、Marginを0,0,0,0にします。また、Buttonの名前を「DrawButton」 、Contentを「カードを引く」にします。少しボタンの幅が狭いので、Widthを「200」に伸ばします(「 名前」はプロパティパネルの上部の方で設定することができます。コードではx:Nameプロパティに相当します) 。
プロパティパネルで「イベント」タブを選択し、Clickイベントの右の所をダブルクリックします。これでイベントハンドラのひな形を作成しておきます。
MainPage.xaml.cs
MainPage.xaml.csに処理をC#で記述していきます。先ほど作成したDrawButton_Clickメソッドに処理を書いて行くのですが、カードを引く処理は次の画面で行うので、ここでは次の画面への画面遷移処理だけを記述します。
private void DrawButton_Click(object sender, RoutedEventArgs e)
{
this.NavigationService.Navigate(new Uri("/ResultPage.xaml", UriKind.Relative));
}
Windows Phoneでは画面の遷移処理はNavigationServiceを用いて行います。Navigateメソッドを用いると指定したURIの画面に遷移します。今回は画面遷移する際のトランジション等は指定していませんが、MainPage.xamlにトランジションを設定する事により、ヴィジュアル的にインパクトのある画面遷移を容易に実装する事が可能です。
ResultPage.xaml
カードを引いた結果を表示する画面としてResultPage.xamlをプロジェクトに追加します。プロジェクトを右クリックして、追加>新しい項目を選択します。「 Windows Phone縦向きのページ」を選択し、名前を「ResultPage.xaml」とします。
デザインビューで画面の項目の設定を修正していきます。「 マイアプリケーション」というTextBlockのTextを変更します(例:gihyo.jp Azure×WP連載) 。「 ページ名」TextBlockのTextを「引いたカード」に変更します。
次に、画面にカード名を表示するTextBlockとカード画像を表示するImageを配置します。追加した2つコントロールの設定は以下のようにします。完全に同じにする必要はありません。必ず設定する必要があるのは、TextBlockのx:Name属性をNameTextBlockに、Imageのx:Name属性をCardImageの2つです。
<TextBlock Height="36" HorizontalAlignment="Center" Margin="0,20,0,0"
Name="NameTextBlock" Text="TextBlock" VerticalAlignment="Top"
Width="196" TextAlignment="Center" />
<Image Height="338" HorizontalAlignment="Left" Margin="0" Name="CardImage"
Stretch="Fill" VerticalAlignment="Center" Width="450" />
ResultPage.xaml.cs
ResultPage.xaml.csに処理を記述していきます。最初に「この画面に遷移してきたイベント」ハンドラにカードを引く処理を記述します。NavigationServiceを使用する際のイベントハンドラは今回作成したResultPageの親クラスであるPageクラスに定義されています。「 この画面に遷移してきたイベント」のイベントハンドラはOnNavigatedToです。
Windows Azure上のアプリケーションへのリクエストは今回はWebClientを用いたオーソドックスな形で行います(今回はWindows Azure上のサービスの作り方からWebClientによるアクセスを採用しました) 。
カードを引く処理は下記のようになります。
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
WebClient webClient = new WebClient();
webClient.Headers[HttpRequestHeader.IfModifiedSince] = "Thu, 01 Jun 1970 00:00:00 GMT";
Uri uri = new Uri("http://127.0.0.1:81/GameService/getcard");
webClient.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(uri);
}
リクエストのヘッダにIfModifiedSinceを設定する事により、カードを引くボタンが押されるたびに、毎回Windows Azureにリクエストが投げられるようにしています。
次に、通信処理の結果イベントハンドラにGameServiceから返って来るJSON形式のレスポンスを受け取って画面に表示する処理を記述します。
最初にアセンブリへの参照を2つ追加します。プロジェクトの参照設定を右クリックして、参照の追加を行います。
最初にGameWebRole.dllを参照に追加します。GameWebRole.dllはこれまでに作成したGameWebRoleプロジェクトのbinディレクトリに出力されています。
次に、CodePlexよりJson.NETをダウンロードし、適当な場所に解凍して、『 Windows Phone版』のDLLの参照を参照設定に追加します。
それではGameWebRoleへの通信のレスポンスを受け取る処理の中身を書いて行きます。
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
WebClient webClient = new WebClient();
webClient.Headers[HttpRequestHeader.IfModifiedSince] = "Thu, 01 Jun 1970 00:00:00 GMT";
Uri uri = new Uri("http://127.0.0.1:81/GameService/getcard");
webClient.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(uri);
}
処理の流れとしては、最初にダウンロードされてきたJSON文字列をJsonConvertを用いてCardオブジェクトへデシリアライズしています。データが取得できれば、あとは結果を画面に表示するだけです。カードのイメージは上記ではStorage EmulatorへのURLを指定しています。
一通りの実装が終わりましたので、実行して動作を確認します。Visual Studioを2つ起動して、先にWindows Azureアプリケーションを実行、その後、本記事のWindows Phoneアプリケーションを実行します。
図7 Windows Phoneアプリケーション
今回作成したサンプルはこちらです。
最後に
今回はWindows Phoneアプリケーションを作成して、前回までに作成したアプリケーションにアクセスしてみました。次回はWindows Azure Toolkit for Windows Phoneをご紹介する予定です。