Adobe AIR for iOSによるiPhone/iPadアプリケーション開発第3回 通信によるデータの取得とリスト表示

2012.02.02

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

本記事は工学社月刊I/O 2011年12月号に掲載された記事の原稿をブログ化したものです。本誌の記事の内容とは異なる場合があります。転載に関しては工学社様の許可を得ております。

また、下記記事も併せてご参照ください。

Adobe AIR for iOSによるiPhone/iPadアプリケーション開発 第3回 通信によるデータの取得とリスト表示

■はじめに

スマートフォンに限らず、アプリケーション開発ではネットワーク/クラウド上のデータを取得し、それを画面に表示する処理を行います。今回はTwitterの検索を例にAIR for iOSでの通信処理とリストデータの表示に関して取り上げます。

■Flexモバイルプロジェクトの準備

以下の手順でFlexモバイルプロジェクトを作成していきます。

  • Flexモバイルプロジェクトの作成(記事ではプロジェクト名は「MonethlyIO_03_List」としていますが任意のプロジェクト名で構いません)
  • src\MonthlyIO_03_List-app.xmlを編集してます。このファイルはアプリケーションの設定を記述するXMLファイルです。最初の方にあるnameタグを「Twiiter検索」とします。これでiPhoneにアプリケーションをインストールした際のアプリケーション名が分かりやすくなります。
  • プロジェクトのプロパティ>Flexビルドのパッケージ化で証明書とプロビジョニングファイルを設定します。この設定に関しては連載第1回を参考に行ってみてください。

■Flexモバイルプロジェクトの初期構造

最初にFlexモバイルプロジェクトの初期構造を確認しておきます。

ファイル/フォルダ名 概要
src ソースファイルが保存されているフォルダです。パッケージ構造に応じてフォルダ分けされています。
src\MonthlyIO_03_List.mxml メインアプリケーションファイルです。XML形式のMXMLで記述されています。ルートタグのfirstViewで最初に表示するView(後述のViewContainer)が設定されています。基本的にあまり触りません。
src\views\HomeView.as 今回作成するアプリの本体のView。ActionScriptでロジックを記述する。後述。
src\views\HomeViewSkin.mxml 今回作成するアプリの本体。MXMLで画面のレイアウトを記述する。HomeView.asとセット。後述。
src\views\MonthlyIO_03_ListHomeView.mxml メインアプリケーションから呼ばれるView。
src\blackberry-tablet.xml BlackBerry端末向けビルドに必要な設定ファイル。
MonthlyIO_03_List-app.xml アプリケーション設定ファイル
Flex 4.5.1 AIR for iOSアプリケーション開発で利用するFlex SDK。
libs\as3corelib.swc JSON解析に利用するActionScript用ライブラリ。暗号化等のライブラリも含まれているポピュラーなライブラリ。
MonthlyIO_03_List.ipa ビルドしたiPhone向けアプリケーションファイル。

■アプリケーションアーキテクチャ

プロジェクトの構造の部分で出てきたファイルは下記のような関係にあります。

図 1 アプリケーションアーキテクチャ

本連載では各画面は基本的にはActionScriptベースのViewとそれに対応する画面を表すSkinで構成しています。ViewやSkinの用語は本連載以外で出てくる場合とニュアンスが変わるかもしれませんのでご注意ください。

ViewとSkinの開発の前にViewContainerであるMonthlyIO_03_ListHomeView.mxmlのソースを確認しておきます。

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
		xmlns:s="library://ns.adobe.com/flex/spark" 
		xmlns:views="views.*"
		title="Twitter検索" 
		>
	<fx:Declarations>
	</fx:Declarations>
	<views:HomeView id="homeView" width="100%" height="100%" />
</s:View>

(MonthlyIO_03_ListHomeView.mxmlソースコード)

1行Viewを指定しているだけです(実案件ではパフォーマンスの問題もあるので、ViewContainerとViewは一体化します)

■Viewの実装

画面のSkinの前に画面のロジッククラスであるViewを実装します。メニューからファイル>新規>ActionScriptクラスを選択します。

名前を「HomeView」、スーパークラスを「SkinnableContainer」とします。スーパークラスは参照ボタンクリックして指定します。

Viewには画面のロジック(イベントハンドラ)を記述します。Viewの実装の流れは以下になります。

  1. スキンとスキンパートの指定
  2. イベントハンドラの作成

まず、以下のコードを記述します。

[SkinState("normal")]
[SkinState("abnormal")]
[SkinState("disabled")]
public class HomeView extends SkinnableContainer {
	public function HomeView() {
		super();
		
		setStyle("skinClass", HomeViewSkin);
	}

	[SkinPart]
	public var searchButton:Button;
	
	[SkinPart]
	public var searchWordTextInput:TextInput;
	
	[SkinPart]
	public var tweetList:List;
}

(HomeView.asソースコード)

クラスの宣言の前にSkinStateの指定をしています。今回は特にステートを用いた処理を実装していないので、形式的に記述している程度に覚えておいて下さい。次にコンストラクタでskinClassでこのViewに対応するスキンの指定をしています。HomeViewSkinはまだ作成していませんが、この後作成します。

最後に『スキンパート』を定義しています。スキンパートはスキンクラスに存在するパーツの事です。ラベルやボタン、テキストボックスやリスト、そしてデータグリッドなどロジックから制御されるパーツはすべて[SkinPart]タグを付けた変数の形で宣言しておきます。変数名がSkinとこのViewをマッピングする際に重要になってきますので、注意して下さい。

いったんこの段階でSkinの実装に移ります。

■Skinの実装

先ほど作成したViewに対応した画面を表すクラスであるSkinを作成します。メニューからファイル>新規>MXMLスキンを選択します。

