🔨

SPMでのマルチモジュール構成 with SwiftPlaygroundsApp

2021/12/13に公開

概要

レシピ動画のクラシルのiOSでリアーキテクチャを担当しており、クラシルでSPMを導入する上で、
マルチモジュール構成において、
SwiftPackageManagerとSwiftPlaygroundsAppを使ったいい感じの構成を考えたのでzenデビューのついでに書いてみます
SPM自体や使用しているXcodegenの話や、マルチモジュールなどは偉大な先人がしてくれてるの、今回は取り扱いません。

目指した形

SwiftPlaygroundsAppを使用してDemoAppの作成メンテコストを下げつつ最小限のXcodegenのみで、ほぼSPMのみで完結する形。

App、DemoAppの開発と、App、DemoAppのbuildを、1つのWindow(workspace)上から行えるようにしたい!

↓最終的なXcworkspaceのプロジェクトナビゲーター

サンプル
https://github.com/ryogabarbie/SwiftPMMultiModule

目次

  • SwiftPackageManagerを使ったマルチモジュール
  • SwiftPlaygroundsApp(.swiftpm)を使用したDemoApp
  • アプリとSwiftPlaygroundsAppをworkspace上でビルドできるようにしたい

SwiftPackageManagerを使ったマルチモジュール

設計や構成などは今回は触れません。
現職のクラシルではXcodegenを使用したマルチモジュールでの実装を進めていますが、
Xcodegenでのマルチモジュール構成の管理の辛いところとして、Xcodegenのymlの学習コスト管理コストが高く社内でも管理できる人間が限られてくるなどがありますが、SPMにすればそれらとおさらばです。

ただ、DebugやReleaseなどのSchemeの管理などでは便利なので、App.xcodeprojなどはXcodegenで管理作成するため、一部Xcodegenも使用しています

let package = Package(
    ...
    products: [
        .library(name: "API", type: .static, targets: ["API"]),
        .library(name: "Home", type: .static, targets: ["Home"]),
    ],
    dependencies: [
        .package(name: "APIKit", url: "https://github.com/ishkawa/APIKit", from: "5.2.0")
    ],
    targets: [
        .target(name: "API", dependencies: ["APIKit"]),
        .target(name: "Home", dependencies: ["API", "UserDefaults", "FeatureInterfaces"]),
    ]
)

SwiftPlaygroundsApp(.swiftpm)を使用したDemoApp

Xcode13.2(beta)からSPMをいい感じにしたSwiftPlaygroundsAppというものが使えるようになりました。
これを使うと、SwiftPackageManagerを利用して、簡単にPlaygournd環境でアプリが開発というものです。
noppeさん の記事で知りました
https://qiita.com/noppefoxwolf/items/cd21a108aef079e2411f

Appで使用してるPackageをDemoAppのDependenciesに追加し、必要なものだけTarget.dependenciesに追加することで、必要なモジュールをさくっと追加しDemoAppを開発することができます!

let package = Package(
    ...
    dependencies: [
        .package(name: "Package", path: "../Package")
    ],
    targets: [
        .executableTarget(
            name: "AppModule",
            dependencies: [
	       // PackageのSettingモジュールをDemoAppで使用できるように
	       // ここで追加してないPackageのモジュールをlinkはできないので、必要なもの個別で追加する
                .product(name: "Setting", package: "Package", condition: nil)
            ]
        )
    ]
)

AppとSwiftPlaygroundsAppをworkspace上で開発&ビルドできるようにしたい

SwiftPlaygroundsAppを使用してDemoAppを作れて便利!という状態になると、AppもDemoAppも一つのXcode(同一のWindow)で開発したくなりますよね。
Projectベースだと、プロジェクトナビゲータにSwiftPlaygroundsAppwを追加することは可能でしたが、DemoAppの開発とbuildを行うにはSwiftPlaygroundsAppをクリックして専用のプロジェクト上で開発buildするしかありませんでした。(もしやり方あるよーって知ってる方は教えてください!)

そこでxcworkspaceを使用して、AppとPackage、DemoAppをそれぞれ開発できる形にしました。
↓ディレクトリ構成

workspaceを開いた状態で、new -> projectからSwiftPlaygroundsAppを任意の場所に作成。
finderで作成したSwiftPlaygroundsAppをworkspaceにドラッグ&ドロップでworkspaceに追加できます。
Workspaceはgit管理下に置いています。

まとめ

SwiftPlaygroundsAppを使用したDemoAppの開発などを含めたSwiftPackageManagerでのマルチモジュール環境での構成についてざっくりまとめました。
DemoAppの作成がかなり楽になり、Xcodegenを最小限に抑えた構成で、割と良いのではという気持ちです。

Discussion