IT業界で気づいたことをこっそり書くブログ

くすぶってるアプリエンジニアが、日々気づいたことを適当に綴っていきます(受託→ベンチャー→フリー→大企業→ベンチャー→起業)

iOSエンジニアはMVVM・RxSwiftをやるべき?キャリアパスから解説する

タイトルは釣りです。

 

本当に書きたいのは

エンジニアはスキルの陳腐化やコモディティ化とどう戦っていくべきか

です。
クソ面倒くさい話を書きます。
死ぬほど長いです。

 

 

モチベーション

最近16人のiOSエンジニア志望者と1時間程度の面談を行ったのですが、多くの人が似たようなことを言っていました。

 

アプリ開発について勉強していて、アプリも出してみたが、次に何をすべきかわからない。とりあえず求人情報を見たらMVVMとRxSwiftが書かれていたのでアーキテクチャについて勉強しようと思う。

 

それでMVVMってどうなの?というあたりを15分くらいで早口で説明するのですが、ちょっと口頭で話すには複雑すぎると思いました。
あと自分でも色々考えをまとめたかったので書きます。

 

免責事項

正直ここらへんの話語りたくないんですよね。
知識不足が露呈しそうで。
iOSアプリ開発は30案件くらいやってますが未だに自信がない。
話半分くらいでお願いします。
違う意見があったらください。

 

MVVMとは?

ja.wikipedia.org

 

ここ3年くらいのiOS界隈ではMVCの上位版みたいな語られ方をしますね。

 

MVC, MVVMはどこから来たのか?

きちんとどこから来たのか調べ始めると私の休日(※休んでない)が溶けるので辞めますが、乱暴な言い方になりますが、今のアプリ界隈におけるMVCってそもそもWeb開発から来てませんか? Webのフレームワークって明確にMVCが別れていますよね。アプリにおけるMVCと全然印象が違います。

 

たぶん合ってると思うんだよなあ。
2010年頃のWeb開発では既にMVCは常識中の常識でした。

f:id:otihateten3510:20210912173234p:plain

 

対してMVVMは明らかにWindowsから来ています。

 

f:id:otihateten3510:20210912173513p:plain

f:id:otihateten3510:20210912173609p:plain

 

WikipediaのMVVMについての説明を読んでみましょう。

根拠
MVVMは、WPF(Windows Presentation Foundation)のデータバインディング機能を利用して、ビュー層からほぼすべてのGUIコード(コードビハインド)を取り除き、ビュー層の開発を他のパターンから分離することを目的として設計されています[3]。このように役割を分けることで、インタラクティブデザイナーはビジネスロジックのプログラミングではなく、UXのニーズに集中することができます。このように、アプリケーションのレイヤーを複数のワークストリームで開発することで、生産性を高めることができます。一人の開発者がコードベース全体を担当する場合でも、エンドユーザーからのフィードバックに基づいてユーザーインターフェースが開発サイクルの後半で頻繁に変更されることが多いため、ビューとモデルを適切に分離した方が生産性が高くなります[要出典]。

MVVMパターンは、MVCによって提供される機能的な開発の分離という利点と、純粋なアプリケーションモデルにできるだけ近いところでデータをバインドすることによるデータバインディングフレームワークの利点の両方を得ようとするものです[3][4][11][clarification needed] バインダー、ビューモデル、およびあらゆるビジネス層のデータチェック機能を使用して、入力データを検証します。その結果、モデルとフレームワークができるだけ多くの操作を行い、ビューを直接操作するアプリケーションロジック(例:コードビハインド)を排除または最小限に抑えることができます。

www.DeepL.com/Translator(無料版)で翻訳しました。

 

ちなみに推奨されてるだけで、WPFをMVVM無しにでも作れるみたいです。

Web界隈では、大体2016年頃から流行ったのではないでしょうか?(合ってる?)Vue.jsが流行り始めた当たりからです。Qiitaでひっきりなしにそういった話題が出ていたのを覚えています。

f:id:otihateten3510:20210912174958p:plain

 

やや遅れて、RxSwiftが流行ります。RxSwiftはSwiftでMVVMをするならできれば入れておきたいLibraryです。だいたいSwiftが出た次の年くらいですかね? 2016年にSwift2.3で結構安定しまして、そこらへんからRxSwiftが盛り上がってきます。(ちなみにSwift4.0で仕様がかなり変わって大変でした)

 

