スタディサプリ Product Team Blog

株式会社リクルートが開発するスタディサプリのプロダクトチームのブログです

不要な Swift コードを静的解析で安全かつ継続的に消していく

不要な Swift コードを静的解析で安全かつ継続的に消していく

こんにちは、iOS エンジニアの @manicmaniac です。 現在スタディサプリ iOS アプリ開発チームのエンジニアリングマネージャをしています。

スタディサプリ iOS アプリは開発開始から7年以上が経過した、そこそこ歴史のあるプロダクトとなっています。 そこそこ長い歴史の中では、「スタディサプリ」が React Native から卒業するまで、あるいは技術的負債への感謝と敬意 で触れたように大小さまざまの利用技術の変遷があり、開発者の入れ替えがあり、多数の新機能の追加や削除がありました。 したがって、コードベースには歴史の生き証人のような不要コードがポツポツと存在しています。

今回はこれらの不要コードを削除する活動を、ツールの助けを得て行った話をします。

不要コードとは

さきほどから不要なコードと言っていますが、今回は 到達不能なコード に話を絞ります。 たとえば、参照されない変数やクラス、あるいは xib ファイルなんかがそれにあたります。

これらのコードは実行されることがないにもかかわらず、読み手に負担をかけたり、余計な依存関係を導入したり、ビルド時間を奪ったり、場合によってはバイナリサイズや実行時メモリのフットプリント増大を招いたりします。

静的解析ツールの活用

幸い Swift には Periphery という不要コードを解析して警告を出してくれるツールがあるので、これを利用しました。 すでに日本語の解説記事がいくつかあるので、具体的な使い方の説明はそちらに譲ります。

仕組みとしては Xcode ビルドシステムがビルド時に作成してくれる IndexStore を解析することで不要なコードを検出しているようです。 したがって、デフォルトでは Periphery を実行すると xcodebuild が実行されます。あらかじめビルドをするなどして IndexStore を作成しておけば、ビルドをスキップして解析だけ行うこともできます。

静的解析による成果

当初 Periphery を実行したところ、1700 件以上の警告が出てしまいました。

警告の中には自動生成のコードに対するものだったり、規約上必要だが使われない引数 (sender とか notification) に対するもののような無視できるものが含まれていました。 それらを除いたうえで、いくつかの PR に分けて作業を進めました。 静的解析も完璧ではないので、万一にも到達可能なコードを削除しないよう、PR の分量を減らしてレビュー可能にすることや、コンフリクトを避ける狙いでした。

Remove unused classes なる PR

こんな感じの PR を合計 8個ほど作り、2,500行ほどのコードを削除することができました。 かかった時間としてはざっくり 8時間程度でした。 静的解析を完全に信頼せず、全ての修正箇所を目視でチェックしつつ、怪しいところは削除の経緯を調べながらだったので思った以上に時間がかかりました。

作業を進めていて感じたこととしては、以下のようなことがありました。

  • ツールに頼っても知らないコードを消すのは怖いので、日頃からこまめに削除していくことが大事
  • 静的解析の結果、実際には使っており、偽陽性として判定されたコードがわずかにあったので目視で確認していてよかった
    • ツールの不具合ではなく、xib などから動的に参照している箇所が主だった

継続的に進めていくための仕組みづくり

というわけで、いったんそこそこまとまった量のコードを消すことができたものの、

ツールに頼っても知らないコードを消すのは怖いので、日頃からこまめに削除していくことが大事

ということで、日頃からこまめに削除できる仕組みを作りたいと思い、実際にやってみました。

Periphery は Xcode 上で警告を出すような使い方 も考慮されているのでこれでやってもいいのですが、スタディサプリではすでに Danger を使って CI 上で linter を走らせたりしているので、その仕組みを使うことにしました。

調べてみたところ有力な Periphery の Danger プラグインは知られていなさそうだったので、このブログの公開に間に合わせるべく急いで作ってみました。

danger-periphery

danger-periphery がうまく動いている様子

こんな感じで PR 作成時に触ったファイルについて警告を出すことで、新たな不要コードを入れるのを防ぎつつ、ボーイスカウトのようにちょっとずつ綺麗にしていけるんじゃないかと思っています。

まとめ

というわけで、静的解析ツール Periphery を使った不要コードの削除についてご紹介しました。

コードを消すというのはややもすると退屈な作業になりがちですが、ツールを使って解析したり、今後不要コードに気づける仕組みづくりをするのはなかなかクリエイティブな部分もあって楽しめました。

引き続き、よりよい学びを届けていくためにアプリの継続的な改善をしていこうと思います。

採用のお知らせ

スタディサプリの開発に関わる iOS エンジニア および シニア iOS エンジニア を積極的に募集しています。 不要なコードを消したい人や、世界の果てまで最高の学びを届けたい iOS エンジニアの方は是非ご応募いただけると幸いです。