Okayama.rbに行ってきました。

本日もOkayama.rbに参加してきました。
参加者は3人。

会社のチームメンバーだけという!!

まぁそれはおいといて、今日は私は先日リリースしたIonicRssReaderのテストをJavaScriptで書く!というのを目標にJavaScriptのテスト周りの調査をしつつ、情報共有ということでmiddleman + Cordova + ionic frameworkの組み合わせの環境構築の手伝いをしてました。

JavaScriptのテストに関しては、mocha + expect.jsの組み合わせで試し中。まだAngularJSのテストまでは書いていないけれど、CoffeeScriptが動くところまで確認できたので、よしとしましょう。

mochaとexpect.jsのインストール
1
2
3
4
npm install -g mocha
npm install -g expect.js
mkdir test
cd test

そしてmocha.optsファイルを作成します。–requireはあってるかどうかわからん…。

test/mocha.opts
1
2
3
4
5
6
7
--require expect.js
--reporter spec
--ui bdd
--growl
--watch
--recursive
--compilers coffee:coffee-script/register

この–compilers coffee:coffee-script/registerが肝でした。CoffeeScriptのバージョンが1.7以上の場合はこうじゃないと変なところでエラーが起きるようでした。これで、テストの実行は

mocha

を実行するだけでした。とりあえずこれでテスト自体は動いたけれど、自分がやりたいアプリのテストはできてないので、今後それをやっていけるようにしたいと思います。まずテスト動いてよかった。

その後、middleman + cordova + ionic framework。
自分が開発したコードの一部を渡して修正してもらって、動かしてみると、動かない…。自分の環境では動いてる。謎過ぎる…。とりあえずバグがなんなのかを探るために、色々削っていっても動かない。
諦めて帰る前に、このディレクティブを参考に、とionic frameworkのドキュメントを見せようとしたら、ディレクティブの先頭にion-の文字が…。

どうも昨日(2/19)バージョンアップして、ディレクティブ名のプレフィックスにion-が付くようにが変わったようでした。

ionic frameworkでアプリを作っている人はアップグレードしたら動かなくなるので気をつけましょう!

原因が何なのか全くわからなかったから、めっちゃハマってしまった…。middlemanの設定が悪いのかなーとも思ったし…。まぁ解決してよかったです!


CordovaでIonicRssReaderを作って公開してみた。

Cordova(PhoneGap)でAndroidアプリを作って公開してみました。
Cordovaはhtml5でマルチプラットフォームのアプリを作るためのツールです。今回は、かねてから調べていたionic frameworkで作ってみました。

IonicRssReader(Android 4.2+)

  • RSSフィードのタイトルとURLを登録する
  • タイトルを押すとフィードを読み込んでカードリスト表示
  • 登録したRSSフィードの削除
  • 外部ブラウザでフィードを表示

くらいまでできます。
見た目はこんな感じ。

device-2014-02-18-230813-7 device-2014-02-18-230950-13-3
device-2014-02-18-231035-7 device-2014-02-18-231106-10

作り方の説明は全部していると長いので、概要だけざっと書きます。
機会があればどこかにちゃんと記事を書きたいなぁ〜。

html,js,cssの生成はMIDDLEMANを使っています。middlemanは静的サイトを生成するためのツールです。記述は流行りのHaml, Coffeescript, Sassを使って記述して、内蔵サーバ(sinatra)を起動して確認できます。設定は多少あります。Cordova+Middleman用のテンプレートがありますからそれを使ってみました。詳細はリンクから。htmlを生成する言語はデフォルトだとHamlですが、私はSlim派なので書き換えました。

https://github.com/pixelsonly/middleman-cordova

上記のテンプレートはbower(jsのパッケージ管理ツール)を使えるようになっており、デフォルトだとjQueryとかを含んでいるので、それを削除してionicを読み込むようにしました。

middlemanの内蔵サーバの起動は簡単。これだけです。

完成したらmiddleman buildで静的ファイルを作り出します。

buildしたhtml,js,cssをAndroid用にコンパイルして実行します。

1
2
cordova build android
cordova run android