f:id:otihateten3510:20210912175108p:plain

 

まあつまりちょいちょい流行っていて、アプリ界隈はWindowsやWebからやや遅れて、言語がモダンになったのにあわせて(Swift,Kotlin)2016年くらいから行り始めたという感じです。

 

RxSwiftとは何なのか?

ReactiveXというパラダイム・思想です。

 

reactivex.io

 

f:id:otihateten3510:20210912180215p:plain

 

ざっくり言えばオブザーバーパターンを実現するためのLibraryです。
あと関数型言語っぽく書けます。
上のページには他に、コードの行数を減らせるとか、非同期エラー処理に強いとか、並行処理が容易と書いています。

 

ここで脳が破壊されるのが、Rxを評価するということはすなわちオブザーバーパターンや関数型言語の評価をすることと同義であり、それは非常に厄介です。永遠のテーマに近いのではないでしょうか。大多数のエンジニアには荷が重いはずです。

 

そんな中、なぜRxSwiftが流行ったのかと言えば、上の特徴とは無関係に、データバインディングができて、MVVMが実現できるからに他ならないでしょう。

 

MVVMがやりたい → RxSwiftを導入する → 関数型言語・オブザーバーパターンについての勉強が必要

 

この流れができています。

まあここらへんも私の妄想でしかない可能性があるんですが、とりあえずはデータバインディングとMVVMが標準装備されているAndroidの方では、RxKotlinがさおど流行ってないんですよね。


Githubでも
RxSwift ★20.9K
RxKotlin ★6.7k

とこんな具合です。
RxJavaは強いんですけど(★45.3k)

 

関数型言語・オブザーバーパターンはなんか良いやつなの?

両者大昔からあって、現代のメインストリームのパラダイムになれなかったやつらです。
良い悪いっていうより、完全に向き不向きだと思うんですよね。作るプロダクトに対して選択するのが良いと思ってます。
ちなみに私はLISP恐怖症なので良いイメージ無いです。

 

ja.wikipedia.org

ja.wikipedia.org

 

なぜMVVMをやりたいのか、真のメリットは?

  1. 分業ができる
  2. 変更容易性により、生産性を高められる(要出典)
  3. FatViewController, FatModelを回避したい(可読性)
  4. 疎結合になり再利用性が高まる
  5. 自動テストが可能になる

あー、なんだか色々否定するのが難しくなってきました。そして自信もない。

まず1の分業はしていません。Webではフロント/バックエンドで上手くやってるのかもしれませんが、アプリでは明らかにできていません。
2,3,4について言えば作ってみればわかりますがメリットどころかコードが膨大になって複雑性が増すので却って有害な場合が多いです。これはあまり反論がないのではないかと思うんですがどうなんでしょう?それで最後に残るメリットが「テスト可能性」なんですよ。というのが私の主張です。

※ここのロジックが一番ふわふわしていますが、説明できる自信がないです。結果的にそうなっているとしか言えず、何故そうなるかとか、ちゃんとした人がコードを書けば大丈夫だとか、色々言われそうです。

 

iOSアプリ開発で自動テストは必要なのか?

上記のロジックから考えると今度俎上に上がるのはこの議題なんですが、これも非常に語りづらいです。
私はiOSアプリにおいて自動テストの優位性はかなり低いと思います。全部不要というわけではありませんが、少なくともテストコードを書くためにアーキテクチャーを大幅に変える必要はないと思っています。

 

自動テストを書く理由ってここらへんですよね。

  • フロントからアクセスしづらい機能だから
  • 大量にテストをまわしたいから
  • 継続的なデプロイを高頻度で行うから
  • 手動テスト工数をそれほど積めないから
  • 実行環境が多岐に及ぶから
  • 実行環境を用意できないから
  • 再現が難しいから
  • 変更が外的要因だから、いつでも検知できるようにするため
  • クリティカルなサービスであるため(人名やお金)
  • より完璧な品質のため
  • TDD的な思想、リファクタリングする時に必要だから
  • 仕様把握のため

このうちiOSアプリにおいて該当するのは本当に僅かです。WebやAndroidに比べても必要なシーンは少ないし、ピンポイントでそこだけ対応するのが妥当だと思っています。
以下のフローは多くのプロジェクトで起きていると思いますが、考えてみると高い学習コストを払ってまでこの選択をすべきなのか疑問です。

 

