くらしのマーケット開発ブログ

「くらしのマーケット」を運営する、みんなのマーケット株式会社のテックブログ。積極採用中です。

Flutterモバイルフレームワークの紹介

はじめに

みんなのマーケットでテックチームに所属しています、楊です。

今回は、Googleが最近発表したFlutterモバイルフレームワークを紹介します。
簡単に言ったら、一応Google版のReact Nativeという理解でいいと思います。

最初にFlutterのドキュメントを褒めてあげたいです。順調にインストールできました。
普段だとGoogleのドキュメント通り1ステップずつ実施して、最後にうまくいかず、stackoverflowで答えを探すのが個人的な日常です。

普段のGoogleドキュメントを参照しながら、開発する私:

f:id:curama-tech:20180330140440g:plain

試す狙い

今回くらしのマーケットで新規開発する「出店登録〜審査」の機能に対して、Tech Stack を選びたい。
独立の機能なので、独立で開発して、後はlibraryの形で主Appにintegrateしたらいいんじゃないかと思う(主AppはLibraryの入り口しか知らない、High aggregation and low coupling)。

A機能を開発する際に、Module A を作って、該当 Module を独立で実行できるようにすれば、Application A で爆速 compile & run できる(UIテストも簡単になる)。
最後リリースする際に、Main Application で各 Module を組み立てて、packageする。

Appアーキテクチャ:

f:id:curama-tech:20180330140530p:plain

要件

  • CrossPlatformの開発能力
  • うちのサポートしているデバイスやOSバージョンに合わせる
  • 既存のNative Appに集約できる
  • Material Designに優しいFrameworkなら、更によい。

結論

React Nativeより完成度や便利性がもっと高いFrameworkで、私の理想のようだけど、まだ本番アプリには使えない段階だ

理由1 - サポートしているデバイスやOSバージョン:

  • まだ 32 bit の iOS デバイスに対応していない(iPhone 4 や iPhone 5など)
  • Android sdk 16以上のみに対応している (うちは 14 から)

理由2 - 大事なWebViewはまだ実装していない:

  • ひとつのアプリの中にたまにnativeで実装したくない機能があると思う

理由3 - JSX よりもっとやばい書き方:

  • 目が痛い
    @override
    Widget build(BuildContext context) {
        return new Scaffold(
           appBar: new AppBar(
               backgroundColor: Theme.of(context).canvasColor,
               elevation: 0.0
           ),
           body: new Column(
               crossAxisAlignment: CrossAxisAlignment.stretch,
               children: <Widget>[
                   // Give the key-pad 3/5 of the vertical space and the display 2/5.
                   new Expanded(
                       flex: 2,
                       child: new CalcDisplay(
                           content: _expression.toString()
                       )
                   ),
                   const Divider(height: 1.0),
                   new Expanded(
                       flex: 3,
                       child: new KeyPad(calcState: this)
                   )
               ]
           )
       );
   }

理由4 - Dart 言語少し不安定(まだ進化中):

  • 今使っている Dart 1 はまるで no-JVM java Lite な感じがする(同じように、null safety がない、why!!!)
  • Kotlinの勉強を始めたばかり! !!

すばらしさ

  1. SDK レベルの Redux
  2. No more controllers / views / layouts / viewGroup / xml / xib / activity / fragment / delegate / resource
  3. Only ウィジェット / State / Reducer ひとつの ウィジェット を一ページとしてもいいし、複数のウィジェットを組み立てもいいし、すごくアジャイルである。
    つまり開発過程はレゴ玩具のように作れる。No More MVC, MVVM, MVP, VIPER(一部分のNative開発者はすごく嫌かも)。Reducer はまったくUIと関係がないし、Pure Fuction なので、ユニットテストは書きやすい。

  4. SDK レベルの Router 画面遷移はさらに簡単になる。WebView(もしあれば^_^||)やプッシュ通知からも簡単に Native ページを起動できる(urlと同じフォーマット)

  5. 既存のNative Appに集約できる

  6. ひとつのページに半分 Native 半分 Flutter も簡単に実現できて、お互いに通信できる(MessageChannelを通して)

  7. 豊富な UI フレームワーク 標準のUIフレームワークに Android の Material Design ウィジェット と iOS の Cupertino Style ウィジェットを両方提供している。 これで Android に Cupertino 風アプリ、 iOS に MD 風アプリを簡単に作れる。

Material Design:

f:id:curama-tech:20180330140628p:plain

Cupertino:

f:id:curama-tech:20180330140642p:plain

  1. iOS UIKit や Android View Package に依存していない React Native は JS を iOS と Android それぞれの Component に変換していく。
    これで大きな問題ふたつがある:システムの Component が修正したり、バグあったりのとき、React Native は待つことしかできない;また、両方統一していない Component は if else の分岐でわけて開発しないといけない。
    Flutterの方は全部の ウィジェット をゼロから実装したので(Skia の力)、Platform や OS とかかわらず、統一している。問題が発生しても、Google 側ですぐに解決ができる。
    もし React Native は Learn Once, Write Everywhere なら、 Flutter は Write Once, Deploy Everywhere だなぁ。

現実世界のReact Native(表から考えると小さな開発だけど、着手したら大きな罠が待っている):

f:id:curama-tech:20180330140657g:plain

  1. 仮想 DOM React Native と同じように、仮想 DOM を実装した。
    これによって State から行われる画面の更新が結構早くなるし、Hot Loading 機能も合わさってさらに開発の効率が上がる。

  2. 便利な auto layout iOS の Constraint Layout と Android の Layout 両方サポートしている(React Native は flexbox のみ)。

  3. Dart 言語に非同期処理がサポートされている Dart 1 には Future を使っていて、 Dart 2 には async await も追加していきました。
    (はい、Swiftさん、君のことに不満がある)

非同期処理:

f:id:curama-tech:20180330140858g:plain

最後の一言

実際数年前、同じような技術はすでに存在している。 Adobe の AIR っていうことだ。

みんなのマーケットでは、一緒に働いてみたいといった方をお待ちしてます。

次回は、Webエンジニアの記事です。