2019年も残すところあと6ヶ月。上半期はどんな感じでiOSアプリ開発をやってたかっていうのを書いておきます。
SwiftUI
とかCombine
とかそういった話題はありません。
目次
開発用ツール
XcodeGen
デメリットはあるもののXcodeGen
が圧倒的に便利です。
しかし、すぐにXcodeGen
を使いたかったかというとそういうわけでもありませんでした。
なのでXcodeGen
をチームで採用しようというのは難しい判断になりそうですね。
一年ちょっと前の自分は`XcodeGen`なんていらないんじゃ...と "試しもしないで" 言ってたので反省した。今は小さく趣味アプリで試してデメリットを把握してからメリットがでかいので仕事で活かしてる
— y.imajô (@yimajo) April 26, 2019
もう少し細かく、自分の気持の移り変わりとしては次のような感じです。
「XcodeGen
の存在知る(知っても別にコンフリクト慣れてるからなーという気持ち)」
↓
「XcodeGen
を試してみる(うーむ、まあ長所が短所を超えているな、くらいの気持ち)」
↓
「複数人のプロジェクトでXcodeGen
を運用する(短所をカバーする圧倒的な良さがあるやん!という気持ち)」
という感じで結局導入してみたら長所が短所を圧倒的に超えてました。
長所
長所を並べてみると
- Xcode関係
Scheme
とConfiguration
の仕組みを知ることになる- わざわざ
Scheme
で設定を変えるみたいな変なことやっててもConfiguration
に差し替え可能 Scheme
間やConfiguration
間の設定値の差分がコードなのでわかりやすい- ファイルが実ファイル順で並ぶので細かいことを気にしなくて良くなる
- マルチモジュールでも構成が把握しやすい
- git関係
- プロジェクトのファイルがコンフリクトしなくなるので気にしなくて良くなる
- 自分が複数ファイルを先に追加してコミットする際にもそのプロジェクトファイルを分割するという作業がない
短所
こういうとき、短所を言えないとちょっとあやしいですからね。短所を無理やり考えてみました。
- 実ファイルからXcode上のグループを作るため、例えばテストターゲットのファイルをプロダクション用のファイルと同じディレクトリに入れられない
この短所は長所でもあります。例えば「テストコード用のファイルなんて別でまとまってるほうがいい」「実ファイルとXcode上のファイルが間違って配置して混乱したら困るからそれを防げてる」とも言えます。
他の短所を無理やり出してみると
- includeしていく
xcconfig
ファイルのinclude順や構造が分かりづらいかも
一つのBuild Configuration
に1つのxcconfig
を指定するため、自前のxcconfig
から複数のincludeしていかないといけない。cocoapodsのxcconfig
をincludeするのもそのうちの一つですが、ちゃんと整理して全共通用のBase.xcconfig
作ったりDebug.xcconfig
/Release.xcconfig
を作って無駄がないように導入したくなるわけです。
これはまず表を作って設定ファイルを階層的に整理していくのがいいと思います。
あとまあ、ブランチを変更した際にファイルが異なっていることがあると確実にXcodeGen
を実行しないといけないというのも短所かもしれません。
なのでこれの解決のために、git hooks
でcheckout時に常にXcodeGen
するようにしてます。cocoapodsでpods install
をhooksに入れてたのと同じですね。
その他: 一部の設定を変更するぐらいならSchemeでやるべきではないがXcodeGenならそれも面倒でもない
他にはScheme
関係。
これはもう根本的な前提の話なんですが、例えば通信先のホスト名など、プロジェクト内の変数を入れ替える場合にConfiguration
で分けてよって思うわけです。これたまにScheme
で分ける人がいてそれめちゃくちゃ面倒なのでしょうと。
基本的にScheme
っていうのは複数のConfiguration
を保持できるわけです。
Apple公式のSchemeのコンセプト
を引用してみると
An Xcode scheme defines a collection of targets to build, a configuration to use when building, and a collection of tests to execute.
で、
そういった大がかかりな仕組みでわざわざ変数書き換えるためにSchemeを使うっていうのはオーバーなわけですよ。
でもどうしてもSchemeで変数の書き換えを分けたいんだったら、まあXcodeGen
でやるとそういうのも差分わかりやすいよねってことです。Configuration
で分ければいいとは思うけど。
mint
mintはバージョン固定できるのが特徴です。例えばXcodeGen
のバージョンをチームで揃えたりするのにラクですね。brewで特定のバージョンにするっていうのは難しいですが、mintは特定のバージョンをインストールするのも、特定のバージョンで実行するのもラクです。
mint run yonaskolb/XcodeGen@1.2.4 # run 1.2.4
https://github.com/yonaskolb/Mint
つまりXcodeGen
やるならmint
も入れるかなとは思います。
SwiftFormat
swiftlint
も使いますが、それはそれとしてSwiftFormat
も使っています。
gitのpre-commit
のhooksに設定していて、commitするたびにcommitしたファイルを対象にSwiftFormat
が動作しています。
GitHub DesktopというMacのクライアントにはUndo機能があるため、コミットしたファイルに変更があるとSwiftFormat
の変更点を確認しすぐUndoしてコミットメッセージそのままコミットし直すという感じです。
3ヶ月に一回くらいSwiftFormat
のルールを見直すっていうのが良いと思っています。
SwiftFormat
もmint
でインストールして使うのがいいと思います。
フォーマットルールのページは分かりづらいんで貼っておきます
https://github.com/nicklockwood/SwiftFormat/blob/master/Rules.md
リアクティブプログラミングフレームワーク
RxSwiftは使うが限定的に使う
- RxSwiftは使う場面は入力イベントが複数あって出力も複数あるときと限定してます
- つまり通信結果を表示したいだけの画面などはRxSwiftは使わない
- おそらく世の中の大半のプロの方たちにも、Rxの概念は難しいと思います。チームでやっていく際にもコードレビューのことを考えたら逆に時間がかかる
- そうなるとテストコードを書いてないRxSwiftのコードなんてかなり恐ろしい
参考の本: RxSwift研究読本
一緒に開発するメンバーがリアクティブプログラミングについて、共通の見解を持つため絶対外せないのが「RxSwift研究読本」じゃないかと思います。
関数型プログラミングのチュートリアル
Rx公式の関数型プログラミングのチュートリアルっていうのがあります
すでにRxがわかっている人からしたら、Rxが採用する関数型プログラミングのアイデアってこれだよなーという感じです。それを知らない人からしたらちょっと意味がわからないかもしれない。「なぜforEach
からmap
とかfilter
を作ってんの?」って気分になるかもしれないですが、その小さな部品を作ってまた組み合わせていく、それがRxが採用する関数型プログラミングのアイデアなわけです。これはちょっとRx慣れてからやるといいと思います。
テストコード
どのような対象にテストコードを書いているか
なるべくViewController
は(難してく)テストしたくないので、ViewController
に処理を集めず、必然的にViewModel
やPresenter
に対してテストコード書いています。
現状、テストコードの利点はだいたい次のように捉えていて
- 不安解消
- コードをレビューしただけで仕様を満たしてるんか?
- 運用されているコードは正常に動作するんか?
- 不具合修正後に対応できたんか?
- インタフェースや再利用性の確認
- 自分が作ったモジュールをテストコードで再利用して見直す
- ライブラリは正しく使えてるか
しかしこのメリットに対して、時間的コストをかけすぎるとメリットに対してバランスが悪くなるとは思います。
例えば一つの機能に対するテストコードを書くときに2時間以上かけない、という制約がないと、無駄にテストコードを書いてしまったり、なんかそもそもテスト対象が複雑すぎるということに気づくきっかけになるはずです。
また、どんなコードを書けば上記の不安が解消するのかという根本を考えずにテストコードを書こうとするとかなり大変なことになります。具体的には単体テストで済む話なのに結合テストをしてMockをたくさん作らないといけないと思い込む、とかです。
Quick/Nimble
かXCUnit
を使うかの選定についてはQuick/Nimble
が使いたけりゃやったらいいと思っています。単体テストでもQuick/Nimble
の表現力は魅力的なので、XCUnit
使ってコメントを散りばめるぐらいならQuick/Nimble使えばいいと思います。
その他、このテストコード無駄だなーと自分では思っても、テストコードの書き方を他のメンバーに示すコードとして意味がある場合もあります。または明らかに無駄だなーと思って書いてるとミスに気づくこともあるのでまあメリットもある。
もしくは無駄なほどテストコード書いていると、そのときはじめて時間をかけないということにたどり着けるかもしれない。
...というのが上半期の感想です。
おわりに
今年後半どうなっていくかわからないんですが、年末にはまたこっからどうなったかがあれば書いてみたいと思っています。
9月はiOSDC2019で「自作して理解するリアクティブプログラミングフレームワーク」が採択されたので話す予定です。どんなことをを発表するのかの細かいことはまた違う記事にしておきます。