名前を「HomeViewSkin」、ホストコンポーネントに先ほど作成したHomeViewを指定します。このホストコンポーネントの指定によりViewとSkinが関連付けられます。

次にタグを記述して画面を作成していきます。前半部分はスタイルの設定やステートの設定なので簡単ですね。

<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
		xmlns:s="library://ns.adobe.com/flex/spark">
	<!-- host component -->
	<fx:Metadata>
		[HostComponent("views.HomeView")]
	</fx:Metadata>
	<fx:Style>
		@namespace s "library://ns.adobe.com/flex/spark";
		.myMessageStyle {
			fontSize: 35;
		}
	</fx:Style>
	<s:states>
		<s:State name="normal" />
		<s:State name="abnormal" />
		<s:State name="disabled" />
	</s:states>
	<s:VGroup includeIn="normal" width="100%" height="100%">
		<s:HGroup width="100%" height="110" paddingBottom="30" paddingLeft="10" paddingRight="10"  paddingTop="30" verticalAlign="middle">
			<s:TextInput id="searchWordTextInput" width="100%"/>
			<s:Button id="searchButton" label="検索"/>
		</s:HGroup>
		<s:List id="tweetList" width="100%" height="100%">
			<s:itemRenderer>
				<fx:Component>
					<s:IconItemRenderer
						fontSize="35"
						iconField="profile_image_url"
						labelField="from_user"
						messageField="text"
						messageStyleName="myMessageStyle"
						verticalAlign="top"
					/>
				</fx:Component>
			</s:itemRenderer>
		</s:List>
	</s:VGroup>
</s:Skin>

(HomeViewSkin.mxmlソースコード)

後半はGroupタグを使いつつボタン、テキスト入力、リスト等の画面コンポーネントをレイアウトしています。各画面コンポーネントにつけているidが重要です。Viewのスキンパートの変数名と一致している必要があります。

Groupは要素を決まった形でレイアウトする場合に使うレイアウトコンポーネントの一つです。Listはデータをリスト形式で表示するコンポーネントで、指定したitemRendererの形式でデータをリスト表示します。ここではアイコン付きでリスト表示を行うIconItemRendererを指定しています。

IconItemRendererの設定値は「リストデータの各要素のどのプロパティを表示するか」という指定で、View側の通信処理で取得したTwitterの検索結果のJSONオブジェクトのプロパティを指定しています。

■Viewの実装の続き

最後に画面のスキンパートに対するイベントハンドラを作成します。

override protected function partAdded(partName:String, instance:Object):void {	
	if(instance == searchWordTextInput) {
		searchWordTextInput.addEventListener(FlexEvent.ENTER, searchWordTextInputEnterHandler);
	}
}

private function searchWordTextInputEnterHandler(event:FlexEvent):void {
	var searchWord:String = searchWordTextInput.text;
	
	searchTwitter(searchWord);
}

(HomeView.asソースコード続き前半)

最初のpartAddedメソッドはイベントハンドラの設定を行ったりするお決まりのメソッドです。スキンパートが画面で追加(生成)されたタイミングで発生するイベントハンドラです。ここではiPhoneのソフトウェアキーボードの「Done」ボタンが押されたイベント=Enterキーが押されたイベントに対するイベントハンドラをaddEventListenerを用いて設定しています。

searchWordTextInputEnterHandlerメソッドでは検索キーワードを画面から取得し、Twitter検索処理を呼び出しています。

private function searchTwitter(searchWord:String):void {
	var twitterURL:String = "http://search.twitter.com/search.json?q=" + escape(searchWord);		
	var twitterUrlLoader:URLLoader = new URLLoader();
	twitterUrlLoader.dataFormat = URLLoaderDataFormat.TEXT;
	twitterUrlLoader.addEventListener(Event.COMPLETE, twitterUrlLoaderCompleteHandler);
	twitterUrlLoader.load(new URLRequest(twitterURL));
}
	
private function twitterUrlLoaderCompleteHandler(event:Event):void {
	var json:String = URLLoader(event.currentTarget).data;
	var tweets:Object = JSON.decode(json);
	var results:Array = tweets.results;
	tweetList.dataProvider = new ArrayList(results);
}

(HomeView.asソースコード続き後半)

searchTwitterメソッドではURLLoaderを用いてTwitterの検索を行っています。JSON形式で検索結果がtwitterUrlLoaderCompleteHandlerに返ってくるので、as3corelibのJSONクラスを用いてデコードし、その結果をtweetListのデータとしてdataProviderに設定しています。最後のメソッドのコードの左側をダブルクリックしてブレークポイントを設定すると、JSONオブジェクトの中身を見て、プロパティなどを確認する事が可能です。

as3corelibはネット上に公開されていますので、下記からダウンロードし、SWCファイルをlibsフォルダにコピーしておいて下さい。

(※AIR2.6環境で構築していますが、AIR3環境を作られている方の場合、AIR3ではネイティブでJSONクラスが用意されています。その場合JSON.decode の部分をJSON.parseメソッドに変えて下さい)

実装が出来ましたので、エミュレータ及び実機でテストしてみて下さい。

■最後に

AIR for iOSでのTwitter検索アプリはいかがでしたでしょうか。次回もAIR for iOSでミニアプリを作っていきたいと思います。

■自己紹介

福田寅成 クラスメソッド株式会社(https://classmethod.jp/) RIAエバンジェリスト RIAやクラウドに関するセミナーの開催や技術記事執筆を通じて、先進技術の啓蒙を行う日々。Flex/AIR/Silverlight/AWS/Azure/Android/iOS/Windows Phone/UXと幅広い分野を担当。

EOF