連載
» 2008年03月24日 00時00分 UPDATE

作って学ぶAIRウィジェットの基礎→応用(3):Flex Builder 3でサクっとActionScriptコーディング! (3/4)

[福田寅成,クラスメソッド株式会社]

RSSのリクエストの作成

 先ほど作成したイベントハンドラのうち「RSSフィードの取得」機能の中身を実装していきましょう。RSSリーダー画面左のRSS一覧の項目がクリックされた際に、そのRSSのURLにアクセスしてRSSを取得するようにします。RSSを取得するためには、通信処理を実装する必要があります。

 AIRで通信を行う方法はさまざまあります。Flex/AIRで提供されているクラスを用いてもよいですし、通信処理に自信のある方は独自の通信処理を実装することもできます。

「URLRequest/URLLoaderペア」を用いた通信処理

 ここでは、簡単な「URLRequest/URLLoaderペア」を用いた通信処理を実装してみます。それぞれの役割のイメージは以下になります。

  • URLRequest:リクエストに関する情報をまとめて保持。送信データなども保持するクラス
  • URLLoader:URLRequestの情報を基に指定されたURLの情報をロードして保持するクラスするクラス

 URLLoaderでの通信処理では「通信の完了」「通信の失敗」などのイベントが発生します。それらのイベントに対する「イベントハンドラ」を用意する必要がありますが、まずは通信処理を下記のように実装してみましょう。

RSSフィード取得部分のコードの詳細

