iOSエンジニアから見たFlutter

こんにちは。ナビタイムジャパン iOSアプリ開発者のKen と YoY です。
この記事は、Flutterを業務で触ってみて感じたことをiOSアプリ開発者目線で記事にしてみました。
2日目の [「Flutterをプロダクション導入しました。」](https://qiita.com/navitime_tech/items/21a6111b36b98cac3100) も公開していますが、また別目線で気づいたことを書けるように留意しました。何かの参考になれば幸いです。

# 1. はじめに
この記事は、iOSアプリ開発者がFlutterを触ってみて感じたメリットやリスク、適しているプロダクトを発信し、Flutter採用検討時の参考になればと思いまとめてみました。

今回記事を書いてみようと思った経緯は下記の通りになります。

- 最近Flutterが流行ってきており、NAVITIME内でもFlutterの採用が検討されるようになってきた。
- 最近Flutterを触ることがあり、その中でiOSアプリ開発者として感じたメリットやリスクがあった。
- 考えを発信することで、何か助けになれば or ご意見をいただき、議論ができればと思った。

# 2. イメージする対象者の方
本記事の対象者は下記のような方をイメージしています

- Flutterに興味がある、または導入を検討している
- 普段iOSアプリの開発を行っている

# 3.目次
- iOSアプリ開発者から見たメリット
- 導入するにあたってのリスク
- 適しているプロダクト
- おわりに

# 4. iOSアプリ開発者から見たメリット
## 4.1. Hot reload
[Hot reload](https://flutter.dev/docs/development/tools/hot-reload) とは、再ビルドすることなくソースコードに加えた修正を反映する機能で、素早く簡単にUIの確認や機能修正、バグ修正の確認ができます。

シミュレータでも実機ビルドした場合でもHot reloadは有効です。
最近SwiftUIでプレビューが追加されましたが、Flutterでは実機でも有効 + マルチプラットフォームなため、この点ではFlutterが優位だと言えそうです。

ただし、Hot reloadしたあとにアプリキルするとHot reload前の状態に戻ったり、再ビルドしないといけない状態に陥ることはよくあります。（ここは深い話なので省略します）

とはいえ、ビルドせずにレイアウトが確認でき素早い開発が可能な点は魅力的です。

## 4.2. UI実装の簡単さ
FlutterではWidgetを組み合わせてUIを組み立てていきますが、種類が豊富なので、思ったよりもLayoutの自由度が高いです。
Hot reload、Widgetの豊富さ、言語仕様などが相まって、プロトタイプを作成するのにかかる時間は圧倒的に早いと感じました。

Flutterには親切かつ豊富なチュートリアルが用意されています。
宣言的なUIの実装や、Dart標準のStreamを利用したReactiveプログラミングの書き方など、
SwiftUIの実装方法に似ている部分があると感じます。
そのため、Flutterで触ることができるのは、SwiftUIのキャッチアップにも役立ちそうです。

また、これは個人差はあると思いますが、Interface Builderを使わずに実装できるのは、
様々な面倒ごとを考慮することがないため、かなり楽でした。
(レイアウトのコピーのしやすさ、コンフリクトの解決のしやすさ等)


例えば、下記のようなレイアウトを書こうとすると以下のようになります。
やってみた感触では、UITableViewよりも遥かに簡単に表示することができました。

![startup_namer_top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/0b7b08ba-43b4-27bd-8678-48d1518952b8.png)


```dart
  final _labels = ["apple", "apple brandy", "aoole butter", "apple corer"];

  Widget _buildSuggestions() {
    return ListView.separated(
        separatorBuilder: (context, index) => Divider(),
        itemCount: _labels.length,
        padding: const EdgeInsets.all(16.0),
        itemBuilder: (context, i) {
          return _buildRow(_labels[i]);
        });
  }

  Widget _buildRow(String label) {
    return ListTile(
      title: Text(
        label,
        style: _biggerFont,
      ),
      trailing: Icon(
        Icons.favorite_border,
      ),
    );
  }
```

上記のコードはFlutterのチュートリアルを参考に一部を書き換えたものです。
- [Codelab - Write Your First Flutter App, part 1](https://codelabs.developers.google.com/codelabs/first-flutter-app-pt1/#0)
- [Codelab - Write Your First Flutter App, part 2](https://codelabs.developers.google.com/codelabs/first-flutter-app-pt2/#0)


## 4.3. ライブラリの導入が簡単
Flutterでのライブラリ導入は、pubspec.yamlファイルに導入したいライブラリ名とバージョンを記入し、
Android Studioでget packageを押すだけという非常に簡単なプロセスです。
そのため、CocoaPodsやCarthageでビルドエラーが起きたり煩雑な手順を踏んで悩まされることは起きにくそうです。

## 4.4. リファレンスの充実性
公式のリファレンス、チュートリアル、動画に加え、QiitaやMediumなどの記事も多く見つけることができます。
Flutterは正式リリースからまだ1年程度なので、検索して見つかる情報が新しく、参考になる情報が見つけやすいと感じます。
参考にしている情報源をいくつか挙げてみます。

- [Widget of the Week](https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw)
- [Flutter CookBook](https://flutter.dev/docs/cookbook)
- [Flutter Codelabs](https://codelabs.developers.google.com/?cat=Flutter)

## 4.5. Android Studioが使いやすい
Flutter自体の良さとはズレますが、エディタについても思うところが多々ありました。
[Android Studio](https://developer.android.com/studio/intro?hl=ja) は、IntelliJ IDEAをベースとしたAndroidアプリ開発用の公式の統合開発環境（IDE）です。
Xcodeを普段触っているので、IntelliJのIDEとしての質の高さに驚きました。
特に驚いたのは「補完機能の充実」と「軽量」な点です。

### 補完機能の充実
今回はAndroidアプリ開発者の方と一緒にモブプロをしながら開発を行っているのですが、
その方が日常的に行っていることが、Xcodeにはないので驚きました。

- コンストラクタ生成、import文の自動追加、レイアウト時のWidgetの変換、削除、Wrapなどの警告や最適化の提案 (もちろんXcodeにも同様の機能はありますが)
- コードフォーマット自動実行 (Cmd + Option + L)
- 最近使ったファイルの一覧表示（Cmd + E）
- サイドバーのツリー位置の移動（Xcodeでいう Cmd + Shift + J）がファイルを開いたときに自動で行われる

### 軽量
ナビタイムジャパンでは最新OSへの対応調査や、古いAppの不具合調査等の事情があり、Xcodeは複数バージョンを残しておく必要がよくあります (ちなみに Xcodeは10GB超えです)。
その点Android Studioはとにかくサイズが軽く、約1.4GBです。さらに、複数バージョン残しておく必要がほとんどないそうです。
(プレビュー版を入れても2~3バイナリくらいだそうです。)

Flutterの開発環境にはもう一つVSCodeがありますが、こちらはさらに軽量です。

ただし、FlutterでiOS開発を行うためにはXcodeは必須ですので、結局ある程度の容量は必要となります。

## 4.6. その他
iOSでは実機ビルドをするには証明書の準備などの障壁がありますが、iOSアプリ開発者でその辺の環境整備が終わっていればすぐにFlutter開発に入ることができます。
ちなみに、Androidでの実機ビルドは端末をつなげるだけです！


# 5. 導入するにあたってのリスク
Flutterについて、現段階でリスクに感じている点は3点あります。

## 5.1. MaterialDesignを採用

これは審査時のRejectリスクを懸念しています。Appleの審査基準は常に何かあれば変わっており、もしかしたら、今後UIはUIKitに準拠すべきなどの理由から、Flutterで開発したアプリがRejectになる可能性は少なからずあるとは思っております。
また、Flutter自体がApple製ではない独自のSDKのため、外部SDK利用のRejectリスクもないとは言えません。
とはいえ、FlutterはUIKitのような見た目はCupertino UIも提供されておりますし、SDKも対応しなければならない場合はFlutter側でも対応してくれると期待もしております。

## 5.2. PlatformViewの不具合/予期しない動作をする

Flutterが提供する機能に、OSのネイティブUIを表示する PlatformViewというものがあり、iOS用に[UIKitView](https://api.flutter.dev/flutter/widgets/UiKitView-class.html)、Android用に[AndroidView](https://api.flutter.dev/flutter/widgets/AndroidView-class.html) が用意されています。


UIKitViewについてはまだrelease previewのため、現状では少々動作が不安定な場合があります。
例えば、UIScrollViewをPlatformViewで表示し、上に別のWidgetを重ねて表示 ([Stack](https://api.flutter.dev/flutter/widgets/Stack-class.html)) した時、タッチイベントが下にあるUIScrollViewに伝わり、ずっとタップされた状態が残る、といったようなことがありました。


## 5.3. Xcode、iOSの更新に伴う変更への追従

これはApple以外のライブラリを利用しているかぎり付き纏う問題かと思いますが、
やはり新iOS、Xcodeが出たときに、どこまで対応が早く行われるのか気になるところかと思います。
ただ、Googleは長年スマートフォンのプラットフォームを開発してきたことで問題に対する意識が違うと思っておりますし、それに問題への対応速度は早いと思っています。

ただ、リスクとして挙げてはいるものの、もしかしたらそこまで気にする必要もないのかもしれません。

# 6. 適しているプロダクト
上記までの内容を踏まえまして、Flutterに適していると思うプロダクトは下記になります。

- 新iOSへの即日対応が必須ではない (不具合対応は別)
- iOSのネイティブ層の利用が少ない
- 新規開発

例えば、案件にもよりますが新iOS対応を即日求められる場合や、新iOSの機能を使いたいときでも、Flutter自身が追いついていないといったことも起こり得ると思います。
そうなった場合、自分でFlutter自身を修正する、といったようなことにもなりかねないと思っています。

また、既存アプリへの適用も規模にはよりますが、難しいと考えております。
弊社には運用年数が5年を超えるようなアプリも少なくありませんが、その場合ソースコードが膨大な量になっており、一気に置き換えは大きな判断を伴います。
一部適用といったこともできなくはないですが、Objective-CのコードにSwiftをつなぎこむのが辛いのと同様に、
別言語同士を繋ぐのにもテクニックを要し、動作上、既存コードとの整合性など考慮すべきが多々出てきます。
その場合、そこまでしてFlutterを取り込む必要があるかといえば、疑問が残ります。

上記に挙げたようなプロダクトであれば、マルチプラットフォームのメリットを受けながら、
スピード感のあるアプリの提供が実現できるのではないかと思っております。

# 7.おわりに
iOSアプリ開発者にも魅力的な点が多いFlutterですが、
1.0がリリースされてから1年ほどというところもあり、リスクに感じる点もいくつかあるのが正直なところです。。

ただそれでも、スピードも案件によっては上がるなど、メリットはかなり多くあり、
実際にFlutterの勉強会に参加してみても、かなり注目されていることは肌で感じることができております。
これから新規アプリの設計検討等を行っていく際には、採用候補として検討してみるのも良いのではないかと感じております。
少しでもFlutterに魅力を感じる方が増え、Flutter界隈がより賑やかになることを楽しみにしております。