はじめに
前回 、前々回 に作成したサービスアプリケーションを、Windows Azure環境にデプロイしました。今回はこのサービスにアクセスするiOSアプリケーションを作成してみましょう。
前回までのサービスのデプロイが完了している状態が前提となります。前回の最後にコンピュートサービスを削除している場合は、再度デプロイしておいてください。
デプロイには、Windows Live IDに紐付くWindows Azure Platformアカウント(以下、Azureアカウント)が必要になります。持っていない方は無料で評価版を使うことができますので、取得してください。
作成するiOSアプリの概要
今回作成するiOSアプリケーションは、初期画面にカードを引くボタンを一個配置します。そのボタンをタップすると画面が換わり、サービスにアクセスして、カードを引いた結果をJSONで受け取ります。ランクに応じて、Windows Azureのブロブ ストレージから画像を取得して、ランクと説明とともに表示します。
Windows Azureストレージ アカウントの作成
まず、ランク画像をアップするストレージ アカウントを、Windows Azure Platform 管理ポータル で作成しておきましょう。
管理ポータルにサインイン後、右下のリストから「ホステッド サービス、ストレージ アカウント、CDN」を選択し、続けて左側のリストの「ストレージ アカウント」を選択します。
ツールバーの「新規ストレージ アカウント」をクリックします。「 ストレージ アカウントの新規作成」ダイアログで、任意のURLを入力し、地域を選択して[OK]ボタンを押下すると、アカウントが作成されます(図1 ) 。
図1 ストレージアカウントの新規作成
中央のアカウントリストビューで[状態]が「作成済み」になったら、項目を選択します。右側のプロパティペインに表示された[BlobのURL]と「プライマリ アクセス キー」( 「 表示」ボタン押下後コピーできます)を、後で使用します。
ブロブ ストレージへの画像のアップロード
Windows上で、ClumsyLeaf Softwareが提供しているCloudXplorerというフリーソフトを使って、ブロブ ストレージを操作します。
上記サイトより、インストーラをダウンロードしてインストールして、CloudXplorerを起動します。ストレージ アカウントの設定から始めます。Fileメニューの「Accounts…」から「Manage accounts」ダイアログを開きます。[New…]ボタンの「Windows Azure account…」をクリックして、ダイアログの「Name」に先ほどのアカウント名(URLサブドメインの先頭)を、「 Secret Key」にプライマリ アクセス キーを入力して、[OK]ボタンを押下します(図2 ) 。
図2 Windows Azure accountダイアログ
ダイアログを閉じると、エクスプローラライクのツリービューにアカウントが追加されます。リストビュー上でコンテキストメニューを右クリックで開きます。「 New」の「Container」を選択し、「 Create directory/container」ダイアログで「Name」を「rank」とし、ブロブ コンテナを作成します。さらに追加したコンテナのコンテキストメニューから、「 Properties」をクリックします。ダイアログの「Policies」タブで[Access Control]を「Public read access (blobs only)」を選択し、適用します。
後は、「 rank」にコンテキストメニューの「Upload」から1.jpg~10.jpgまで連番でJPEGファイルをアップロードしておきます(図3 ) 。
図3 CloudXplorer
XcodeによるiOSアプリケーションの作成
ここからMac OS Xでの作業です。Xcodeを起動したら、「 Welcom to Xcode」で「Create a new Xcode project」を選択します。
図4 Create a new Xcode projectダイアログ
「Choose a template for your new project:」ダイアログで「Utility Application」を選びます(図4 ) 。これはiPhoneにプレインストールされている、天気アプリと似た構成を提供するテンプレートです。メイン画面で右下のインフォマークをタップすると、画面が裏にひっくり返すような遷移とともに、別の画面に行きます。
図5 Choose options for your new projectダイアログ
「Choose options for your new project:」ダイアログで[Product Name]を適当に入力します。オプションは[Use Storyboard]のみチェックします。[Next]ボタンをクリックします(図5 ) 。プロジェクトの作成先を選んで[Create]ボタンをクリックします。
UIの作成
MainStoryboard.storyboardを開きます。そうすると、自動的にInterface Builderが表示されます。「 Main View Controller」のインフォマークボタンを選択します。Attributes Inspector(右ペインの右から3番目のアイコン)を表示します。「 Button」の[Type]を「Rounded Rect」に、[Title]を「Draw a card」にします。スタイルが変わったボタンを画面の中央に持っていきます。ドラッグ中に補助線が表示されるので、そのときにドロップすると中央に置けます。
次に「Flipside View Controller」を選択します。右下の「Object Library」からUIImageViewを画面上部に1つ、UILabel2つを画面中央と下部に、それぞれドラッグ&ドロップで配置します。
図6 MainStoryboard.storyboard
UIコントロールをコードから参照する
作ったコントロールにコードから参照するための設定(接続)をします。
図7 EditorとViewの切り替え
Editorを真ん中のAssistant Editorを表示し、左のビューにMainStoryboard.storyboardを開き、Flipside View Controller Sceneを表示します。そして右のビューにGIAFlipsideViewController.hを表示します。Controlキーを押しながら、左側のInterface Builder内のコントロールをドラッグして、ソースの既存の@propertyの次の行にドロップします(図8 ) 。
図8 コントロールの接続(1)
この際、コントロールからカーソル示すソースコード行部分に線が引かれます。ドラッグ&ドロップすると、コード上でコントロールを示す変数名を[Name]欄に入力して[Connect]ボタンをクリックします(図9 ) 。
図9 コントロールの接続(2)
そうすると、プロパティ宣言が自動で生成されます。さらに実装ファイル側に@synthesize(プロパティのメソッドを定義)と、viewDidUnloadとdeallocメソッドにリリース(メモリ上からオブジェクトを解放する)処理も追加されます。プロパティのローカル変数は自動的に定義されるので宣言しなくても構いません。このやり方で、
コントロール Name
上部のUIImageView rankImage
中央のUILabel rankLabel
下部のUILabel descLabel
とそれぞれ接続してください。ローカル変数は、Nameの先頭に_(アンダースコア)が付きます。
サービスにアクセスする処理の実装
FlipsideViewController.mのviewDidLoadメソッドに以下の処理を追記します。
- (void)viewDidLoad
{
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSError *error = nil;
NSDictionary *json = nil;
NSData *data = [NSDatadataWithContentsOfURL:[NSURLURLWithString:@"http://<ユニークID>.cloudapp.net/Service/DivineService.svc/card/leo"]
options:NSDataReadingMappedIfSafe
error:&error];
if (!error) {
json = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&error];
}
if (error) {
NSLog(@"Error: %@", error);
UIAlertView *alertView = [[UIAlertViewalloc] initWithTitle:@"Error"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"OK", nil];
[alertView show];
[alertView release];
return;
}
int rank = [[json objectForKey:@"rank"] intValue];
NSString *imageUrlStr = [NSStringstringWithFormat:@"http://<ストレージアカウント>.blob.core.windows.net/rank/%d.jpg", rank];
NSData *rankImageData = [NSDatadataWithContentsOfURL:[NSURLURLWithString:imageUrlStr]];
_rankImage.image = [UIImageimageWithData:rankImageData];
_rankLabel.text = [NSStringstringWithFormat:@"%d", rank];
_descLabel.text = [json objectForKey:@"desc"];
}
viewDidLoadは、ビューがロードされた直後に実行されるメソッドです。今回は画面が表示される前に、サービスURL「http://<ユニークID>.cloudapp.net/Service/DivineService.svc/card/leo」にアクセスして下記のようなJSONを、NSDataとしてバイナリデータを取得します。
{"desc":"This is a sample leo Card.","rank":5}
さらにNSJSONSerializationを使って、そのNSDataをJSONとしてパースし、内容をNSDictionaryとして扱えるようにします。
rankImageにrank値をそのままJPEGファイル名として、ブロブ ストレージのURL「http://<ストレージアカウント>.blob.core.windows.net/rank/<rank値>.jpg」を指定して、画像をロードします。rankLabelにはrank値を、descLabelにはdesc値を表示します。
これだけで、アプリケーションの実装は終了です。左上のRunボタンをクリックすると、iOSシミュレータ上でアプリが起動します。[Draw a card]ボタンをクリックすると、毎回違うランクとそれに応じた画像が表示されます(図10 ) 。
図10 iOSアプリケーションの実行
最後に
本記事では、Windows Azure上のサービスとブロブ ストレージ上の画像にアクセスするiOSアプリケーションを実装してみました。次回は、Windows Azure Toolkit for iOSを使った実装について、紹介したいと思います。