Webアプリを公開しよう! Chrome Web Store/Apps入門

第6回 Webアプリを作ろう#3──Options Page,Web Storage

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

Web Storage

Web Storageとは,データをブラウザ上に保存するため仕組みです。ブラウザを閉じてもデータが保持されるlocalStorageと,同一セッションで有効でブラウザを閉じるとデータが消去されるsessionStorageの2種類があります。今回は設定を保存することが目的のため,localStorageを利用します。

Web Storageとクッキーとの違い

Web StorageはAPIがシンプルなため,簡単にデータを保存することができます。また,クッキーはサーバー側へリクエストを送信するたびにクッキーの内容がすべて送られているため通信量が増えてしまいますが,Web Storageではローカルでやり取りしているだけなので余計な通信が発生しません。

データの保存と参照

データの保存と参照には,window.localStorage以下のsetItem()メソッドとgetItem()メソッドを使用します。データは,キーと値をペアとしたものになります。保存できる値は,仕様上はJavaScriptオブジェクトが可能ですが,現状の実装では文字列のみ可能となっています。localStorageとsessionStorageはデータのスコープが違うだけでAPIは同一ですので,もしsessionStorageを利用する場合でも同じ記述方法で問題ありません。また,いずれも保存できるデータ量は,5MBとなっています。

options.js(設定の保存)


// 通知範囲
var ranges = [
    'short',    // 目的地~1km圏内
    'middle',   // 1km~10km圏内
    'long'      // 10km圏外
];

~省略~

// 設定
document.getElementById('apply').addEventListener('click', function(){

    // 通知設定/通知時間
    var setting = {
        notify: document.getElementById('notify-setting').checked,
        display: parseInt(document.getElementById('display-time').value, 10)
    };

    // 通知距離
    for ( var i = 0, len = ranges.length; i < len; i++ ) {
        var distance = parseFloat(document.getElementById(ranges[i]).value, 10);
        if ( document.getElementById(ranges[i] + '-unit').value === 'm' ) {
            distance /= 1000;
        }
        setting[ranges[i]] = distance;
    }
    localStorage.setItem('setting', JSON.stringify(setting));
}, false);

「設定」ボタンのクリック時にsetting変数を用意し,設定オブジェクトとして,それぞれのフォームから取ってきた値を格納しています。この設定オブジェクトをlocalStorage.setItem()メソッドから⁠setting⁠というキーで保存しています。また,保存できる値が文字列のみとなっているため,設定オブジェクトをJSON.stringify()メソッドを使って文字列に変換して格納しています。

options.js(設定の参照)


// 初期化
function init(){
    var setting = JSON.parse(localStorage.getItem('setting'));

    // 通知設定
    document.getElementById('notify-setting').checked = setting.notify;

    // 通知時間
    document.getElementById('display-time').value = setting.display;

    // 通知距離
    for ( var i = 0, len = ranges.length; i < len; i++ ) {
        var distance = setting[ranges[i]];
        if ( distance < 1 ) {
            document.getElementById(ranges[i] + '-unit').selectedIndex = 0;   // 単位:m
            document.getElementById(ranges[i]).value = (distance * 1000);
        } else {
            document.getElementById(ranges[i] + '-unit').selectedIndex = 1;   // 単位:km
            document.getElementById(ranges[i]).value = distance;
        }
    }
}

設定画面のイニシャルセットとして,保存されている設定をlocalStorage.getItem()メソッドで参照して各フォームへセットしています。今度は逆に,保存されている値が文字列となっているためJSON.parse()メソッドを使ってJavaScriptオブジェクトに変換しています。

ここでは,getItem()メソッドとsetItem()メソッドを使っていますが,ほかにも以下のような記述方法でも同様のことができます。お好みの方法で記述してください。


//データの保存(setItemと同じ意味)
localStorage.setting = JSON.stringfy(setting);
localStorage["setting"] = JSON.stringfy(setting);

//データの参照(getItemと同じ意味)
var setting = JSON.parse(localStorage.setting);
var setting = JSON.parse(localStorage["setting"]);

表1 localStorage/sessionStorage

メソッド/プロパティ説明
lengthストレージの長さを返す
key(n)n番目のキーを返す
getItem(key)キーに対応する値を返す
setItem(key, value)キーと値のペアを保存する
removeItem(key)キーと対応する値を削除する
clear()ストレージを消去する

設定の反映

実際に設定された値を使って通知を行うように変更します。設定値をキャッシュする方法もありますが,今回は設定が変更された際にすぐに反映されるように都度参照しています。

background.js(デフォルト設定)


// デフォルト設定
if ( !localStorage.getItem('setting') ) {

    var setting = {
        notify: true,   // 通知設定
        display: 5,     // 通知時間(sec)
        short: 0.2,     // 目的地~1km圏内: 200m
        middle: 1,      // 1km~10km圏内: 1km
        long: 5         // 10km圏外: 5km
    };
    localStorage.setItem('setting', JSON.stringify(setting));
}

まだ何も設定されていない最初のアクセスの際にデフォルト値を利用するようにします。⁠setting⁠をキーとした値がなければ改めてデフォルト設定を保存しています。

background.js(デスクトップへの通知部分を抜粋)


/*
 * 自動更新を開始する
 */
var watchId = 0;    //自動更新停止用のID
function startWatchPosition(sender, sendResponse){
    
    ~省略~

    // デスクトップに通知
    var setting = JSON.parse(localStorage.getItem('setting'));
    if ( setting.notify ) {

        // 距離によってしきい値を変える
        var threshold = 0;
        if ( distance < 1 ) {

            // 目的地~1km圏内
            threshold = setting.short;

        } else if (distance < 10 ) {

            // 1km~10km圏内
            threshold = setting.middle;

        } else {

            // 10km圏外
            threshold = setting.long;
        }

        // 一度通知した距離は再通知しない
        var notifiedKey = Math.floor(distance / threshold) * threshold;
        if ( !notified[notifiedKey]  ) {
            notify('目的地までの距離', '約 ' + distance + ' km', setting.display);
            notified[notifiedKey] = true;
        }
    }
    ~省略~
}

以前より変更された部分は,デスクトップへの通知を行う前に設定を取得し,デスクトップへの通知自体を行うかどうか決定するように処理を追加しています。また,これまで固定値で判定していた箇所を設定値で判定するように変更しています。

これで,Odometerに設定画面が追加され,ユーザー自身で各種設定を行えるようになりました。Web Storageは,Webアプリの設定に限らず,各種データを保存する方法として利用できるので是非活用してください。

まとめ

今回は,Odometerに設定画面を追加し,Options PageとWeb Storageの詳細を解説しました。次回も引き続きさまざまなAPIを解説していきたいと思います。

crxファイルはzipファイルですので,右クリックからのダウンロード後に拡張子をzipに変えていただければ中身を参照できます。Odometerのコード量が増えてきたため,参考のためのソースコードは上記ファイルより取得してくださるようお願いします。

著者プロフィール

吉川徹(よしかわとおる)

普段は,普通のSIer。Webからローカルアプリケーション,データベースからインフラ周りに至るまで,何でも担当する雑食系。主にHTML5開発者コミュニティ「HTML5-developers-jp」で活動中。同コミュニティ主催の「HTML5とか勉強会」のスタッフを務め,HTML5の最新動向を追っている。

コメント

コメントの記入