UnderOSを使ってみる

  • 7
    Like
  • 0
    Comment
More than 1 year has passed since last update.

RubyMotion歴約一年でそのうち半年くらいProMotionを使ってアプリを作っているのですが未だ完成しません(開発中のRapidNews)。

ProMotionについて書こうと思ったのですがネタが思い浮かばなかったので最近本元のTwitterでささやかれたフレームワーク「UnderOS」を紹介します。

実際の例

まずはこうした計算機の画面。

th_under_os2.jpg

この画面をUnderOSで構成するのに必要なのは

calculator.html
<!-- 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なこれと

calculator.css
/* 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ファイル。セミコロンまで使っていて芸が細かいですね。後発だけに継承の書き方も洗練されてます。そして

calculator_page.rb
#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が見慣れませんが中身は

config.rb
UnderOs::App.start do
  config.navbar    = true
  config.root_page = HomePage.new
end

のような感じでapp_delegateを隠匿しています。

さらに

UnderOSが狙いとしているところはおよそ理解できたとして、ではページを構成するのに常にHTML,CSS,Rubyの3点セットが必要なのかというとそうではなく、

stuff_page.rb
#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