自動テストを書かなきゃいけないから → MVVMがやりたい → RxSwiftを導入する → 関数型言語・オブザーバーパターンについての勉強が必要

 

これはMVPやVIPERなどのアーキテクチャでも同様です。
(ReSwiftは別の文脈ですが)

 

iOS MVVMは一過性の流行なのか?

アーキテクチャのトレンドは毎年のように変わります。

MVCがクソと言われ、Apple提唱の方法から離脱し、MVPが流行り、MVVMが流行り、CleanArchitectureが流行り、VIPERが流行り(?)
かと思えばCocoaMVCって良いよね、と回帰してる人も現れたりして、みんな思い思いに自由に勝手なこと言っててすごいです。ついていけません。

 

じゃあMVVMが一過性なのかと言えばNOです。
ここからは非技術的な話が入ってきます。

 

1.MVVM+RxSwiftで慣れた人は、MVVM+RxSwiftが書きやすい

当たり前なんですが、その書き方に慣れた人はその書き方が一番書きやすいんです。RxSwiftの熟練者だけのチームがあれば、当然次のプロジェクトでもRxSwiftを採用するでしょう。CocoaMVCはおそらく書きづらいと思うはずです。

そして、会社を挙げてRxSwiftを使っている有名な会社がいくつかあります。代表例はDeNAクックパッドドワンゴです。サイバーエージェントは確かAbemaTVあたりがRxだったはずです。

他にはベンチャー企業がRxSwiftをよく採用しています。新しいもの好きですね。

 

2.RxSwiftが向いているプロジェクト、MVVMが向いているプロジェクトがある

たとえばライブ配信アプリのように、沢山の要素(view)が同時に動くようなアプリではRxSwiftが向いているらしいです。これはオブザーバーパターンが向いているからです。

そして大規模なアプリでは自動テストの必要性が上がってくるため、当然MVVMを採用したくなります。結果的にMVVMやRxSwiftが消えることは直近1,2年ではありません。

 

MVVMは無くならない

わかるでしょうか?この2つの理由はお互いにコラボレーションします。一定の割合でこれは残っていくはずです。

 

副次的に起こるRxSwift+MVVMの必要性、そして避けられないコモディティ化

大企業が作ってるような大規模な案件や、ライブ配信のような新規性のある案件、目立ってるベンチャー企業がRxSwift+MVVMを採用すると、当然皆が真似します。実際に2018年、2019年はそこそこ流行った認識です。

しかし当然、向いていないプロジェクトでも採用されました。

logmi.jp

 

また、AppleがRxSwiftと似たような仕組みであるCombineというのを発表しました。これがiOS13からなので、採用し始めるプロジェクトが出るのがおそらくそろそろ出始めると思います。本格的に採用するのは、おそらくSwiftUIが本格化する来年下旬か再来年だと想います。

developer.apple.com

 

また、SwiftUIではデータバインディングができるらしいので、RxSwiftを使わずともMVVMが実現できるようになります。

 

これらをまとめると、RxSwiftの優位性はかなり落ちるでしょうし、MVVMを続けようとするプロジェクトもどれほど残るかやや疑問ではあります。

f:id:otihateten3510:20210912193101p:plain

 

じゃあMVVMやRxSwiftを勉強しなくていいのか?

これが難しいところで、例えばiOSエンジニア志願者なら答えはNOになってしまうと思います。
まず上で書いたように、RxSwift+MVVMを得意とするチームが少なからず存在すること、またそれに向いたプロジェクトが存在していることが理由の一つ。
そして、たとえそうではなくとも、一度書いたRxSwift+MVVMのコードは5年、10年と保守していかなければならないわけで、そうなると募集要項に「RxSwift+MVVM」が入ってくるわけです。

これはSwiftが流行り始めた頃のObjective-Cや、今後SwiftUIが流行った時におけるStoryboardと同じ立場です。つまりレガシーコードになっていくんですが、その需要は確実に存在するため対応が必要です。

 

クソみたいなレガシーコード・チキンレース

エンジニアは常に自分がレガシーコードしか触れない人材になることを恐れています。そのため次の技術を探し、勉強し、トレンドに乗っていち早くそのコードを試して、極力早くそのプロジェクトから脱出するというチキンレースを行っています。
それが上手くできた人は、毎年のように言ってることがコロコロ変わりますが、常にハイレベルのスペシャリストだと認識されるでしょう。

