Titanium Mobileで作る! iPhone/Androidアプリ

第9回 データの永続化

この記事を読むのに必要な時間:およそ 3 分

最新ニュースから

前回の掲載で,Titanium Mobileの1.6.0がリリースされたとお知らせしましたが,先日(15日には)早速 1.6.1 がリリースされました。iPhoneではiOS 4.3への対応とXCode 4への対応が主なアップデートのようです。XCodeは久しぶりのメジャーアップデートがあったばかりで,素早い対応に今後の更新にも期待できます。

データの永続化

今回は,アプリが扱うデータをアプリ終了後も保持するための方法を解説します。具体的には,Twitterアプリで投稿するツイートの編集中に終了しても,編集中の内容が保存されるように変更してみます。iPhoneアプリは,ユーザーの不意な操作やメモリの自動開放などにより,意図せずアプリが終了したりデータが消えることがありますので,編集中のデータが保存されるのは重要なことです。

まずは,入力していたツイートを保存するコードです。前回のmessage_window.jsに追記しています。

win.addEventListener(
    'close',
    function(){
        var text = textArea.value;
        Ti.App.Properties.setString('previousText', text);
    }
);

win.addEventListener(
    'open',
    function(){
        var text = Ti.App.Properties.getString('previousText');
        if ( text ) {
            textArea.value = text;
        }
    }
);

windowがcloseすると,window中のtextAreaなどのUI部品の入力内容は消えてしまうので,windowのcloseイベントにイベントリスナをセットして,その値を保存します。

ここで利用している,Titanium.App.Propertiesは キーと値でデータを管理できる便利なオブジェクトです。値を保存するときは,Ti.App.Properties.setStringに値に対応するキーと,その値を渡します。逆に取得するときは,Ti.App.Properties.getStringにキーを渡します。setString, getStringとあるように,保存するデータの型によってメソッド名が変わります。また,Javascriptのオブジェクトをそのまま保存することはできないのでJSONなどでシリアライズする必要があります。Stringではない値について,位置情報の保存のサンプルで解説します。

win.addEventListener(
    'close',
    function(){
        var text = textArea.value;
        Ti.App.Properties.setString('previousText', text);

        if (mapview.visible) {
            var loc = mapview.location;
            var locationList =
                [loc.latitude,loc.longitude,loc.latitudeDelta,loc.longitudeDelta];
            Ti.App.Properties.setList('locationList', locationList);
        }
    }
);

win.addEventListener(
    'open',
    function(){
        var text = Ti.App.Properties.getString('previousText');
        if ( text ) {
            textArea.value = text;
        }
        if ( Ti.App.Properties.hasProperty('locationList') ) {
            var locationList = Ti.App.Properties.getList('locationList');
            mapview.show();
            mapview.setLocation(
                {
                    latitude : locationList[0],
                    longitude : locationList[1],
                    latitudeDelta : locationList[2],
                    longitudeDelta : locationList[3]
                }
            );
        }
    }
);

この例では,mapViewの位置を設定するのに必要な4つの値について,配列に一度変更することで保存しています。オブジェクトのままでは保存できませんが,いくつかの値をまとめて保存したいだけであれば,配列であれば保存することができます。また,キーに対応する値があるかどうかについてはTi.App.Properties.hasPropertyで確認することができます。

ファイルで保存してみる

上の例ではTi.App.Propertiesを利用して値の保存を行っていますが,Titaniumではファイルの読み書きも手軽に利用できます。同じデータをファイルに保存する例を説明します。

var fileName = 'tweet.txt';
win.addEventListener(
    'close',
    function(){
        var text = textArea.value;
        var loc;
        if (mapview.visible) {
            loc = mapview.location;
        }
        var json = JSON.stringify({previousText:text,location:loc});
        var file  = Ti.Filesystem.getFile(
            Titanium.Filesystem.resourcesDirectory + '/' + fileName
        );
        file.write(json);
    }
);

win.addEventListener(
    'open',
    function(){
        var file  = Ti.Filesystem.getFile(
            Titanium.Filesystem.resourcesDirectory + '/' + fileName
        );
        var json = file.read();
        if ( !json || json.length <= 0) {
            return;
        }
        var data = JSON.parse(json);
        var text = data.previousText;
        var location = data.location;
        if ( text ) {
            textArea.value = text;
        }
        if ( location ) {
            var locationList = Ti.App.Properties.getList('locationList');
            mapview.show();
            mapview.setLocation(location);
        }
    }
);

ファイル書き込みをする方法で注意してほしい点はファイルハンドラを取得する,Titanium.Filesystem.getFileです。引数にはファイルのパスを指定するのですが,アプリが書き込める領域として,

  • Titanium.Filesystem.resourcesDirectory + '/' + fileName

を指定しましょう。resourcesDirectoryのほかにも読み書きできるディレクトリのパスがいくつか用意されており,APIリファレンスから確認できます。

また,ファイルにデータ構造を格納するために,JSONを利用したシリアライズを行っています。TitaniumにはJSONのシリアライザ/パーサがJSONというオブジェクトに実装されているのでこれを使います。パーサとしては,Twitter APIから取得したデータのパースに既に利用していますが,シリアライザとしても利用できます。また,この例ではファイルに書き込んでいますが,当然JSONでシリアライズした結果をTi.App.Properties.setStringを利用して保存するのもよい手段です。

画像を保存する

ツイートの編集画面には,もう一つ写真のデータも表示されています。いままでのコードでは,写真アルバムから写真を選択する場合は,すでに写真はアルバムに保存されていますし,新しく撮影する場合は撮影時に,写真アルバムに保存するような設定になっています。

なので,改めて画像を保存する処理は必要ないのですが,全く違う方法で画像を取得していたり,保存したい場合のために解説をしておきます。

Titanium.Media.saveToPhotoGallery(image)

このコードだけで,変数imageに入っている画像のデータを写真アルバムに保存することができます。また,

var file  = Ti.Filesystem.getFile(
    Titanium.Filesystem.resourcesDirectory + '/' + fileName
);
file.wriete(image)

というような形で,imageをファイルに保存することも可能です。

著者プロフィール

倉井龍太郎(くらいりゅうたろう)

株式会社はてな アプリケーションエンジニア。

スマートフォンアプリからSQLチューニングまで幅広く格闘中。好きな言語はRuby。

URLhttp://d.hatena.ne.jp/r_kurain/
Twitter@kurain

コメント

コメントの記入