これで実機で確認できました。とりあえずmiddleman build, cordova build, cordova runを繰り返しながら開発していたのですが、Rubyist的にはSlim, CoffeeScript, SassでAndroidアプリ、iPhoneアプリが作れるのはいいなぁと思います。しかも、見た目の部分はionic frameworkがかなりいい感じで提供してくれるので、すごくしょぼいデザインになる、ということはないでしょう。また、ionic frameworkはAngularJSを前提としていて、最初から書きやすいdirectiveを提供してくれている点もいいですね。普通にアプリ作るのにjQueryは要りません。IonicRssReaderにはjQuery(zepto)は入れてません。

アプリによっては向き不向きはあるとは思いますが、ひどくモッサリする、ということはないかなと思いました。
あとフォームのバリデーションが、AngularJSを使うと割と簡単なので、そこがよかったです。とりあえずAngularJSが楽しいし、Androidアプリは学習コストが非常に高くなっていると思うので、こういうアプローチでさくさく作るのもいいかなって思ってきてます。


Ionic Framework & Cordova & Middlemanでやってみようと思う。

昨日のOkayama.rbでApache Cordovaでネイティブアプリを作れるということはわかったので、ちょっと調査をしていました。やっぱりhtml, js, cssはSlim, CoffeeScript, Sassで書きたくなるのがRails使いの性。

Node.js製のYeomanをいじってやるのが正解かと思っていたのですが、Ruby製で似たようなものがあると知りました。それがMiddlemanです。middleman自体はgemになっていて、静的サイトを作るのをサポートするものになります。まるでRailsのviewとassetsだけを使えるようにした感じです。Slimでhtmlを構成することに慣れている自分としては、これは非常にありがたいし、CoffeeScriptもSassも書けるしLiveReloadにも対応しています。素晴らしい。さようなら、Yeoman。

middlemanを試してみるのは非常に簡単です。

1
2
3
4
middleman init my_project
cd my_project
middleman # サーバ起動
middleman build # 静的ファイルを生成

config.rbをいじればLiveReloadもできるし、buildの場合のみの設定なども行うことができます。

middlemanでCordovaプロジェクトを書くための便利ツールないかな?と思っていたら、ありました。

github: middleman-cordova

ただこれはhaml前提、jQuery前提だったりしたので、自分なりにbower.jsonをいじったりしながらionicを入れたり、テンプレートをSlimに入れ替えたりしながら、自分なりのテンプレートを作ってみました。まだちょっと公開できるレベルじゃないので、公開していませんが、いい感じになったら公開したいと思います。

このmiddlemanとionicで動くテンプレートを作っている最中に気づいたのですが、ionic frameworkはAndroid4.2+じゃないと動きません。正確には、標準ブラウザではAndroid4.2+じゃないと動きません。G’z Oneでチェックしていたら、ヘッダーが全然表示されないので原因を探っていたのですが、標準ブラウザの場合だけそうなりました(Chrome for AndroidならOK)。Cordovaを使ってネイティブアプリにすると、ICSだとChromeが使えないので、そこはすっぱり切ってAPI Levelを17にすればいいと思います。

試しにRSSリーダーか何かを作ってみようかなと思います。


Okayama.rbに参加してきました。

Okayama.rbに参加してきました。
本日の参加者は、以下の3人。

今日はrubyというよりもハンバーグ食べた後にそれぞれ好きなことをしてました。
僕はSelfieGirlで使っているフレームワークのionicがバージョンアップしたらしかったので入れ替え作業をしてました。その後は、Apache Cordovaについて調べてました。調べていたといっても、ionic frameworkのGet Startのアプリ部分のコードをコピペしてみていただけですが。

Apache Cordovaはhtml5で作られたものをネイティブアプリとしてインストールする形にするもののようです。というかどうもCordovaはPhoneGapのようですね。

Cordova(PhoneGap) とりあえずどんなものか

サンプルをコピペで動かしてみましたが、ionicとhtmlとjavascriptだけでTodoアプリが出来上がりました。そしてちゃんとアプリとしてAndroidにインストールできました。ionicを使うとモバイルに特化したUIで、htmlでサクサク作ることができるのでちょっと可能性を感じ始めています。書いていて楽しいし。別にネイティブアプリにする必要はないかな?とは思いますが、本当にhtmlとAngularJSがあればいい感じのアプリが作れるので、敷居がさがった感じはします。まぁPhoneGapが騒がれていた頃に冷ややかに見ていた自分としては今更感動してるってのもどうか?とは思いますが…。