未経験者が就職する際には、一旦その人らが生み出したクソをメンテナンスする業を背負わなければ業界に潜り込めませんので、勉強する必要が出てきます。

 

これは戦略的なゲームです。
例えばFlutterを例にあげれば、いち早くその流行を察知し、勉強し、技術記事を書き、著書を書き、登壇して、スペシャリストになり、それを散々布教した上で企業にアドバイザーとして技術支援して高い報酬を得る。みたいな人も居ます。
羨ましいです!

 

そしてそういう人らの情報を真に受けた我々下々のエンジニアがそれを勉強して、それが業界標準になり、誰もがそれを勉強しなければならなくなる、という社会の仕組みです。

 

だから私登壇とかああ言うのぶっちゃけ嫌いなんですよね。
まあ本人らは楽しくやってそうですし、完全に善意でやってると思うんですが。回り回って事業の速度を遅くしたり工数増大させたりしてるだけでは?という・・・すいません愚痴が過ぎました。

 

新人が採る選択肢はまず2つ、就社(Closed)か、就界(Open)か

もし大企業に就社して、そこの方針が「RxSwift+MVVM使おう!」だったら、それを勉強するべきです。もしそれが別の技術だったとしても勉強するべきです。特に大きい会社では色んな独特な技術が使われています。それがたとえニッチで学習コストが高かったとしても、頭が良い人を採用し、時間をかけてやっていけばいいわけですから。会社の方針は間違っていませんし、社員もそれに沿うのが出世への近道でしょう。
それでいいんです。そういう会社は売上がすごく高いんですから。世間で何が流行ってるかよりも社内で何が使われてるかの方が重要です。

対して、例えばフリーランスジョブホッパーのように「どこでも通用する技術を身に着けよう」と言うのであれば少し話が難しくなります。まず大多数がやっている開発方法を優先すべきでしょう。ニッチだったりレガシーなものを採用しているプロジェクトへのアサインは首を絞めますから、会社や案件選びから考えていかなければなりません。
また、新しい技術が袋小路になっていないか、それがレガシー化した時に自分のスキルとして何が残るか考えなければなりません。

 

Closedな人材としてやっていく場合

何より必要なのは入りたい会社の採用している技術です。
それを調べたりヒアリングするところから始まると思います。
まあこっちは簡単です。

Openな人材としてやっていく場合

こちらは難解です。
まず、特定の技術をやりたいという欲求が具体的にあるのならば、それができるところに行くべきでしょう。
RxSwiftだったり、SwiftUIをやってるイケてる会社を探すのが良いと思います。

 

そうではない場合、より厄介です。
そもそも会社の募集要項に「RxSwift+MVVM」があるのはいくつか考えられます。

  • 現状そのプロジェクトが有る
  • そのくらい勉強している、やる気ある優秀な人材がほしい
  • 流行ってる技術を採用している会社だというアピール

会社としては優秀な人に来てほしいので間口を広くしたいという状況があります。
そうなると、「弊社では最新トレンドの技術が試せますよ」とアピールしたいわけです。この様々な思惑の中、行動を見極めなければならないと思います。

 

もしその会社がSwiftUIを採用していないのに「SwiftUIできる人募集!」と書いていたらどう思うでしょうか?不誠実な会社だと思うでしょうか?そういう会社はたくさんありますが、そうとも言い切れません。
そういう最新技術やってますアピールをする会社には、もちろん技術に対するモチベーションが高い人が集まるでしょう。
逆にレガシーな技術を採用している会社には、優秀な人があまり来てくれないかもしれません。

プロジェクトはチーム戦ですから、優秀な人がより来てくれる会社に言ったほうが安全ですよね?

 

ただ、そういう会社に行くと当然上で言ったような「最新トレンドの社会の流れ」に簡単に流されて苦しい思いをします。
要はどう足掻いても絶望です。

 

iOSエンジニアの差別化しづらい問題

エンジニアってより難しいことやってハイレベルの人材になるみたいな風潮あるじゃないですか。例えば検索技術とか、データベース技術とか、セキュリティ関係とか、ああいうのはそんな感じあるんですが
特にiOSエンジニアはAppleにしたがって普通にやるのがベターみたいなシーンが多くて、ぶっちゃけ歴3年以降、他のエンジニアとの差別化が難しくなってくる職業だと思います。