RSSフィードの取得
    private function getRSSFeed(event:ListEvent):void {
        trace("getRSSFeed");

        // 【1】URLRequestオブジェクトの生成
        var urlRequest:URLRequest = new URLRequest();

        // 【2】クリックされたURLを取得し、
        // URLRequestオブジェクトにセット
        urlRequest.url = RSSInfo(event.itemRenderer.data).url;

        // 【3】URLLoaderオブジェクトの生成
        var urlLoader:URLLoader = new URLLoader();

        // 【4】データ読み込み完了イベントのイベントハンドラの設定
        urlLoader.addEventListener(Event.COMPLETE,
            loadRssFeedCompleteHandler);

        // 【5】IOエラーイベントハンドラの設定
        urlLoader.addEventListener(IOErrorEvent.IO_ERROR,
            ioErrorHandler);

        // 【6】URLLoaderオブジェクトにURLRequestオブジェクトを
        // 関連付けて、通信処理開始

        urlLoader.load(urlRequest);

        // 【7】いったん全画面を利用できなくする
        this.enabled = false;
    }

 コードを1行ずつ簡単に見ていきましょう。

  1. URLRequestオブジェクトを作成
  2. URLRequestオブジェクトのurl属性にダウンロードしたいURLのアドレスを指定(「http://www.atmarkit.co.jp/」などのURLを文字列で指定)(*1
  3. URLLoaderオブジェクトを作成
  4. URLにアクセスし内容をダウンロードする処理が「完了」した際の「完了イベント」に対する「イベントハンドラ」を指定(*2)
  5. URLダウンロードリクエストをした際にサイトが落ちていたり、URLが間違っていたりした場合に発生する「I/Oエラーイベント」に対する「イベントハンドラ」を指定(*2
  6. URLLoaderオブジェクトのloadメソッドを実行。その際に、引数にURLRequestオブジェクトを指定(*3
  7. ダウンロード処理が長い場合を考慮し、いったんRSSReader全体をクリックできなくしておく(*4

 この段階で、イベントハンドラが存在しないためのエラーが出ます。そのイベントハンドラの実装は少し後に回して、先に*マークの処理に関してポイントを押さえておきます。

*1:キャストで型を指定する

 ここでは、「『RSS一覧』リストの項目がクリックされたイベント(ListEvent)」のアイテムレンダラー(リストのクリックされた項目をレンダリング(描画)しているコンポーネント)のデータ(Object型)を取得し、RSSInfoクラスにキャスト(型を指定して利用できるようにする。良パフォーマンス)して、そのプロパティであるurlを取り出しています。

 キャスト処理はしなくてもActionScriptでは動くのですが、型指定する場合に比べパフォーマンスは下がります。また、型指定がないと、Flex Builder 3の便利な[Ctrl]+[Space]キーによるコード補完が効かないという開発上の不便さも発生します。

*2:イベントの指定をActionScript上で行う場合のパターン

 イベントの指定をActionScript上で行う場合は以下のパターンで指定します。

図9 イベントの指定の仕方 図9 イベントの指定の仕方

 今回は、URLLoaderのloadメソッドに関する「complete」イベントと「ioError」イベントに関して処理を行うよう指定しています。

注意! 「メモリリークの原因」

このaddEventListenerメソッドで追加されるイベントハンドラはオブジェクトから「強参照」されています(デフォルト)。この場合、イベントハンドラがGC(ガベージ・コレクション)対象外になるので、メモリリークの原因になる場合があります。

イベント処理の内容などを考慮して、addEventListenerの5番目の引数「useWeakReference(デフォルトfalse)」をどうするか検討するようにしましょう。


*3:非同期処理

 この行が実行されても、ダウンロード処理はすぐには始まりません。非同期処理として処理が行われます。そのため、「RSSリーダー読み込み(依頼)処理」と「読み込んだデータの表示処理」を1つのメソッド内に連続する形で記述できません。そのため、処理を分けて、それらを「イベント」によって結び付けています。

*4:待っている間の処理はイロイロ

 ここでは画面全体をクリックできなくしていますが、RSS一覧の部分だけを使えなくしたりもできますし、マウスカーソルのアイコンを砂時計などに変えたりしてもよいでしょう。

ほかのイベントは[ヘルプ]の例を参照

 今回、イベントに関しては2つのイベントに関してのみ扱いましたが、ほかにもダウンロードの状況を判断するイベントや、HTTPのステータスを取得するイベントなどさまざまなイベントがURLLoaderのloadメソッドには関連します。

 それらの詳細に関しては、Flex Builder 3の[ヘルプ]の「URLLoader」の「例」を参照すると、よいでしょう。

RSSのレスポンスの取得

 次に、先ほどひな型を作成したloadRssFeedCompleteHandlerメソッドの中身を実装していきます。この処理の引数のイベントオブジェクトには、URLLoaderのloadメソッドで読み込んだRSSデータが入っているので、それを取り出して、「記事一覧」表示エリアに表示します。

RSS読み込み完了処理
    private function loadRssFeedCompleteHandler(event:Event):void {
        trace("loadRssFeedCompleteHandler");
        try {
            // AdobeのライブラリのFeedFactoryを用いて、
            // XMLをRSSフィードとして取得

            rss = FeedFactory.getFeedByString(event.target.data);

            // RSSからアイテムのリストを取り出す
            feedItemList = rss.items;
        } catch(e:Error) {
            // 型が判別できない場合処理しない。ライブラリの制限で、
            // RSSが正しく取得できない場合があります

            trace(e.message);
            feedItemList = null;
            Alert.show("RSSを正しく取得できませんでした。");
        }
        // 全画面を利用できるようにする
        this.enabled = true;
    }

 上記処理ではデータの受け取り処理を1行、画面への表示処理を1行と本質的には2行のコードで処理を行っています。その2行の処理をtry/catchで囲い、エラーハンドリングをしています。

RSS形式の判断

 最初、データはXML形式で受け取ります。それをクライアント側で利用しやすい形にgetFeedByStringメソッドが解析/変換処理を行います(具体的には、XMLがRSS 2.0RSS 1.0Atom 1.0のいずれの形式かを判断し、XMLの記事一覧部分をそれぞれのクラス(RSS20Item、RSS10Item、Atom10Item)の配列に変換します。この処理の部分を今回筆者の側で修正を行っています)。このgetFeedByStringメソッドでRSSが解析できないと判断された場合、エラーが発生し、catch句が呼ばれます。

エラー処理

 エラー処理としては、ここではエラーの内容をデバッグコンソールに出力し、記事一覧を空にし、画面にエラーの旨を通知しています。エラーの発生いかんにかかわらず、最後に画面全体をクリックできるように元に戻しています。

[Bindable]メタデータタグを使う「バインド」処理とは?

 ここで、RSSデータを画面に表示する処理の部分が重要なポイントです。

            // RSSからアイテムのリストを取り出す
            feedItemList = rss.items;

 上記の右辺は、getFeedByStringメソッドで取得したRSSオブジェクトから記事一覧のアイテムリストを取り出している部分です。この部分はいいのですが、この記事一覧をfeedItemListにセットするだけで「RSSデータの画面表示処理」が終わってしまっています。

 最初にfeedItemList変数を宣言したときを思い出しましょう。feedItemListには、[Bindable]メタデータタグが定義されています。これが、ポイントとなる部分です。

 この処理は「バインド」と呼ばれる仕組みで、あるオブジェクトのプロパティが変更された場合、その変更が別のオブジェクトに自動通知され、同じ変更が行われるというものです。

 [Bindable]メタデータタグをプロパティに設定することにより、Flexフレームワークにそのプロパティがバインディング対象であると登録され、以後、そのプロパティに変更があった場合、そのプロパティを参照している場所ではそれぞれ互いに変更が通知されるようになります。

 feedItemListは以下の3カ所に存在しています。

  1. スクリプトの変数宣言部分
  2. loadRssFeedCompleteHandler処理でRSSデータを取得する部分
  3. feedItemListデータグリッドのdataProviderに中括弧付きで

 loadRssFeedCompleteHandlerから参照されている1の変数の変更が3のデータグリッドに通知されているわけです。dataProviderはデータグリッドの中身を表しますから、結果、データグリッドにRSSの記事の一覧データが表示されるようになります。

 ここでエラーがなくなっていると思うので、ウィジェットを実行してみます。実行してRSSを選択しても、記事一覧には何も出ません。次ページで原因を解明しましょう。こういった場合、デバッグ実行ブレークポイントで問題を発見します。

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。