Close icon
2019月08日07日

NikoNikoLog 開発の記録 (3) - TAppKit が生まれ、その開発がはじまった

またまた前回に続き、NikoNikoLog のモバイルウェブ版の開発の話、しかもまた前回から引きずっているフロントエンド用フレームワーク開発の話です。

完全に開発者向けの記事が続いてしまって申し訳ありませんが、もうちょっとだけお付き合いください。

TAppKit(仮)の誕生

atotok ブランドの製品である NikoNikoLog10Years 、これらの製品群に我々の意図した通りの一貫したユーザー体験を与えるためには、フロントエンド用フレームワークの開発がチームに課せられた急務でした。

開発は最初から綿密に設計して行う選択肢もありましたが、まずは先に作った NikoNikoLog のモックをフレームワークベースの実装に置き換えるところからはじめました。なのでフレームワーク自体は完全に新規開発とはいえど、その一方で NikoNikoLog の次期大規模アップデート開発の成果物でもあります。

ちなみにフレームワーク化するにあたって、どうしても名前が必要になります。とりあえず軽い気持ちで TAppKit と名付けておきました。TAppKit の T は atotok、10Years、NikoNikoLog と言った製品が社内で Tule Project と呼ばれていることに由来します。

JavaScript で作るか、CoffeeScript で作るか

TAppKit と名前まで仮ながら決めたものの、そのフレームワーク開発は ES6(ES2015)で行うのか、CoffeeScript で行うのかは結構悩みました。ちなみに TypeScript は完全に最初から対象外だったのはうちの社風から察してください。

結局、制御系の構文をスマートに書きやすいなどの理由で CoffeeScript を採用することにしました。letconst などの ES6 の機能は使いたいと思いつつも、今回のフレームワークは各機能が細かくコンポーネント化、クラス化されていたりするので不用意な変数による侵食は起きづらいであろうとの判断もありました。それでも実はそれを決定に持っていくまでの間、水面下では CoffeeScript と JavaScript の両方で同じ実装を進めていた・・・のもまた懐かしい話です。

今後、状況次第では CoffeeScript で書いているコアなコードを JavaScript にリプレイスする可能性も・・・もしかしたらあるかもしれません。

TAppKit(仮)の設計思想、強みと弱点

TAppKit はその設計思想や使い勝手において、Ruby on RailsApple の提供する AppKit の影響を大きく受けています。データの取り扱いに関する部分は Rails、UI に関する部分は AppKit の影響を受けていることが顕著です。

例えば TAppUILabel では表示テキストを以下のコードで書き換えられますし、TAppUIImageView なら以下のコードで表示画像を変更できます。

allocUIComponents: ->
  self = @
  # DOM を TAppUILabel として登録
  self.view.addSubView(
   name: 'userLabel'
   view: self.app.uiKit.uiLabel.new('.selector-to-label')
  )
  # DOM を TAppUIImageView として登録
  self.view.addSubView(
   name: 'userImage'
   view: self.app.uiKit.uiImageView.new('.selector-to-image')
  )
  super()

someMethod: ->
  self = @
  # userLabel は TAppUILabel のインスタンス
  self.userLabel.setTitle('foobar')
  # userImage は TAppUIImageView のインスタンス
  self.userImage.setImage(PATH_TO_URL)

また、データベースから単一のレコードは以下のように取得することができます。

someMethod: ->
  self = @
  # self.app.data はアプリケーションのデータモデルへのアクセサで .someDatas はモデル
  data = self.app.data.someDatas.find(1)
  # 単一のデータレコードの操作
  data.name = 'sample'
  # 単一のデータレコードのサーバーへの保存
  data.save()
  .fail ->
   # 失敗時のコールバック、続きの処理を記述
   return
  .done ( data ) ->
   # 成功時のコールバック、続きの処理を記述
   return
  # 単一のデータレコードの削除
  data.destroy()

新しいデータレコードの作成なんかは以下の感じです。

someMethod: ->
  self = @
  data = self.app.data.someDatas.new()
  data.name = 'myname'
  data.save()
  # 上の new 〜 save() は以下のようにも記述できる
  self.app.data.someDatas.create( name: 'myname' )

TAppKit の強みは以下の通りです。

  • API とフロントエンド側のデータの扱いが容易
  • スマートフォン用ブラウザ向けの UI/UX の実装コストを大幅な削減可能
    • コード上は意識しなくても、設定だけ適切に与えるだけで各UIコンポーネントの挙動をネイティブアプリにかなり近い状態で再現できる
  • プロトタイピングの感覚で一気に画面が開発できる
    • 実際、TAppKit を使って 10Years も大規模なアップデートのための開発を行っているが、画面実装はサクサク進んだ

逆に TAppKit の大きな弱点は、完全に新規開発のフレームワークなので、機能が足りない部分は随時追加開発が必要なことです。通常の完成されたフレームワークならリファレンスに載っているような細かな配慮のための機能も、必要になった時にそれにに応じて実装しないといけません。また、リファレンスも同時に作成する必要があるもの多少とは言え手間でもあります。

その他、実開発を行っていて時々頭を悩ますのは、不足している機能を実装する際に、その機能は TAppKit 側にあるべきなのか、それともアプリケーション側にあるべきなのかの判断だったりします。

次回・・・

次回からは遂に開発中の画面のスクリーンショットを少しずつ公開してみようかなと思っています。スクリーンショットと共に、それらの機能のこと、その開発の裏話や経緯などもお伝えできたらな、とも考えています。

関連記事

アトトックラボとは

株式会社アトトック のメンバーが技術の話、デザインの話、キャラクターの話、ときどき脱線してガジェットの話やライフハックの話など好きなことを書いています。


最近の記事


タグ