Worklight を使用する: 第 2 回 構造化モジュールを開発して IBM Worklight の暗号化オフライン・キャッシュ機能を使用する

モバイル・アプリケーションを構造、機能、セキュリティーの層で構成する

IBM Worklight プラットフォームを紹介するこの連載では、多種多様な IBM ソフトウェア製品を利用してモバイル・アプリケーションを作成する方法を説明します。第 2 回では、引き続き Worklight アプリケーションの開発プロセスを説明します。そのなかで、ハイブリッド・アプリケーションを作成する際のベスト・プラクティスを明らかにするとともに、Worklight の暗号化オフライン・キャッシュ機能について説明します。

Carlos Andreu , Software Developer, IBM

Carlos Andreu は、IBM Software Group のソフトウェア開発者で、現在はハイブリッド・アプリケーション、Android アプリケーション、iOS アプリケーションを構築するためのフレームワークの作成に取り組んでいます。彼は、最新のトレンドと技術関連のブログを追ったり、読書、テレビ、そしてあらゆるジャンルの音楽を楽しんだり、さまざまなことに興味を持っています。彼についての詳細は、http://dev.yapr.org/carlosandreu を参照してください。



Jeremy Nortey, Software Developer, IBM

Jeremy Nortey は、Software Group に所属する IBM Mobile Foundation のソフトウェア開発者として、モバイル・ソリューションのソフトウェアおよび品質保証を開発しています。iOS を専門としており、余暇は iPhone のネイティブ・アプリケーションの作成に費やしています。サッカーとランニングも趣味にしています。



Raj Balasubramanian, Product Architect, IBM

Raj Balasubramanianは、IBM Software Group の顧問 IT アーキテクトです。顧客関連を担当し、アプリケーションおよびインフラストラクチャー関連のプロジェクトを実現しています。彼は技術に関するあらゆるものから、歴史、物理に至るまで、広範な分野に関心を持っています。余暇がたっぷりあるときには、夫婦で出掛けたり、息子とロボットについて話し合ったりして楽しんでいます。彼の技術的および個人的な活動については、彼個人のブログ Gurukulam を読んでください。



2012年 8月 30日

はじめに

IBM Mobile Foundation の一部となっている IBM Worklight は、さまざまな機器のプラットフォームで実行可能な Web ベースの技術を使用して、迅速にモバイル・アプリケーションを作成するための堅牢なプラットフォームです。この記事では、第 1 回の続きとして、モバイル・ユーザーがタスクの ToDo リストを作成して管理するために使用できる「Todo」という名前の完全に機能する自己完結型モバイル・アプリケーションの開発プロセスを進めます。このプロセスの中で、マルウェアによる攻撃や機器の盗難があった場合に機密情報を守るための Worklight クライアント・ランタイムのセキュリティー対策機能である、暗号化オフライン・キャッシュ機能について説明します。

今すぐ Worklight を入手してください

無償で有効期限のない IBM Worklight Developer Edition 5.0 を今すぐダウンロードしてください!

現時点で、Eclipse IDE には IBM Worklight Studio がセットアップされていて、皆さんは単純な「Hello World」タイプのアプリケーションを iOS と Android にデプロイする方法を十分理解できているはずです。今回は、第 1 回で開発を始めた Todo アプリケーションから取り掛かります。第 1 回で作成した初期アプリケーションをダウンロードして、Worklight Studio 環境にインポートしてください (あるいは、この記事に付属の Todo アプリケーション・プロジェクト・ファイルをダウンロードすることもできます)。


アプリケーションの開発

サンプル・アプリケーションの使用

この記事で説明するサンプル・アプリケーションは、例を示すことのみを目的とした演習として紹介しているものです。JavaScript には大量のアプリケーション・ロジックが (特に jQuery を使用して) 取り込まれることになるため、読みやすく、信頼性が高く、矛盾のないような形でアプリケーション・ロジックを構造化するためのベスト・プラクティス、そして名前空間の使用方法に関するプラクティスなどを説明します。

