R&Dトレンドレポート

第22回マッシュアップ開発のススメその8:モバイル版アプリケーションを作ろう②]

モバイル版アプリの作成

今回からTitanium Mobile(以下Titanium)を使ってのモバイルアプリの構築を行っていきます。

前回環境構築手順をご紹介しましたが、その前後にAptanaというeclipseベースの開発環境に統合されたTitanium Studioが発表されました(プレビュー版ですが⁠⁠。

今までのTitaniumはエディタを除いたコンパイラ環境でしたが、Aptanaと統合されることによってJSの補完機能のついた統合開発環境として利用することが可能です。また、デバッグ機能も充実しておりブレークポイントを設定してウォッチしながらのデバッグも可能となっています。

こちらで公開されていますので、興味のある方は導入してみてはいかがでしょう?

今回のターゲット

今回のターゲットデバイスですが、iPhoneに絞って行いたいと思います(iOSのバージョンは4.3とします⁠⁠。

アプリの構成

PC版と同様に、動画選択画面と動画再生画面の2画面構成で考えています。動画選択画面は、iPhoneのおなじみのスタイルであるテーブルビューを用いてリスト表示を行います。

リストの中に、

  • 動画のサムネイル画像
  • タイトル
  • チャンネル情報
  • 放送日時
  • 時間あたりのコメント数

を表示させます。

テーブルビューのリストをタップすると、その動画の再生画面へと遷移します。

図1 動画選択画面と動画再生画面のイメージ図
図1 動画選択画面と動画再生画面のイメージ図

まずは上のような単純な構成で作成してみたいと思います。

Titaniumでの基本的な作り方

Titaniumで新規プロジェクトの作成を行います。プロジェクト名はjikyouとしました。Titaniumは初期ファイルの生成が終わりましたら、さっそくソースの編集を行いましょう。

プロジェクトのディレクトリに移動すると、

  • Resources
  • build

というディレクトリと

  • manifest
  • tiapp.xml

というファイルがあります。

ResourcesがTitaniumで作成するアプリケーションのルートディレクトリとなり、アプリケーションの起点となるのが、app.jsというJavaScriptのファイルとなります。

buildディレクトリはiphoneやandroidのコンパイルを行ったときにネイティブコードが生成されます。ソースの編集&コンパイルを繰り返していると、よくわからないところでエラーになったりします。そんなときはbuild/*をすべて削除してしまうという乱暴な解決方法があるようです。

基本的にソースとして触るのはResources/以下のファイル群になります。

それではapp.jsを見てみます。デフォルトで生成されるapp.jsは2つのタブを持つウィンドウが立ち上がります。が、ここではわかりやすいように1つのタブにだけ着目します。

リスト1 app.js(デフォルト)
var tabGroup = Titanium.UI.createTabGroup(); //タブグループの作成

var win1 = Titanium.UI.createWindow({  //ウィンドウを作成
    title:'Tab 1',
    backgroundColor:'#fff'
});

var tab1 = Titanium.UI.createTab({  //タブを作成
    icon:'KS_nav_views.png',
    title:'Tab 1',
    window:win1  // タブにウィンドウを関連づける
});

tabGroup.addTab(tab1);   //タブグループにタブを関連づける

tabGroup.open(); //タブグループをオープンする

タブグループ<タブ<ウィンドウ(<ラベルなど)という関係を構築し、最終的にタブグループをオープンすることでUIの構築ができています。非常に簡潔で、直感的にもわかりやすいと思います。

それではこれを改造してwin1にテーブルビューを表示させてみましょう。

動画選択画面の作成

ウィンドウの内容を変更させたい場合は、createWindow()にurlパラメータを与えます。

リスト2 ウィンドウ内容の変更
var win1 = Titanium.UI.createWindow({  //ウィンドウを作成
    title:'Tab 1',
    backgroundColor:'#fff'.
    url: “movie_list.js”
});

こうすることで、このウィンドウが開いたタイミングでurlのjsファイルが実行されます。つまり、app.jsにUIの記述を行ったように、movie_list.jsにテーブルビューのUIを構築させればよいというわけです。

movie_list.jsではどのような処理がされるのでしょうか?

  • ウィンドウがアクティブになる
  •           ↓
  • 動画一覧をサーバから取得する
  •           ↓
  • 取得したデータをテーブルビューに展開する
  •           ↓
  • テーブルビューを表示する

まずはここまでを実装してみます。

リスト3 movie_list.js
myWin = Ti.UI.currentWindow; // 自分自身のウィンドウを取得する。

var URL="http://example.com/jikkyou/list.cgi"; //動画一覧を取得するAPI

// Titaniumで用意されているHTTPClient関数
var c = Titanium.Network.createHTTPClient();
var json;
var data = [];
var rowData = [];
c.open("GET", URL); // GETで取得
c.send();
c.onreadystatechange = function() // HTTPClientのステータスが変わったら。。(コールバック関数)
{
    if ( c.readyState == 4 )
    {
        if ( c.status == 200 )
        {
            json = eval("("+c.responseText+")");
            for( i = 0; i < json.data.length; i++ )
            {
                //JSONからデータを取得
                var data = json.data;
                var iconurl = "http://example.com/jikkyou/data/"+ data[i].id + "-240.png";
                var title = data[i].title;

                //テーブルの行データを作成する。
                var row = Titanium.UI.createTableViewRow();

                //行に貼り付けるサムネイルを生成
                var iconImage =  Titanium.UI.createImageView({
                    image:iconurl,
                    width:64,
                    height:40,
                    left:4,
                    top:2
                });

                //行に貼り付けるタイトルを生成
                var titleLabel = Titanium.UI.createLabel({
                    text:data[i].title,
                    font: {
                        fontSize:12,
                        fontWeight:'bold'
                    },
                    width:'auto',
                    textAlign:'left',
                    top:2,
                    left:70,
                    height:16
                });

                //行に貼り付ける年月日を生成
                var dateLabel =  Titanium.UI.createLabel({
                    text:data[i].startdate,
                    font: {
                        fontSize:10,
                        fontWeight:'bold'
                    },
                    width:'auto',
                    textAlign:'right',
                    bottom:5,
                    right:20,
                    height:16
                });
                //上で生成したオブジェクトを行に貼り付ける。
                row.add(iconImage);
                row.add(titleLabel);
                row.add(dateLabel);
                row.hasChild=true;
                row.className = 'daily_row';
                row.height = 44;
                rowData.push(row); //配列にプッシュしておき、、
            }
            var tableView = Titanium.UI.createTableView({
                data:rowData //テーブルの行データの集合として与える。
            });

            //自分自身にテーブルビューを貼り付ける。
            myWin.add(tableView);
        }
    }
}

HTTPClientなど出てきていますが、XMLHttpRequestとほぼ同じような関数です。jsを使用したことがある人であればすんなり理解できるモノと思います。

たったこれだけで、外部APIを使用してネイティブアプリとして動作するわけです。すごいですね~。

APIから取得した行数が多いと(1画面に収まらないと⁠⁠、スクロールでその行がアクティブになった時点でアイコン画像を取得しにいきます。ネイティブアプリらしい動作と、なによりスクロールが気持ちいいですね。

しかし、このテーブルビューでは1回しかAPIを叩かないため、リストの更新ができません。すべてのリストを返すというのも動画が増えてきた場合に現実的ではありませんね。

次回はこの辺を踏まえて、動画選択画面の使い勝手を改善していきます。

最後にlist.cgiが返すJSONを載せておきます。

リスト4
{"data":[
    {
        "path":"/mnt/nas/data/368-10_2_2011050101_210004782_9e96090125ae97381d73cc36ea8db122.mp4",
        "startdate":"2011-05-01 21:00:04",
        "genre":"2",
        "seccnt":"2.0578",
        "proc":"1",
        "allcnt":"14067",
        "ch":"10",
        "enddate":"2011-05-01 22:54:00",
        "id":"368",
        "title":"[二][文]日曜洋画劇場「007/ダイ・アナザー・デイ」(2002年アメリカ・イギリス合作)リー・タマホリ監督 ピアース・ブロスナンハ"
    },
    ]
};

それでは次回もよろしくお願いいたします!

おすすめ記事

記事・ニュース一覧