読者です 読者をやめる 読者になる 読者になる

imthinker::net

ふらふらうぇぶろぐ

Titanium™ をはじめるとき

Titanium Mobile Alloy

Titanium™ Advent Calendar 8 日目は 2 日目と一転して「Titanium™ をはじめるとき」というテーマで「今、 Titanium をはじめるなら !? 」を書いてみたいと思います。それではよろしくお付き合いください。

STEP 0 : Mac を買う

f:id:RyuGoo:20131206233701p:plain

これから Titanium を使ってアプリ開発をされる方は、できれば OS X 上で開発されることをオススメします。環境構築の手間や iOS も視野に入れた開発を行うためには Mac の方が何かと便利です。 MacBook Air でも何とかなります。

STEP 1 : JavaScript を知る

Titanium を使い始める前に JavaScript についての基礎的な知識は頭に入れておいた方が良いでしょう。特に C や Java といったお堅い言語に親しんだ方からすると、 JavaScript は自由奔放すぎて戸惑うことが多いかもしれません。

Ruby や Python などの LL と比較しても JavaScript は不思議な言語だと思います。文法は C によく似た形ですが、中身はまるで違います。例を紹介します。

スコープ

多くの言語は if 文 や for 文の中にオブジェクトのスコープが作られますが、 JavaScript はスコープが作られません。スコープを持つのは関数だけです。

// if 文は {} の中にスコープを提供しない
var hello = 'world';
if (hello === 'world') {
    var foo = 'bar';
}
console.log(foo); // bar

// for 文も {} 中にスコープを提供しない
for (var i = 0, l = 100; i < l; i++) {
    console.log(i); // 0 〜 99
}
console.log(i); // 100
console.log(l); // 100

// 関数は {} の中にスコープを提供する
function myFunc() {
    var fizz = 'buzz';
    hello = 'titanium';
}
myFunc();
console.log(fizz); // fizz というオブジェクトは見つからない
console.log(hello); // titanium (関数の中から外にある変数を操作できる)

関数

JavaScript の関数は第一級オブジェクトです。要は超凄いやつです。

// 普通の関数
function normalFunc() {
    console.log('普通の関数');
}

// 変数に入れられる (関数リテラル)
var literalFunc = function () {
    console.log('関数リテラル');
};

// 関数を引数にできる
function argsFunc(callback) {
    callback();
}
argsFunc(literalFunc); // 関数リテラル

// 関数を受け取ることもできる
function giftFunc() {
    return function () {
        console.log('どうぞ');
    };
}
var getFunc = giftFunc();
getFunc(); // どうぞ

他にも他言語と違いを感じる場面もありますが、いざ使ってみるとこの柔軟性に助けられる場面も多いです。もう少しカチッとさせたければ、 CoffeeScript や TypeScript も Titanium では使えるので、検討すると良いと思います。

STEP 2 : Alloy を使う

「Titanium は JavaScript を使って iOS や Android に対応する、ネイティブな UI を持つアプリを作るためのツールです」… 私はこの文言を多くの場面で使ってきました。これは正しくもあり、これからを考えると不適切かもしれません。

Appcelerator は Titanium 用の MVC フレームワークとして Alloy を提供しています。 Alloy が登場した当初は日本のユーザーコミュニティ内部でも「本当に使えるのか」「またベストプラクティスが変わるのではないか」と懸念していましたが、この懸念は杞憂であったと私は考えています。

Alloy は XML / TSS (Titanium Style Sheet) / JavaScript の 3 本立てで Titanium アプリを構築するフレームワークです。コードをビルドすると、 Titanium 向けに最適化された JavaScript に変換され、そのまま Titanium アプリとして実行できます。

f:id:RyuGoo:20131207200718p:plain f:id:RyuGoo:20131207200710p:plain

index.xml

<Alloy>
  <TabGroup>
    <Tab title="tab1">
      <Window title="window1" class="win">
        <Label text="label1" id="lbl1" onClick="lbl1Click" />
      </Window>
    </Tab>
    <Tab title="tab2">
      <Window title="window2" class="win">
        <Label text="label2" id="lbl2" onDblclick="lbl2Dblclick" />
      </Window>
    </Tab>
  </TabGroup>
</Alloy>

index.tss

".win": {
  backgroundColor: '#FFFFFF'
}
"Label": {
  font: {
    fontSize: '16sp'
  }
}
"#lbl1": {
  font: {
    fontWeight: 'bold'
  },
  color: '#666666'
}
"#lbl2": {
  font: {
    fontWeight: 'italic'
  },
  color: '#FF0000'
}