図 1 に、Todo モバイル・アプリケーションを実行するユーザーの一般的な操作フローを示します。要約すると、ユーザーは以下の操作を行います。

  • アプリケーションを開きます。
  • オフライン・データをセキュアに保管するためのパスコードを入力し、「Start (スタート)」をタップして 2 番目のパネルに進みます。
  • 最初のフィールドに新しい「Todo」項目を表すテキストを入力した後、「Add Item (項目の追加)」ボタンをタップして、その項目をリストに追加します。
  • リスト内の項目をタップして「完了」のマークを付け、項目が選択された状態にします。「Remove Done (完了項目の削除)」をタップして、完了マークが付いたすべての項目を削除します。
  • パネルに表示されている項目をフィルタリングする場合は、2 番目のテキスト・フィールドに項目の名前またはその一部を入力し、「Filter Items... (項目のフィルタリング…)」をタップします。
図 1. サンプル・アプリケーションのパネル
サンプル・アプリケーションのパネル

以上の機能をアプリケーションに追加するために行う最初のステップは、コードをアプリケーション内で特定の役割を果たすモジュールに分割することです。Todo アプリケーションは、以下のモジュールで構成されることになります (図 2 を参照)。

  • Constant モジュール: アプリケーションで使用するさまざまな定数の取得や設定を行います。
  • List モジュール: 現行セッションのリストを保管し、イベントを処理します。イベントには、リストへの新規項目の追加、完了項目へのマーク付け、完了マークが付いた項目の削除などがあります。
  • Vault モジュール: リストの暗号化および復号を行います。Worklight の暗号化オフライン・キャッシュ機能を利用するのは、このモジュールです。
図 2. モジュールおよびモジュール間のやりとり
モジュールおよびモジュール間のやりとり

コードを構造化するには、JavaScript の世界で広く普及している「モジュール・パターン」を使用します (「参考文献」を参照)。リスト 1 に、モジュール・パターンのスケルトンを記載します。名前空間 (MYAPP) に含まれるオブジェクト (Module1) には、自動実行関数 (即時関数) を割り当てます。このオブジェクトで使用するグローバル・オブジェクト (つまり、ウィンドウ。ほとんどのクライアント・サイド JavaScript では、ウィンドウがグローバル・オブジェクトの役目を持ちます) やベンダー・ライブラリー (つまり、jQuery など。モジュールの外部で Prototype.js や別のライブラリーが $ を使用しているとしても、モジュール内で $ を使用することができます) はこの関数に渡すようにするのが賢明です。また、依存関係をリストアップして、依存関係にローカル変数を割り当てるのも望ましいプラクティスです。それは、キーと値のペアを検索するよりも、ローカル変数にアクセスしたほうが早いからです。

以下はその一例です。

var eoc = WL.EncryptedCache; eoc.open()

いずれかのモジュールの中で open 関数を呼び出す必要が生じるたびに、JavaScript で WL オブジェクトを検索し、続いて open 関数が含まれる別のオブジェクトを指す EncryptedCache キーを検索するよりも、上記のように変数を割り当てるほうが賢い方法です。

リスト 1. モジュール・パターンのスケルトン
MYAPP.Module1 = (function (global, $) { 
//List dependencies: jQuery 1.7.2

//List private variables

//List private functions
var _init = function () {
console.log("I'm ready!");
}

//List one time initialization procedures 

//public API
return {
init : _init
};

}(window, jQuery)); //MYAPP.Module1

ここで、賢いコーディング・スタイルの規約を紹介しておきます。サンプル・コードでは、定数には大文字を使用し、プライベート関数の前にはアンダーバーを追加してプライベート変数と区別します。この規約を拡張し、変数を必要とするあらゆる関数の先頭で、1 つの var で複数の変数を宣言する「single var pattern」を使用することができます。このようにする理由としては、JavaScript の関数内で宣言された変数はコードの実行時に「ホイスト」される (関数の先頭で宣言されたように扱われる) こと、また変数を使用し忘れると、望ましくない結果 (同じ名前のグローバル変数が上書きされるなど) になる場合があることが挙げられます。