今回は@ore_publicさんと@kiyokuraさんと話してたことで、サーバなどで仕事上で使えそうな話もあったので、実りはあったなーと思います。コスト削減しないと…。

それにしてもionicのバージョンアップしたらなんか動作が変わった気がする…。今更気づいたんだけれど。ちょっと調査しなければ。


ionic frameworkでサイドメニューを使う

ionic frameworkでサイドメニューを使うサンプルは、本家のサイトにあります。

Side Menu Controller

普通に書くと、こんな感じです。

01
02
03
04
05
06
07
08
09
10
11
<side-menus>
  <pane side-menu-content>
    <p>メインコンテンツ</p>
  </pane>
  <side-menu side="left">
    <p>左側のメニュー</p>
  </side>
  <side-menu side="right">
    <p>右側のメニュー</p>
  </side>
</side-menus>

これで動くんですが、nav-barとnav-viewを使った場合はどうするのかがちょっとわかりにくかったので、自分なりに直したのを載せておきます。まずはテンプレート側。

index.html
1
2
3
4
5
6
7
8
<body ng-app="SelfieGirl">
  <nav-bar animation="nav-title-slide-ios7"
           type="bar-calm"
           back-button-type="button-icon"
           back-button-icon="ion-arrow-left-c">
  </nav-bar>
  <nav-view></nav-view>
</body>

AngularJSのコントローラーとしてCardCtrlをidで指定します。

cards.html
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<side-menus id="CardsCtrl">
  <!-- メインコンテンツ。drag-contentをfalseにすると画面のスライドで表示できなくなる。 -->
  <pane side-menu-content drag-content="false">
    <view title="title"
          left-buttons="leftButtons"
          right-buttons="rightButtons">
      <content has-header="true" padding="true">
        <p>ここがメイン領域</p>
      </content>
    </view>
  </pane>
  <!-- 左サイドメニュー -->
  <side-menu side="left">
    <header class="bar bar-header bar-assertive">
      <div class="title">メニュー</div>
    </header>
    <content has-header="true">
      <list>
        <a href="javascript:void(0)"
           class="item item-icon-lef"
           ng-click="logout()">
          <i class="icon ion-log-out"></i>
          ログアウト
        </a>
        <a href="javascript:void(0)"
           class="item item-icon-lef"
           ng-click="foo()">
          <i class="icon"></i>
          foo
        </a>
        <a href="javascript:void(0)"
           class="item item-icon-lef"
           ng-click="bar()">
          <i class="icon"></i>
          bar
        </a>
      </list>
    </content>
  </side-menu>
  <!-- 右サイドメニュー -->
  <side-menu side="right">
    <header class="bar bar-header bar-assertive">
      <div class="title">メニュー</div>
    </header>
    <content has-header="true">
      <list>
        <item class="item-icon-left">
          hoge
        </item>
        <item class="item-icon-left">
          piyo
        </item>
        <item class="item-icon-left">
          fuga
        </item>
      </list>
    </content>
  </side-menu>
</side-menus>

そして、このサイドバーを表示するための処理をJavaScriptで書きます。
$scope.sideMenuControllerが肝です。

cards_controller.js
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
angular.module('SelfieGirl.controllers', [])
  .controller('CardsCtrl', function($scope){
    $scope.title = 'SelfieGirl';
    $scope.leftButtons = [
      {
        type: 'button-clear',
        content: '<i class="icon ion-navicon"></i>',
        tap: function(e) {
          // ヘッダーの左ボタンを押したら左メニュー表示
          $scope.sideMenuController.toggleLeft();
        }
      }
    ];
    $scope.rightButtons = [
      {
        type: 'button-clear',
        content: '<i class="icon ion-navicon"></i>',
        tap: function(e) {
          // ヘッダーの右ボタンを押したら右メニュー表示
          $scope.sideMenuController.toggleRight();
        }
      }
    ];
    $scope.logout = function() {
      // ログアウト処理
    };
    $scope.foo = function(){};
    $scope.bar = function(){};
  });

コントローラーの処理がでかくなってしまうので、もっと細かくサイドバー単位で分割できるかもしれないですが、1画面として管理したいとしたら、上記のような感じになるのかなぁと思います。それにしてもサイドバーの実装がすごく楽ですね。ここはやはりhtml5というところでしょうか。ionic便利ですなぁ。