index.js

function lbl1Click(e) {
    alert(e.source.text); // label1
}

function lbl2Dblclick() {
    alert('ダブルクリック');
}

$.index.open(); // TabGroup を開く

※ これらのコードは Titanium 3.2-beta / Alloy 1.3-beta で確認を行っています。

見ての通り、 Alloy は XML で見た目の構造を作り、 TSS で見た目の装飾を行い、 JavaScript でインタラクションを構成します。 XML, TSS, JavaScript で共通する名前を持つものが関係を持っていて、とても管理しやすくなっています。

これだけだと VC フレームワークですので、ロジックを記述するに適したモデル (M) を別途、 JavaScript で構成しますが、これもまた Backbone.js を土台にした大変便利な機能を持っていて、 SQLite とシームレスなやり取りを実現しています。

TableView や ListView と SQLite 上のデータをマッピングするための便利な記法も用意されていて、全てを JavaScript で書く通常の Titanium アプリ構築よりも素早くアプリを動作させるところまで持って行けるでしょう。

STEP 3 : Titanium を知る

STEP 2 と並行して、 Titanium がどのようなものなのかを API や思想から知りましょう。いくら Alloy が素早くアプリを構築できるフレームワークだとしても、 Titanium が提供する API が分からなければ使い物になりません。

また、 Titanium は iOS と Android の両方に対応するアプリを作ることができますが、 1 度書いた同じコードを走らせることを推薦しているツールではありません。場合に応じて、それぞれのプラットフォームに合わせたコードを書き分けます。

これを Write once, adapt anywhere と呼びます。 run anywhere ではないことに注意が必要です。 Alloy 以前は UI 含めて JavaScript で全て書いていたので、 iOS と Android でコードを書き分けると大変なことになりがちでした。

しかし、 Alloy 以降はコードの書き分けが行いやすくなっています。 View に関しては views/ios , views/android ディレクトリに分けて XML を配置すれば OK ですし、 JavaScript 中では

if (OS_IOS) {
    // iOS の場合
}

if (OS_ANDROID) {
    // Android の場合
}

のように書き分けることができます。もちろん、 TSS にもプラットフォームごとに適応するスタイルを分ける構文が用意されています。

こうした情報は API ドキュメント に記載されています。また同じページには 充実したガイド も用意されているので、こちらにも目を通すと良いでしょう。特にガイドにはチュートリアル的なものも用意されていて、初学者に最適です。

残念ながら Titanium のドキュメントは英語でしか提供されていませんが、比較的平易な英文で書かれていますので、 Google 翻訳などの力を借りながら読み解くことができるでしょう。

また、 Titanium Mobile ユーザー会 では毎月「もくもく会」という勉強会を開催していて、 Titanium Certified Expert 資格を持ったメンバーも来ていますので Titanium で疑問がある場合に質問することができます。

APPENDIX : Titanium 向きのアプリ

以上の 3 ステップ + 1 が今どきの Titanium のはじめかたです。 Alloy の利用を前提とするのが良いと考えています。最後に Titanium 向きのアプリとは何かを考えてみたいと思います。これの答えは単純なものです。

OS 標準の UI を持つ、ウェブ API と連携するタイプのアプリ

これが Titanium 向きのアプリだと思います。 Titanium には HTTPClient API があり、これを使うと少ないコードでシンプルな HTTP 通信を行うことができます。

var http = Ti.Network.createHTTPClient();
http.onload = function () {
    console.log(JSON.parse(http.responseText));
};
http.error = function (e) {
    console.error(e);
};
http.open('GET', 'http://ip.jsontest.com/');
http.send(null);

もしもウェブ API と連携したクライアントアプリを作りたい場合、 Titanium は有力な選択肢になります。

こうして書くとかなり限定的なシーンでしか使えないように思えますが、このあたりはネイティブモジュールを組み込むことでパフォーマンスの問題を解決したり、機能を補ったりして、対応の幅を広げることができるでしょう。

ただし、モジュールに頼りすぎるとマルチプラットフォーム対応が難しくなるという副作用もあります。 iOS と Android 両対応のアプリを作りたい場合は注意が必要です。

自分がやろうとしていることは何か、何を作ろうとしているのかを把握した上で、もしも Titanium がフィットしそうならば、そのときが Titanium をはじめるとき です!選択肢の 1 つとして、是非ともどうぞ。

(無理矢理 ('A`))


9 日目は Kota Iguchi さんです。今日書いた内容全てを一変してしまうかもしれない、次世代 Titanium = Ti.Next について何かを書いてくださるようです!