リスト 2. ホイストの例
//Example of Hoisting 
myname = "global";

function func() {
alert(myname); //returns: "undefined" 
var myname = "local";
alert(myname); //returns: "local"

モジュールを駆動するのは、クロージャーと呼ばれる基本構成概念です (「参考文献」を参照)。JavaScript では、クロージャーが参照する関数のローカル変数は、関数がリターンした後もそのまま保持されます。これは、JavaScript で関数によって定義されるスコープに密接に関係します。リスト 1 に示されているクロージャーの使用例を見てください。ここで、_init() はプライベート関数であるため、MYAPP.Module1 に割り当てられた自動実行関数の外部ではアクセスできませんが、このプライベート関数への参照を持つオブジェクトを返すことは可能です。したがって、MYAPP.Module1.init() とすれば、プライベート関数に簡単にアクセスすることができます。この仕組みを可能にするのが、クロージャーです。

JavaScript は、プログラミング・パターンについて書かれたほぼすべての本で説明されている Observer パターンと同様のイベント指向プログラミング言語です。JavaScript のスクリプトでは、ユーザーがスクロールしたとき、HTML タグをクリックしたとき、リンクにマウス・ポインターを重ねたときなどをはじめ、ユーザーが行うさまざまな操作のたびに、イベントが発生します。イベントはリッスンする対象とすることも、独自のイベントをトリガーすることもできます。

従うべき重要なプラクティスには、「関心の分離」もあります。これは、マークアップ、スタイル、アプリケーション・ロジックをそれぞれ切り離しておくことを意味します。HTML コードは、アプリケーションの構造だけを記述していなければなりません。HTML にインライン JavaScript 関数を含めることは避けるべきです。それには、イベント駆動型のコーディング・スタイルを適用することができます。つまり、インライン呼び出しが必要な特定の要素を HTML に含める代わりに、その要素に必要なアクションをトリガーする特定のイベントを観察します。こうすることにより、アプリケーション・ロジックを HTML のあちこちに分散させるのではなく、JavaScript 内だけに集めることができます。同様に、HTML を JavaScript の一部として作成して、テンプレートを代わりに使用することは避けてください (「参考文献」を参照)。


Constant モジュール

まずは、名前空間を定義するところから始めます (リスト 3 を参照)。このサンプル Todo アプリケーションで使用する名前空間には、「TD」という名前を付けます。名前空間は基本的に、アプリケーションに関係する他のすべてのオブジェクトを保持するオブジェクトです。アプリケーションの拡大に備え、TD をグローバル名前空間に定義しておくことも可能です。TD オブジェクトがまだ用意されていない場合は、「single var pattern」を使用して TD オブジェクトを作成してください。メソッド呼び出しの一貫性を確実にするのは、名前空間関数です。TD.namespace(TD.module1) を呼び出すと、module1 という名前のオブジェクトが TD に追加されます。以下のリストを見ると、TD 名前空間を宣言して、必要に応じてこの TD 名前空間の下にオブジェクトを足していく方法がわかります。

リスト 3. 名前空間関数
/**********************************************************************************
* TD NAMESPACE
**********************************************************************************/
var TD = TD || {};

TD.namespace = function (ns_string) { 
var parts = ns_string.split('.'),
parent = TD, 
i;

// strip redundant leading global 
if (parts[0] === "TD") {
parts = parts.slice(1); 
}

for (i = 0; i < parts.length; i += 1) {
// create a property if it doesn't exist
if (typeof parent[parts[i]] === "undefined") {
parent[parts[i]] = {}; 
}
parent = parent[parts[i]]; 
}

return parent; 
};

参考になる資料

Worklight user documentation に記されている Encrypted Cache (暗号化キャッシュ) についての情報や「Worklight Developer's Reference Guide」も参照してください。

図 3 に示されているように、TD.Constant (このサンプル・アプリケーションの Constant モジュール) にはプライベート・メンバーがありません。このモジュールは、Public API と名付けられた API (オブジェクト・リテラルを使用して作成された、単なるキーと値のペア) を介して値を返すだけです。同様に、Todo items key は暗号化オフライン・キャッシュ機能に使用されます。encryptdecrypt の値は、単純なブール値です。これらの値によって、Vault モジュールに暗号化または復号のどちらを行うかを指示します。

図 3. 各モジュールの要素
各モジュールの要素

List モジュール

図 1 とリスト 4 に示されているように、基本的にアプリケーションのメイン・ページとなるのは、このサンプル・アプリケーションの 2 番目のパネルです。このパネルには、以下の要素があります。

  • ヘッダーに表示されるロゴ
  • 新規項目を追加するときに使用するテキスト・フィールド (id="new-todo")
  • 新規項目を追加するためのボタン (id="add")
  • 完了マークが付けられたすべての項目を削除するためのボタン (id="delete")
  • 項目リストを追加するための順不同リスト (id="todo-list")
  • リストが空になっているときにテキストを表示するための div タグ (id="no_items")

また、data-filter=’true’ プロパティーを <ul> タグに追加すれば (「参考文献」を参照)、データをフィルタリングできることにも注意してください (http://jquerymobile.com/demos/1.1.0/docs/lists/index.html)。

リスト 4. メイン・パネルの HTML
<!-------------------------- MAIN PAGE  -------------------------->
<div data-role="page" id="main" >

<!-- <div data-role="header"><h1>Todo App</h1></div> -->
<img class="centerimg" src="images/logonobg.png"/>

<div data-role="content" >

<input type="text" name="new-todo" id="new-todo" 
placeholder="Write your tasks here..." />

<div class="controls" data-role="controlgroup" data-type="horizontal">
<a href="#" id="add" data-role="button" data-icon="plus">Add New</a> 
<a href="#" id="delete" data-role="button" data-icon="delete">Delete Done</a>
</div>

<ul id="todo-list" data-role="listview" data-filter="true" data-inset="true" >
</ul><!-- /todo-list -->

<div class="center" id="no_items"></div>

</div>
<!-- /content -->
</div>
<!-- /page -->

タスク・リストの項目は、以下の例に示すように、リスト配列に格納します。

[{content: “myTodo Item 1", done: false},
{content: “myTodo Item 2", done: true}].

これはキーと値のペアによる JavaScript オブジェクトで構成される単純な配列で、項目の名前を表す文字列と完了項目であるかどうかを追跡するためのブール値が値として設定されているものです。

図 3 に示されているように、TD.List (このサンプル・アプリケーションの List モジュール) には、_encrypt() というプライベート・メソッドが定義されています。このメソッドは Public API から Vault モジュールの encrypt() メソッドを呼び出して、リスト (list という名前のプライベート配列) を暗号化します。TD.List には、HTML 文書内に定義された項目を表示するために、テンプレートから生成される _item_template() という関数もあります。この関数には、item というキーと値としてリスト配列を持つオブジェクトを渡す必要があります。

演習

演習として、より複雑な型チェック (例えば、item.done がブール値を返すかどうかのチェック、null に対するチェックなど) を実行することもできます。

プライベート関数 _add() は、item.content が空でないことや、’undefined’ でないこと、そして item.done を呼び出すと何らかの結果が返されることをチェックします。値が割り当てられていない変数は、デフォルトで ‘undefined’ を返すことに注意してください。

リスト 5. _add() 関数
_add =  function (item) {
if (item.content !== 'undefined' && item.done !== 'undefined' && item.content.length > 0)
{
list.push(item);
}
},// add item

_refresh_list() 関数は、リスト配列で動的に map 関数を実行して、その配列に格納されているすべてのオブジェクトに新しい要素を追加します。この関数の残りの部分では、リストをクリアし、リストを基に生成されたテンプレートの結果を HTML 内の順不同リスト (ul) に追加した後、ビューを最新の表示に更新します。この最後のメソッド呼び出しは、リストのスタイルを最新の状態に更新するための jQuery Mobile 特有の呼び出しです。

リスト 6. _refresh_list() 関数
_refresh_list = function () {

$.map(list, function (item, i) {
item.index = i;
});

list_ul.empty();
list_ul.append(_item_template({item : list}));
list_ul.listview('refresh');

if (list.length < 1) {
no_items.text('No items.');
} else {
no_items.text('');
}

}; // refresh list

もう 1 つの演習

この手法を変更して、異なるデータ構造と異なるアルゴリズムを使用して ID の生成と追跡を行うようにすることもできます。その目標は、map 関数を使用してリスト全体を繰り返し処理して ID を生成する必要をなくすこと、そして項目を追加または削除するたびに、リスト全体をクリアしてすべてを追加し直す必要をなくすことです。

次に、アクションをイベントにアタッチします。jQuery を使い慣れているとしたら、bind()、live()、delegate() などの呼び出しを見慣れていたり、使い慣れていたりすると思いますが、この例では on() だけを使用します。jQuery 1.7.0 以降、これらの bind()、live()、delegate() といったメソッドは、単なる on() のラッパーになっているためです。また、$(this) は、$this という名前のローカル変数に「キャッシュ」されます。これは、DOM の操作には非常にコストがかかるため、理想的には前述の jQuery 関数はできるだけ使用しないようにして、DOM (Document Object Module) に入り込む時間を制限することが望まれるからです。この例では、完了項目であるかどうかを記述するブール値をトグルして、スタイルシート (.css ファイル) に定義されている done クラスを追加または削除していることに注意してください。最後に、項目をクリックして完了マークを付けた直後にアプリケーションを閉じる場合であっても、リストを encrypt() で暗号化してから永続化します。

リスト 7. TD.List 内でのイベントのアタッチ
add_btn.on('click', function () {

_add({content : new_item.val(), 
done: false });

new_item.val('');
_refresh_list();

_encrypt();

}); // add btn

list_ul.on('click', 'li', function () {

var $this = $(this),
$item = $this.find('a'),
index = $item.attr('id'), 
current_item = list[index];

current_item.done = !(current_item.done);

if (current_item.done) {
$item.addClass('done');
} else {
$item.removeClass('done');
}

_encrypt();

}); // list item

delete_btn.on('click', function () { 
var i = list.length;

while (i--) {
if (list[i].done) {
list.remove(i);
}
}

_refresh_list();

_encrypt();

});// delete btn

削除ボタンにも同様の処理が適用されます。そのためのコードは、Worklight Studio で表示することができます。

List モジュールの Public API は極めて単純です。この API では、これから作業する対象の最新のリストを取得するための get()、新しいリストを設定して操作するための set()、現在設定されているリストを最新の表示に更新するための refresh() を使用することができます。これらのメソッドを呼び出すには、TD 名前空間の後にモジュールの名前を続け、最後にモジュールから返されるオブジェクトのキーのいずれかを追加して呼び出します。

以下の例を見てください。

TD.List.get(), TD.List.set([]), TD.List.refresh()

上記はすべて有効な関数です。次に、以下の例を見てください。

TD.List._refresh_list(), TD.List._add()

上記の関数は有効ではありません。これらの関数を呼び出せるのは、モジュール内から呼び出す場合 (関数がスコープを作成することを思い出してください)、または特権メンバー (モジュール内で返されるオブジェクトなど) が呼び出す場合のみです。

リスト 8. TD.List の Public API
//public API
return {
get : function () {
return list;
},
set : function (new_list) {
list = new_list;
},
refresh : function () {
_refresh_list();
}
};

Vault モジュール

TD.Vault モジュールは、Worklight の暗号化オフライン・キャッシュ (Encrypted Offline Cache: EOC) 機能のラッパーです。EOC はローカル・ストレージ上に HTML5 で作成され、cookie を使用しないで永続データを保管する方法となります。EOC には、ストレージをオープンおよびクローズするためのメソッド、そしてオープンされたストレージで値の読み取りおよび書き込みを行うためのメソッドが用意されています。EOC の背後にあるセキュリティーの詳細についてはこの記事では説明しませんが、要点を言えば、EOC はユーザー・パスワードを使用してデータを暗号化します。したがって、この特定のモジュールに関連する HTML コードは、以下の要素が含まれるページ (図 1 の最初のパネル) となります。

  • ロゴまたはアプリケーション名を表示するヘッダー・イメージ
  • パスコードの入力フィールド (id=’passcode’)
  • パスコードを送信するためのボタン (id=’send_passcode’)
リスト 9. パスコード・ページの HTML
<!-------------------------- PASSCODE PAGE  -------------------------->
<div data-role="page">

<img class="centerimg" src="images/logonobg.png"/>

<div data-role="content">

<div class="center" id="invalid_passcode"></div>

<ul data-role="listview" data-inset="true">
<li data-role="fieldcontain">
<label for="passcode">Enter Passcode:</label> 
<input type="text" name="passcode" id="passcode" value="" placeholder="Your passcode" />
</li>
</ul>

<a id="send_passcode" href="#" data-role="button" data-theme="a">Start</a>
</div>
<!-- /content -->

</div>
<!-- /page -->

JavaScript コードでは、まず、グローバル変数を自動実行関数に渡します。この例で渡すグローバル変数は、jQuery ($ として再定義) と WL (WL として再定義した Worklight の名前空間) です。次に、依存関係にローカル変数を割り当てることによって、依存関係を「キャッシュ」します。これにより、(WL 名前空間をパラメーターとしてモジュールに渡すことなく) 簡単に wl.EncryptedCache.open を呼び出して、eoc という名前のローカル変数に wl.EncryptedCache をキャッシュできるようになります。続いて、ユーザーが入力したパスフレーズを KEY というプライベート変数に格納し、パスコード・ボタン、パスコード・フィールド、そしてパスコードが無効な場合にエラー・メッセージを表示する div に対応する DOM 呼び出しを保存します (リスト 10 を参照)。

リスト 10. TD.Vault モジュール、依存関係、およびプライベート変数の定義
TD.namespace('TD.Vault');
TD.Vault = (function ($, wl) { 
//dependencies
var eoc = wl.EncryptedCache,
log = wl.Logger,
list_obj = TD.List,
CONST = TD.Constant,

//private variables
KEY = "",
send_passcode_btn = $('#send_passcode'),
passcode_fld = $('#passcode'),
invalid_passcode_div = $('#invalid_passcode'),

最後の演習

Worklight の資料を調べて、onErrorHandler() コールバック関数から返されたステータス・コードに基づくエラー固有の処理を実装してください。

続いて、いくつかのプライベート関数を定義します。最初の _error() は、エラー・コールバックを受け取った場合にログに記録するだけの関数です。_setData() および _getData() メソッドは、それぞれ暗号化および復号するデータの取得方法と設定方法を指定します (リスト 11 を参照)。

リスト 11. _error()、_setData()、および _getData() 関数の定義
//private functions
_error = function () {
log.debug("error");
},

_setData = function (new_list) {
if (new_list) {
list_obj.set(new_list);
list_obj.refresh();
} 
},

_getData = function () {
return list_obj.get();
},

イベント定義では、TD.List と同様に send_passcode_btn をクリック・イベントにアタッチし、ユーザーがアプリケーションの開始時に入力したパスコードの長さが 1 文字以上である場合、そのパスコードをプライベート変数 KEY に割り当てます (リスト 12 を参照)。

リスト 12. パスコード送信ボタンをイベントへアタッチする
send_passcode_btn.on('click', function () {

var passcode = passcode_fld.val();

if (passcode.length > 0) {
KEY = passcode;

_decrypt();

$.mobile.changePage("#main", { transition: CONST.DEFAULT_TRANSITION });

} else {
passcode_fld.val('');
invalid_passcode_div.text('Invalid Passcode.');
}

});

次に、EOC の中身を復号するためにプライベート関数 _decrypt() を呼び出します。この関数では、暗号化されたキャッシュをオープンした後に復号することになることを示す定数 (CONST.DECRYPT) を引数に指定して _open() を呼び出します。_open() 関数は eoc-open イベントをトリガーして該当するアクション (復号) を送信し、その結果として _read() が呼び出されます。_read() では、ユーザーが提供したキーを使用して、暗号化されたキャッシュの読み取りが試行されます。この時点で _setData() を呼び出し、parseJSON() によって構文解析されて JavaScript 配列に戻されたデータを引数として渡します (この配列には、すべてのインデックスに対して 1 つの項目を表すキーと値のペアが含まれています)。キャッシュから何かが返された場合には、List モジュールの set() を呼び出して、返されたリストを新しいリストとして設定します。そして最後に、TD.List の Public API の refresh() を呼び出して、HTML のリスト要素を最新の表示に更新します。

リスト 13. _close()、_write()、_read()、_encrypt()、および _decrypt() 関数と eoc-open イベント・リスナー
_close = function () {
var onCompleteHandler = function () { 
$.publish('eoc-closed'); 
};

//function(onCompleteHandler, onErrorHandler)
eoc.close(onCompleteHandler, _error);
},

_write = function () {
var data = JSON.stringify(_getData());

//function(key, data, onCompleteHandler, onErrorHandler)
eoc.write(CONST.TODO_ITEMS_KEY, data, _close, _error); 
},

_read = function () {
var onCompleteHandler = function (data) {
_setData($.parseJSON(data)); 
_close(); 
};

//function(key, onCompleteHandler, onErrorHandler)
eoc.read(CONST.TODO_ITEMS_KEY, onCompleteHandler, _error);
},

_encrypt = function () {
_open(CONST.ENCRYPT);
},

_decrypt = function () {
_open(CONST.DECRYPT);
};

$.subscribe("eoc-open", function (e, action) {
if (action) { // == CONST.ENCRYPT
_write();
} else { // == CONST.DECRYPT
_read();
}
});

暗号化もほとんど同じステップに従います。異なる点は、キャッシュをオープンした後のアクションが _read() ではなく、_write() の呼び出しであることです。その後、_getData() を実行して最新のリストを取得し、それを JSON.stringify() で文字列に変換した上で、そのストリングをキャッシュに格納します。暗号化および復号が完了するごとに、キャッシュをクローズしてください。

図 4 と図 5 に、完成したアプリケーションが iPhone シミュレーター上で実行されている様子を示します。

図 4. 完成したアプリケーションが iPhone シミュレーター上で実行されている様子 (パスコードのページ)
完成したアプリケーションが iPhone シミュレーター上で実行されている様子 (パスコードのページ)
図 5. 完成したアプリケーションが iPhone シミュレーター上で実行されている様子 (メイン・ページ)
完成したアプリケーションが iPhone シミュレーター上で実行されている様子 (メイン・ページ)

まとめ

IBM Worklight を紹介するこの連載の第 2 回では、第 1 回でセットアップした Worklight 開発環境を使用して、機能を追加し、Todo サンプル・アプリケーションを作成しました。その過程で、コードを構造化することによって、アプリケーションの開発、表示、保守にどのようなメリットがもたらされるかを学びました。さらに、Worklight の暗号化オフライン・キャッシュ機能を使用してデータ (タスク・リスト) を機器に永続化する方法についても学びました。この連載の最終回では、アダプターによるサーバー・サイドの接続性を追加して、サンプル・アプリケーションを仕上げます。


ダウンロード

内容ファイル名サイズ
Sample application project filestodo-app-part2.zip18.5MB

参考文献

学ぶために

製品や技術を入手するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Mobile development, WebSphere
ArticleID=831687
ArticleTitle=Worklight を使用する: 第 2 回 構造化モジュールを開発して IBM Worklight の暗号化オフライン・キャッシュ機能を使用する
publish-date=08302012