⛺
[iOS] Swift Package Managerで個人アプリをマルチモジュール&プロジェクト化してみた
はじめに
キャッチアップを兼ねて個人開発で作成していたアプリをSwift Package Managerでマルチモジュール化してみました。
公開されたアプリはこちら
ソースコードはこちら
マルチモジュールにするメリット
今回はSPMでマルチモジュール化しましたが、そのことで以下のようなメリットがあると思います。
-
依存関係がわかりやすくなる
- Package.swiftを見れば依存関係がわかります。
-
コンフリクトの減少
- 多人数で開発している場合は、プロジェクトファイルののコンフリクトが必ずと言っていいほど発生しますが、それが発生しにくくなります。
-
可読性の向上
- モジュールごとにコードを分割するため、強制的に各モジュールの責務(役割)が明確になり、可読性が向上します。
(プロジェクトファイルのコンフリクトについてはXcodeGenを導入することで防ぐことはできますが、個人的にはyamlファイルのメンテナンスコストが高いと感じています。)
マルチプロジェクトにするメリット
さらに今回は環境ごとにプロジェクトファイルを用意するマルチプロジェクトを採用しました。
環境ごとにプロジェクトファイルを分割している
使ってみてのメリットとしては
-
環境ごとに1つのプロジェクトファイルなので環境設定が楽になる
- StagingはこっちでProductionがこっちがなくなります。(散らからない)
-
アプリごとにプロジェクトファイルを分けることができそう
- 今回は環境ごとにプロジェクトを分けましたが、一つのプロジェクト内に複数のアプリを作成することもできそう
- 同じような機能を持ったアプリであればCoreなモジュールを使い回して、素早くリリースすることができるかも?(やったことないので未検証)
- たまたま見つけましたが、ONE株式会社さんはその構成を取っていそう
- https://engineering.0x1.company/tech-stack-of-ios-d6466798ed80
アプリの構成
アプリの構成は以下のようになっています。
各Moduleの関係図
Find | Group | Settings |
---|---|---|
Outline Name | Module Name | Description |
---|---|---|
App | ProductionApp | 本番環境のエントリーポイント |
〃 | StagingApp | 開発環境のエントリーポイント |
Features | FindFeature | Find機能をまとめたもの |
〃 | GroupFeature | Group機能をまとめたもの |
〃 | SettingsFeature | Settings機能をまとめたもの |
Core | UIComponents | UI周りのExtenstionやColorを定義したもの |
〃 | UseCases | 複数のViewModelなどで使われるものをまとめたもの |
〃 | Repositories | 外部またはDBにアクセスする実装をまとめたもの |
〃 | Models | アプリ内で使われるEntityをまとめたもの |
〃 | APIService | 複数のRepositoryで使われるAPI接続に関わるもの |
実装時に困ったこと
- Xcodeでプロジェクトを開いたときにSchemeをうまく認識してくれずにビルドができない
- Xcodeの再起動
- Package.swiftを変更して依存関係を変更しても認識されない
- Xcodeの再起動 & Clean build
その他
UseCaseやRepositoryのDI用にswift-dependenciesを導入しました。(Test用、Preview用に注入を変更することができるのでとても使い勝手がいいです)
まとめ
ほぼ全く機能がない個人アプリだったのですんなり移行することができました。
Xcode独特の挙動に困ることもありますが、マルチモジュール化はかなり良いのではないでしょうか。
今回はまだやってないですが、Feature間の画面遷移は今の構成だとできないので考えていきたいと思っています。
参考
- マルチモジュール化について
https://zenn.dev/usk2000/articles/7c5cf34c3dff5a
https://engineering.mercari.com/blog/entry/20210906-162294936e/
- この記事はuhooiさんのLokiに触発されて作りました。Speacial Thanksです!
終わり
Discussion