RubyMotion歴約一年でそのうち半年くらいProMotionを使ってアプリを作っているのですが未だ完成しません(開発中のRapidNews)。
ProMotionについて書こうと思ったのですがネタが思い浮かばなかったので最近本元のTwitterでささやかれたフレームワーク「UnderOS」を紹介します。
##実際の例
まずはこうした計算機の画面。
この画面をUnderOSで構成するのに必要なのは
<!-- app/layouts/calculator.html -->
<page title="Calculator">
<label id="result">0</label>
<button class="row5 col1 top">C</button>
<button class="row5 col2 top">±</button>
<button class="row5 col3 top">%</button>
<button class="row5 col4 ops">÷</button>
<button class="row4 col4 ops">×</button>
<button class="row3 col4 ops">-</button>
<button class="row2 col4 ops">+</button>
<button class="row1 col4 ops">=</button>
<button class="row4 col3">9</button>
<button class="row4 col2">8</button>
<button class="row4 col1">7</button>
<button class="row3 col3">6</button>
<button class="row3 col2">5</button>
<button class="row3 col1">4</button>
<button class="row2 col3">3</button>
<button class="row2 col2">2</button>
<button class="row2 col1">1</button>
<button class="row1 col1 double">0</button>
<button class="row1 col3">.</button>
</page>
ファイル拡張子もずばり.htmlなこれと
/* app/styles/calculatro.css */
page {
background-color: darkgray;
}
label {
left: 0;
top: 80;
color: white;
height: 80;
width: 320;
font-size: 80;
text-align: right;
}
button {
width: 79px;
height: 79px;
color: black;
background: white;
border-radius: 0px;
font-size: 40;
}
button.double { width: 159; }
button.ops { background: yellow; font-size: 20; }
button.top { background: lightgray; font-size: 20; }
.row1 { bottom: 0px; }
.row2 { bottom: 80px; }
.row3 { bottom: 160px; }
.row4 { bottom: 240px; }
.row5 { bottom: 320px; }
.col1 { left: 0; }
.col2 { left: 80; }
.col3 { left: 160; }
.col4 { left: 240; }
これまたストレートに.cssファイル。セミコロンまで使っていて芸が細かいですね。後発だけに継承の書き方も洗練されてます。そして
#app/pages/calucurator_page.rb
class CalculatorPage < UnderOs::Page
def initialize
@label = first('#result')
find('button').each do |b|
b.on(:tap){|e| handle_tap(e)}
end
end
def handle_tap(event)
case event.target.text
when '0','1','2','3','4','5','6','7','8','9','.'
@label.text = '' if ['0', @first_value].include?(@label.text)
@label.text += event.target.text if @label.text.size < 18
#略
end
def calculate
return if ! @first_value
values = [@first_value, @label.text]
values = values.any?{|v| v.include?('.')} ? values.map(&:to_f) : values.map(&:to_i)
@label.text = values[0].send(@operator, values[1]).to_s
end
end
Rubyです。Objective-Cっぽさは微塵も感じられません、。さらにfind(‘button’)
でボタンを一括して指定できたりb.on(:tap)
でイベントを拾うなどJQuery的な書き方が意識されていてRuy未経験者でも十分親しみやすいと思います。
##使い方
前後しますが使い方はまず
gem install under-os
テンプレートが用意されているので
mkdir -p ~/Library/RubyMotion/template/uos
git clone https://github.com/under-os/under-os-template.git ~/Library/RubyMotion/template/uos
そうするとappフォルダには
`-- app
|-- layouts
| `-- home.html
|-- models
|-- pages
| `-- home_page.rb
|-- styles
| `-- application.css
|-- views
`-- config.rb
これらのファイルが作成されます。
layoutsにHTML、pagesにRubyファイル、stylesにCSSを配置、その他にmodelsやviewsというフォルダが用意されています。
config.rbが見慣れませんが中身は
UnderOs::App.start do
config.navbar = true
config.root_page = HomePage.new
end
のような感じでapp_delegateを隠匿しています。
##さらに
UnderOSが狙いとしているところはおよそ理解できたとして、ではページを構成するのに常にHTML,CSS,Rubyの3点セットが必要なのかというとそうではなく、
#app/pages/stuff_page.rb
class StuffPage < UnderOs::Page
def initialize
self.title = "Various Stuff"
@box = View.new(style: {
top: 50,
left: 50,
width: 100,
height: 100,
background: :red,
borderRadius: 10,
borderWidth: 2,
borderColor: :green
})
@b2 = View.new(style: {background: :blue})
insert @box.insert(@b2)
insert Icon.new(:cog).position(x: 50, y: 300)
end
end
といようにコードだけで完結させることもできます。
insert Icon.new(:cog).position(x: 50, y: 300)
でviewを追加、入れ子にする場合は
insert @box.insert(@b2)
と書きます。もちろんコードだけでなくInterface Builderで作ったviewを読み込むこともできるようです。
##試してみての感想
ネイティブアプリのコードをHTMLやCSS風に書くことを目指したフレームワークはRubyMotionに限らずこれまでにもいろいろ作られてきたかと思いますが、その中でも結構、感動的な再現度ではないでしょうか。
一方で華麗なマジックがほど裏側ではえげつないことしているのでは?と疑いを持つことかと思いますが、作者はUnderOSは’thin web-like wrapper’だと主張しています。
実際に今の段階では小一時間もあればコード全体を目を通すことができますし、メタプログラミングなどが駆使されて読みづらいというようなこともありませんでした。
とはいっても既に書き慣れているユーザーだとあえて手を出す必要性は感じにくいかもしれません。ただ使う使わないは別にしてもRubyMotionの裾野を広げる可能性のある注目すべきプロジェクトかと思います。
公式サイト
http://under-os.com