Titanium＋Alloyではじめて開発する人向けのサンプルアプリ（基礎編）

## はじめに

現在、Titaniumでの開発をマンツーマンで教えてる方がいて、Classic環境でひと通りの基礎的なことをマスターしてもらったので、今度はこれをふまえてAlloyでの開発・・と思ったんだけどサンプルアプリ＆解説がないことに気づきました(^_^;)

で、自分のブログで以前まとめた記事があったのでそれを流用しつつ、自分で記事を書くことにしました

応用が効きそうな分野で言うと、メイン画面→詳細画面に遷移するというようなアプリをイメージしてます

### 自分の実行環境

- Mac OS X 10.9.5
- Titanium SDK 3.3.0.GA
- XCode 5.1.1
- alloy 1.4.1

## Titanium でAlloy用の新規プロジェクト作成する


### File→New →Mobile App Projectと進む

![shot-2015-01-10-7.00.58.png](https://qiita-image-store.s3.amazonaws.com/0/10187/855965b4-aa1c-fc0b-ba08-656adef0467b.png)

### 左側のタブでAlloyを選択。右側はひとまずTwo-tabbed・・のテンプレートを選択します

![shot-2015-01-10-7.01.06.png](https://qiita-image-store.s3.amazonaws.com/0/10187/c5ea4dc4-fab3-cc7c-d5c6-233df61f4db5.png)


### プロジェクト設定を行います

- 赤字の所を適宜読み替えて設定してください
- ひとまず今回はiOSをターゲットにしてるのでチェックボックスはiOSのみになるようにしておいてください


![shot-2015-01-10-7.01.35.png](https://qiita-image-store.s3.amazonaws.com/0/10187/2524f419-947f-22bf-0efc-b3efd013fdd0.png)




## 画面遷移系のサンプルアプリ

これから作るアプリはこのようなものを想定してます

### 起動時の画面

![shot-2015-01-10-7.30.57.png](https://qiita-image-store.s3.amazonaws.com/0/10187/e850afbf-da48-3ceb-44b7-de2f83252d78.png)

### ラベルをタッチした時に遷移して遷移後の画面

![shot-2015-01-10-8.29.04.png](https://qiita-image-store.s3.amazonaws.com/0/10187/c519dbcb-3154-aabd-0856-bd05749ad48e.png)



## 起動時の画面を作る

従来のClassic環境での開発と異なり、[本家公式ガイド](http://docs.appcelerator.com/titanium/latest/#!/guide/Alloy_Concepts)に記載されてるようにAlloyではアプリケーションを以下3つに分割して開発を進めていきます。

- Model 
  - データ、アプリケーションの状態を含んだビジネスロジックを提供します。
- View 
  - データを表示したり操作するためのGUI コンポーネントをユーザに提供します。
- Controller 
  - Model と View のコンポーネント間をつなぐアプリケーションロジックを提供します。

> 補足：ここでいうMVCはBackbone.js由来のMVCになります。Alloyは、Backbone.jsがベースになってるためWebアプリケーションの世界でイメージされるMVCの考えで行くと少し違和感を感じる所があるかもしれないので、本格的な開発を進めていく時にはBackbone.js自体についての理解を進めておくことをオススメします

今回のアプリはとてもシンプルなものなので、結果としてView とControllerの機能しか使わないため、以下ViewとControllerの役割を簡単に解説しながら具体的なコードを示していきます

### Viewについて

従来のClassic環境では

- UI要素の生成
- UI要素の色、幅、高さなどの定義

というのが入り組んでしまい、徐々にソースコードの見通しが悪くなってしまう状況になり得ます。

Alloyは独自の規約を課すことで、この辺りを解決しようとしてます。まぁこのあたりはRailsの設定より規約の考えを取り入れてる感じです。（詳しいことは[Alloyコンセプトの日本語訳](https://github.com/ledmonster/alloy-doc-ja/blob/master/Alloy_Concepts.md#%E8%A8%AD%E5%AE%9A%E3%82%88%E3%82%8A%E8%A6%8F%E7%B4%84)を参照してください）

AlloyでのViewは

- UI要素の生成
  - /プロジェクトフォルダ/app/views配下に規約にしたがってXML形式のファイルを準備する 
- UI要素の色、幅、高さなどの定義
  - /プロジェクトフォルダ/app/styles配下に規約にしたがってTSSというスタイルシートっぽいファイルを準備する 

という流儀に沿って開発を進めます

#### /プロジェクトフォルダ/app/views/index.xml

Tab１に表示される項目を一部変更してみたいと思います。

プロジェクト設定時に作成されてるXMLファイルを以下のように編集します

```xml
<Alloy>
	<TabGroup>
		<Tab id="tabOne" title="Tab 1" icon="KS_nav_ui.png">
			<Window title="Tab 1" id="mainWindow" class="container">
				<Label id="label">Hello, World!!!!!!!</Label>
			</Window>
		</Tab>
		<Tab title="Tab 2" icon="KS_nav_views.png">
			<Window title="Tab 2">
				<Label>I am Window 2</Label>
			</Window>
		</Tab>
	</TabGroup>
</Alloy>

```

#### /プロジェクトフォルダ/app/styles/index.tss

WebのHTML/CSSのIDセレクタ、クラスセレクタと同じように記述します。

```css
".container": {
    backgroundColor:"#fff"
},
"#label": {
    width: "100%",
    height: 40,
    color: "#000",
    top:"50%",
    left:0,
    textAlign:'center'
}  
```



- 上記XMLで＜Window .... class="container"＞というマークアップをしてますが、ここでcontinaerというクラスセレクタを**.container**内で定義してます
- 上記XMLで＜Label id="label"＞..というマークアップをしてますがこのlabelというIDセレクタに紐づくものを**#label**にて定義してます


### Contorollerについて

従来だとTi.UI要素を生成して、イベントリスナーを定義して・・という形のソースコードになりがちでしたがAlloyの場合には/プロジェクトフォルダ/app/controllers/配下に、ネーミングルールに沿ったJavaScriptのファイルを配置してそこにロジックを記述します

#### /プロジェクトフォルダ/app/controllers/index.js

今回は画面遷移をおこないため

- 遷移先になるコントローラーを生成する
- 生成されたコントローラーのメソッドを呼び出すことで以下が実現されます
  - 新しいWindowの生成を実施
  - 現在のTabで新しいWindowを開くようにする

という流れになります。

```js

$.index.open();

$.label.addEventListener('click', function(e) {
  var newWindow;
  newWindow = Alloy.createController('newWindow');
  return newWindow.move($.tabOne);
});$.index.open();
```

## 遷移先の画面を作る

遷移先の画面に関する処理を ViewとContorollerに関連するファイルを作成します。ひとまず newWindow という名前でそれぞれのファイルを作ることにします

### Viewについて

起動時と同様の流れでXMLとTSSを作ります。

#### /プロジェクトフォルダ/app/views/newWindow.xml

```xml
<Alloy>
  <Window id="newWindow" class="container">
    <Label id="label">This is a new Window</Label>
  </Window>
</Alloy>

```

#### /プロジェクトフォルダ/app/styles/newWindow.tss

```css
".container": {
    backgroundColor:"#fff"
},
"#label": {
    width: "100%",
    height: 40,
    color: "#000",
  top:"50%",
  left:0,
  textAlign:'center'

} 
```

### Contorollerについて


#### /プロジェクトフォルダ/app/controllers/newWindow.js

呼び出す側のindex.jsで

```js
xxxx.move($.tabOne);
```

move()というメソッドを定義して、かつ、Viewにあたるindex.xmlのTabにtabOneというidを設定しているのでそのTabを受け取れるように実装します。

```js
exports.move = function(_tab) {
  Ti.API.info(_tab);
  return _tab.open($.newWindow);
};

```

上記のような実装をすることで、遷移元が現在ActiveなTi.UI.Tabの情報を受け取りつつ、画面遷移が実現できます。

※ 画面遷移の方法はもしかしたらもっと良いやり方があるかもしれないので、他のやり方されてる方がいましたらコメントお願いします

## 終わりに

Alloyでの開発は、独自の流儀というか規約があるためそれに沿った開発を強いられるため慣れないうちはストレスを感じるかもしれません。

ただその規約を理解してしまうと、そこからいっきに開発が進められるのでこの記事がAlloyへの移行のきっかけになれればと思ってます。



## 参考にした情報のまとめ

- [Alloy コンセプトの日本語訳](https://github.com/ledmonster/alloy-doc-ja/blob/master/Alloy_Concepts.md)
  - 上記以外にも[Alloyの公式ガイドの情報を翻訳](https://github.com/ledmonster/alloy-doc-ja)されてます。更新が1年前からストップされてますが全体を網羅されてるので一読するのをオススメします