ココナラiOSアプリのSPMによるマルチモジュール化に向けて
こんにちは。株式会社ココナラアプリ開発グループ、iOSチームの上沼です。
今回は、ココナラiOSアプリのSPMによるマルチモジュール化に向けて、検討したことをご紹介します。
背景
ココナラアプリはリリース以来、様々な機能を追加しており、規模の大きいアプリになってきています。それに伴い、開発する上でいくつか課題が生じており、大きなものとしてビルド時間の増加があります。
ビルド時間
ココナラアプリでは、既にFrameworkを利用したモジュール分割を行っているのですが、レイヤーごとに分割しているため、機能が増えるにつれ、ビルド時間が長くなるという課題があります。
また、ココナラでは、SwiftUIの導入を進めていますが、ビルド時間が長いため、Previewがなかなか表示されず、活用できていません。
そのため、レイアウトを一部変更しただけという場合でも、画面を確認する際はビルドが完了するまで長い時間待つ必要があり、開発効率が落ちてしまっています。
コンフリクト
ビルド時間の他にコンフリクトも課題となっています。
ココナラでは並行してプロジェクトが動いているため、ファイル追加や同一ファイル変更によるコンフリクトがよく発生しており、開発効率が落ちる要因となっています。
Frameworkによる分割
ココナラアプリがレイヤーごとに分割されているという話をしたのですが、ここにも課題があり、Modelがいろいろなレイヤーに散らばっていたり、分割の仕方が曖昧になっており、正しく責務を果たせていません。
現在並行してSPM導入を進めているということもあり、SPMによるマルチモジュール化によって上記課題を解決出来るのではということで検討を行っています。
モジュールの分割
モジュール分割の方法としては、機能単位でモジュールを分割する方法や、レイヤー単位で分割する方法があります。
どのような課題を解決したいかによって、モジュール分割の仕方が決まってきますが、ココナラではビルド時間の短縮を主な目的としているため、大きな方針としては機能単位でモジュールを分けることにしました。
基本的には機能単位でモジュールを分割しつつ、複数の機能で利用する部分については共通モジュールとして切り出します。例えば、モデルや共通コンポーネントなどです。
機能単位のモジュールをFeatureモジュール、共通モジュールをSharedモジュールとしています。
Featureモジュール間の参照
機能単位での分割の方針として、依存の複雑化や循環参照を避けるため、Featureモジュール同士の参照を制限しようと考えています。
ここで問題になるのが画面遷移などの他の機能と連携するような実装です。
直接他の機能を参照するということができなくなるため、依存を取り出す仕組みを新しく導入する必要があります。
現時点では検討段階ですが、おおまかに以下のような仕組みにしようと考えています。
Environmentは、機能の実装を抽象化する役割を持ち、各モジュールはEnvironmentにアクセスして依存を取得します。
Environmentの実装はアプリケーションターゲットで行い、各モジュールにDIします。
画面遷移
FeatureAからFeatureBに遷移する場合、FeatureBを直接参照はせず、SharedモジュールにあるEnvironmentにアクセスし、FeatureBに遷移する処理を実行することで画面遷移を行います。
import SharedModule
struct FeatureA: View {
let env: Environment
var body: some View {
Button {
env.moveToFeatureB()
} label: {
Text("FeatureBへ遷移")
}
}
}
アプリケーションターゲットはFeatureBを参照することが出来るため、画面遷移の処理を実装し、FeatureAに依存を注入しています。
NotificationCenter
ココナラアプリでは、NotificationCenterを利用しており、機能を跨いで処理を実行しています。
しかし、モジュール分割した際に、別のモジュールに対してNotificationCenterで通知を送るということが出来なかったため、通知や監視の実装はアプリケーションターゲットで行うようにし、モジュールからEnvironmentを通して実行するという形にすることで通知を行えるようにしています。
まとめと今後について
今回は、ココナラiOSアプリのマルチモジュール化に向けての取り組みについてご紹介しました。
今後どのように移行を進めるかなどの検討を行った後、マルチモジュール化を進めていく予定です。マルチモジュール化が一定進んだタイミングで、その時の状況や新たに出た課題について共有出来ればと思います。
ちなみに、今年の9/1 ~ 9/3に開催されたiOSDCでは、ココナラもブースを出しており、私も参加していました。その時の様子をこちらで紹介しているので、良かったら覗いてみてください!
ココナラでは、一緒に事業のグロースを推進していただける様々な領域のエンジニアを募集しています。iOSアプリ開発だけでなく、フロントエンド領域・バックエンド領域などでも積極的にエンジニア採用を行っています。少しでも興味を持たれた方がいましたら、エンジニア採用ページをご覧ください。
Discussion