そんな中焦って色んなものに手を出すんじゃないかと睨んでるんですが、これって難しいですよね。キャリアパスとしてはしょうがない側面もあるし、でも「より難解なことしたもん勝ち」ってなんか嫌ですよね。

フリーランスやってると、RxSwift案件の単価が明らかに2割くらい高いんですよ。これってどういうことかというよ、他人の書いたRxSwiftを引き継いでくれるエンジニアが少ないってことだと思うんですよ。なんかね、お客さんにはマイナスですよね、っていう。

 

絶望から逃れる手

上流工程のような、技術以外のスキルを身につける手がありますが、これでも結局トレンドには流されます。上流工程を身に着けつつ、フリーランスになれば結構この絶望から逃れられます(今の私がこれです)

登壇者になる手もあります。

優秀な、分かってるリーダーの下につくというのも手です。ただしその人がつよつよエンジニアだとついていけない事も往々にしてあります。

自分がそのリーダーになってしまうというのも手です。ただし出世する必要がありますし、部下を制御できるかはまた別問題です。

 

採用しないにしても勉強するのは有り

話の流れで漏れましたが、新しい技術を採用はしないにしても勉強するのは有りだと思います。
何かしらの考え方を参考にして、似たようなことを自分のコードで試すということができます。
教養にもなりますし、いくつかの新しい技術は実際にデファクトスタンダードになってしまいますから、その見極めの練習も必要です。

 

iOS + MVVMは今後どうなる?

私はCocoa MVVMになると思っています。
より柔軟に、画面やパーツ毎に切り替えできるようになるんじゃないでしょうか?ある意味理想的だと思います。

 

話足りないこと・まとめ

まとめるの無理ですわこれ。

とりあえず新人は真面目アピールのために勉強せざるを得ないんじゃないですかね?あと会社の方針はよく聞いたほうが良いです。

あとは、技術の採用というのは絶対的な解があるわけではなくて、トレードオフがあったりチームメンバーに依存したりします。あくまでやってるのは理論じゃなく工学なので。

だから「より良いアーキテクチャーやライブラリーがあるんじゃないか?」というのは幻想だったりします。そういう探求もエンジニアのさがだと思いますが。残念ながらAppleも進化していってるので、その結果iOSエンジニア自体が徐々にコモディティ化していってます。まあアプリエンジニア自体がレアなので全然まだまだブルー・オーシャンですけどね。

そうそう、AndroidGoogleがMVVMを推奨しています。でもこのMVVMはMVVMじゃないとかそういう人たちも居ます。よぐわがんね。宗教戦争

developer.android.com

 

そもそもViewModelって最初は違う意味合いだったんですよ。Utility的な。それがいつの間にかアーキテクチャになって。てか昨今のアーキテクチャという概念自体が、どうにもWebにおけるフレームワークを作りたがってる感じなんですよね。Webは本当にフレームワークありきなんですけど、アプリはiOSAndroidもそれそのものがフレームワークみたいなもんなんで、フレームワークonフレームワークみたいな黒魔術みを感じます。

あとCleanArchitectureはアーキテクチャじゃなくて「きれいに書く方法だ」みたいに言われてますね。私はその本読んでないので何とも言えないですが。

何かしら技術を採用するときは、大抵そのカウンターとなるデメリット記事があったりするので探してみてください。Reduxとかも結構見つかります。ReSwiftってやつ。

エンジニアってどうもこういう枠組み発明をしたがる傾向がありますね。昔はWebやSIerでオリジナルフレームワークが作られてて地獄だった、みたいな昔話が出るんですが、アプリ業界ではそういうアーキテクチャ地獄についてまだ好意的な意見が多いですよね。ちょっと謎。

 

あとなんだろ、思いついたら追記します。

 

宣伝

iOSエンジニア志望者のたまり場みたいな場所を作ろうかなとちょっと考えています。
興味があったらお問い合わせください。
そこからベテランエンジニアがピックアップしていくみたいなイメージで考えてます。あと就職の相談したりとか。
そう言えばオフショアとかニアショアとか存在するのにインターン活用ってあまりないよなと思って、思いつきです。ぜんぜん儲かる気がしないのでただの慈善活動になりそうですけど。

似たようなのは2個くらいあるらしいですけど、用途として被らないようにしたいですね。勉強は見ませんが仕事は与えるみたいな感じで。

 

f:id:otihateten3510:20210912204718p:plain