Special thanks to Simon Brunel, creator of JDI. He gave me permission to use JDI’s code to describe how to develop Sencha Touch apps. I sincerely appreciate his great works and fraternity!
それでは JDI の作成に取りかかりましょう。今回は、アプリへの認証機能を実装します。
- ログイン画面

- ログアウト画面

今回のチュートリアルの完成形は、以下の URL から利用できます。
JDI at Tutorial #1:
http://apps.kawanoshinobu.com/jdi-1
JDI は HTML5 is Ready App Contest で 1 位を獲得した Sencha Touch アプリです。アプリの概要については、チュートリアル #0 を参照して下さい。
Sencha Touch Tutorial: HTML5 is Ready App Contest 1位アプリ「JDI」を作る #0:
http://dev.ariel-networks.com/wp/archives/3270
On your mark!
プロジェクトの作成と Sencha.io の準備を行います。
プロジェクトの準備
プロジェクトのディレクトリを作成して、application というディレクトリ以下に Sencha Touch アプリの雛形を生成します。
$ mkdir jdi
$ cd jdi
$ sencha -sdk ../touch-2.2.0 generate app App application
...
JDI では、データの永続化とログイン認証、異なるデバイス間でのデータの同期に Sencha.io を利用しています。Sencha.io の API を利用するために application 以下に libraries/sencha-io ディレクトリを作成して、そこに Sencha.io SDK を配置します。
Sencha.io SDK:
http://download.sencha.io/sencha-io-0.7.13.zip
$ mkdir -p libraries/sencha-io
$ cp -r ~/Downloads/sencha-io-0.7.13/ libraries/sencha-io/
プロジェクトの準備を簡単に行うために、雛形プロジェクトを作りました。上記の手順を手作業で行う代わりに、以下のリポジトリを利用しても構いません。clone した後 Ant の initialize タスクを実行し、その後 Sass のコンパイルを行って下さい。
https://github.com/kawanoshinobu/sencha-io-app-template
$ git clone https://github.com/kawanoshinobu/sencha-io-app-template.git jdi
$ sencha ant -f project.xml initialize
$ compass compile application/resources/sass/
Sencha.io
Sencha.io 側でアプリの準備を行います。まだアカウントがない場合は、以下の記事を参考に作成して下さい。
Practical Sencha Touch #3: Sencha の BaaS「Sencha.io」を使う:
http://dev.ariel-networks.com/wp/archives/3058
Sencha Cmd を使って Sencha.io にアプリを作成します。この際に生成される AppId は開発時に必要になるので書き留めておいて下さい。その後、アプリで利用する認証グループを作成し、アプリと関連づけます。
$ sencha io create-app jdi {$ユーザー名} {$パスワード}
Sencha Cmd v3.1.1.274
[INF] initializing Sencha.io...
[INF] authenticating developer...
[INF] using team: kawanoshinobu...
[INF] creating app: jdi...
[INF] App created successfully! Use the following AppId and AppSecret in your application code.
[INF] AppId: 78166768-435f-400c-a8cf-ccd70a49c01e
[INF] AppSecret: pGNF8CBDzmKiEfxH
[INF] shutting down Sencha.io...
$ sencha io create-auth-group jdi {$ユーザー名} {$パスワード}
Sencha Cmd v3.1.1.274
[INF] initializing Sencha.io...
[INF] authenticating developer...
[INF] using team: kawanoshinobu...
[INF] Created Auth. Group : jdi
[INF] shutting down Sencha.io...
$ sencha io app-set-group jdi jdi {$ユーザー名} {$パスワード}
Sencha Cmd v3.1.1.274
[INF] initializing Sencha.io...
[INF] authenticating developer...
[INF] using team: kawanoshinobu...
[INF] Auth Group successfully set for app
[INF] shutting down Sencha.io...
以上で下準備は完了です。実際にコードを書き始める前に、開発時の注意を 2 点。
Touch 2.2 で生成したプロジェクトでは、開発時に利用するフレームワークのコードが sencha-touch.js になっています。ただ、このままだとコードが圧縮されていてデバッグしづらいのと、エラーや警告を出してくれないので sencha-touch-all-debug.js を利用するように変更した方がよさそうです。
// application/app.json
"js": [
{
// "path": "touch/sencha-touch.js",
"path": "touch/sencha-touch-all-debug.js", // *1
"x-bootstrap": true
},
...
また開発時に利用するファイルの動的ローディングでは、現在のタイムスタンプをパラメータに指定して読み込むことで、ブラウザのキャッシュを回避しています。ただ、この仕組みだとデベロッパーツールでブレークポイントを張れません。コードをデバッグする時は Ext.Loader のコンフィグで disableCaching オプションに false を指定するとよいでしょう。
// application/app.js
Ext.Loader.setConfig({ disableCaching: false });
Get set, start coding!
お待たせしました、それでは認証機能の実装を始めましょう。application ディレクトリに移動し Main コントローラを作成します。
$ cd application
$ sencha generate controller Main
続いて application/app.js で Sencha.io のアプリとの関連づけを行います。
// application/app.js
Ext.Loader.setPath({
'Ext.io': 'libraries/sencha-io/src/io', // *1
'Ext.cf': 'libraries/sencha-io/src/cf', // *2
'Ext': 'touch/src',
'App': 'app'
});
io: {
appId: '78166768-435f-400c-a8cf-ccd70a49c01e' // *3
},
controllers: [
'Main',
'Ext.io.Controller' // *4
],
Ext.Loader に Sencha.io クラスの読み込みの設定を行います(*1, *2)。また io コンフィグの appId オプションに Sencha.io アプリの AppId を指定します(*3)。そして contollers オプションで Ext.io.Controller クラスを読み込むように指定します(*4)。この際、Main コントローラの後に Ext.io.Controller を読み込むよう指定する必要があるので注意して下さい。
実はこれだけで、認証機能が実装できてしまいます。未認証のユーザーの場合、ログイン画面が表示されます。認証後はログアウトボタンが表示されます。アカウントがないユーザーのための新規登録画面も用意されます。

このように Sencha.io と関連づけることで、自動で認証機能が備わります。ただ、今回は独自のログイン画面・ログアウト画面を作りたいので、io コンフィグに以下の設定を追加します。
io: {
appId: '78166768-435f-400c-a8cf-ccd70a49c01e',
manualLogin: true, // *1
authOnStartup: true // *2
},
ログインのタイミングを自由に実装できるよう manualLogin オプションに true を指定します(*1)。これで自動で認証画面が表示されなくなりました。その場合でも、authOnStartup オプションに true を指定して、起動時に認証は行うようにしておきます(*2)。
認証機能の構成
JDI では、認証機能を実現するために以下のクラスが構成されています。
View
view/AuthPanel.js
メールアドレスとパスワードを入力するログインフォームです。ログインボタンとアカウント登録ボタンを用意して、状況に応じて表示を切り替えています。また、ボタンのタップイベントを一旦ビューでハンドリングして、その後カスタムイベントを発火してコントローラ側に処理を委譲しています。
view/SplashScreen.js
アプリのロゴ、認証後に表示するユーザー情報パネル、認証フォームを保持するコンテナです。また、状況に応じてユーザー情報パネルを表示するか、認証フォームを表示するかを切り替えます。また JDI ではログインしたユーザーの顔写真を表示するために Gravatar API を利用しています。API へのリクエストが完了した後、userloaded イベントを発火します。
view/UserPanel.js
ユーザー情報(画像、アカウント名、メールアドレス)とログアウトボタンを表示するパネルです。
view/Main.js
アプリのメイン画面です。今回はツールバーだけを配置しています。
view/ToolBar.js
JDI 用にカスタマイズしたツールバーです。今回はユーザーパネルを表示するためのボタンだけを配置しています。
Widget
JDI では view ディレクトリと controller ディレクトリに並列して widget ディレクトリを作成しています。このディレクトリにはビューよりも細かい単位の再利用可能なコンポーネントを配置しています。
widget/ToolButton.js
状態を持つボタンです。チェックしている時とそうでない時で見た目を切り替えます。
Controller
controller/Main.js
Sencha.io の初期化、ユーザーのログイン・新規作成・ログアウト、SplashScreen の表示などアプリ全体に関わる処理を行うコントローラです。
controller/User.js
Gravatar API を使った画像データの取得やユーザー情報の表示を制御するコントローラです。
都合上細かい説明は割愛しますが、リポジトリを参考にコードを写経してみて下さい。これらのクラスを実装すると、以下の表示になります。
- ログイン画面

- ログアウト画面

認証の流れとしては、まず Ext.Viewport に SplashScreen ビューを追加し、未認証の場合に SplashScreen を表示、そうでない場合は SplashScreen を破棄することで、ログイン画面を制御しています。認証には Sencha.io の Ext.io.User.authenticate メソッドを利用しています。認証後はメールアドレスを元に Gravatar API を使ってユーザー画像を取得し表示します。ログアウトボタンのタップイベントをトリガーに Sencha.io の API をコールしてログアウトします。
Apply makeup
機能の実装が完了したら、見た目を調整しましょう。JDI では、dark.scss というファイルを resources/sass ディレクトリに作成しています。アプリケーションで dark.scss をコンパイルして出力される dark.css ファイルを利用するよう app.json を以下のように変更します。
"css": [
{
"path": "resources/css/dark.css", // *1
"update": "delta"
}
],
JDI で特徴的な部分として Android の Roboto フォントが使われている点が挙げられます。フォントファイルを resources/fonts ディレクトリに配置して、Sass のコンパイル時に参照できるよう config.rb を変更します。これに伴い、resources/sass/stylesheets/pictos ディレクトリも application/resources ディレクトリに移動します。
# resources/sass/config.rb
...
# Compass configurations
relative_assets = true
sass_path = dir
css_path = File.join(dir, "..", "css")
fonts_dir = File.join("..", "fonts")
images_dir = File.join('images')
今回の認証機能に必要なスタイルの記述は、以下のリポジトリを参考にして下さい。詳細の解説は割愛させて頂きます。
https://github.com/kawanoshinobu/jdi-at-tutorial-1/tree/master/application/resources/sass/stylesheets/dark
また前回のチュートリアルでもお話しましたが、Touch 2.2 では $font-family 変数が動かなくなっています。フレームワークの _Class.scss ファイルに以下の変更を適用して下さい。
// application/touch/resources/themes/stylesheets/sencha-touch/base/src/_Class.scss line:1
html, body {
// font-family: "Helvetica Neue", HelveticaNeue, "Helvetica-Neue", Helvetica, "BBAlpha Sans", sans-serif;
font-family: $font-family;
font-weight: normal;
-webkit-text-size-adjust: none;
margin: 0;
cursor: default;
}
Conclusion
駆け足でしたが JDI の認証機能について解説しました。今回取り上げた内容を反映したリポジトリを以下に用意しました。説明が不足している箇所に関しては、このリポジトリのコードを参考にして頂ければと思います。
jdi-at-tutorial-1:
https://github.com/kawanoshinobu/jdi-at-tutorial-1
See Also
jdi (Original):
https://github.com/simonbrunel/jdi
How to use User Services:
http://docs.sencha.io/current/index.html#!/guide/concepts_user
関連文書: