はじめに
前回の記事でXcodeGenを導入したプロジェクトの話をしました。
その記事で紹介したプロジェクトではCocoaPodsとCarthageを用いてライブラリを管理していました。
そろそろXcode9で導入されたSwift Package Manager(以下、SwiftPM)に移行してみてもいいかなと考え、XcodeGenはそのままでライブラリ管理をSwiftPMにしてみた際の知見を話します。
XcodeGenの解説は前回の記事を参考にしていただき、本稿では割愛します。
SwiftPMとは
CocoaPodsやCarthage同様にSwiftで構成されているパッケージを管理するツールです。
他にない強みとしては以下です。
- Apple製
- XcodeのIDEサポートがある
Apple製なので、Xcodeを含めたツール周りで親和性が高いので今後はSwiftPM使っといた方がいいかなと考えています。
Xcode11以前ではPackage.swift
というソースコードで管理し、ツールアプリやサーバー側ソースコードしか扱えませんでしたが、Xcode11よりIDEサポートが導入され、Xcodeで完結できるようになりました。
SwiftPM対応しているライブラリはプロジェクトルートに Package.swift
が置いてあるプロジェクトは基本できます。
XcodeGen+SwiftPM
やり始める前は Package.swift
が必要になるかなと思いました。
ですが、終わってみるとXcodeGenのプロジェクト構成ファイルproject.yml
のみで完結できました。
完成したものでSwiftPM関係ある部分を抜粋しました。クリックで開きます。
name: test
packages: # SwiftPMで扱うPackageを最初に定義
Reusable:
url: https://github.com/AliSoftware/Reusable
exactVersion: 4.1.1 # バージョン指定 versionでもOK
RxSwift:
url: https://github.com/ReactiveX/RxSwift
minorVersion: 5.1.1 #指定マイナーバージョン ex: 5.1系ならどれでもOK
Action:
url: https://github.com/RxSwiftCommunity/Action
branch: master # ブランチ指定
RxSwiftExt:
url: https://github.com/RxSwiftCommunity/RxSwiftExt
minVersion: 5.1.0 # 指定バージョン以上かつ
maxVersion: 5.2.0 # 指定バージョンより小さい
APIKit:
url: https://github.com/ishkawa/APIKit
revision: b95a941 # コミット指定
Rswift:
url: https://github.com/mac-cain13/R.swift.Library
majorVersion: 5.2.0 #指定メジャーバージョン fromでもOK ex: 5系ならどれでもOK
SwiftyUserDefaults:
url: https://github.com/sunshinejr/SwiftyUserDefaults
from: 5.0.0 # majorVersionと同義
# 後は同様の書き方、細かい設定なので、割愛
targets:
test:
type: application
platform: iOS
scheme: {}
deploymentTarget: "13.0"
sources:
- test
- path: "test/Resources/R.generated.swift"
optional: true
type: file
dependencies:
- target: TestFramework # Embedded Framework
- package: Action
- package: Reusable
- package: Rswift
- package: RxSwift
product: RxCocoa # RxSwift内部のRxCocoaを指定する
- package: RxSwift
product: RxRelay # RxSwift内部のRxRelayを指定する
- package: RxSwift
- package: RxSwiftExt
# 後は設定周りなので、本稿では割愛
TestFramework:
type: framework
platform: iOS
scheme: {}
deploymentTarget: "13.0"
sources:
- TestFramework
dependencies:
- package: APIKit
- package: SwiftyUserDefaults
# 後は設定周りなので、本稿では割愛
全体の設定を確認した場合はこちらをご覧ください。
後はプロジェクトルートでxcodegen
を叩くとSwiftPMのライブラリ依存関係が解決したプロジェクトが生成されます。
生成プロジェクトをXcodeで開くとそれぞれのfetchが始まり、しばらくすると以下のように Project Navigator上で確認ができます。
次に細かい定義に関して説明していきます。
1. プロジェクト全体で扱うPackageを定義
まずはXcodeGenのドキュメントを参考にプロジェクト全体で扱うパッケージをそれぞれ定義します。
url
にて、リモート先を指定し、その後のパラメータでバージョンなどの細かい指定ができます。
今回は特にローカルで扱うものがなかったのですが、先述のドキュメントにも記載の通り導入ができます。
name: test
packages: # SwiftPMで扱うPackageを最初に定義
Reusable:
url: https://github.com/AliSoftware/Reusable
exactVersion: 4.1.1 # バージョン指定 versionでもOK
RxSwift:
url: https://github.com/ReactiveX/RxSwift
minorVersion: 5.1.1 #指定マイナーバージョン ex: 5.1系ならどれでもOK
Action:
url: https://github.com/RxSwiftCommunity/Action
branch: master # ブランチ指定
RxSwiftExt:
url: https://github.com/RxSwiftCommunity/RxSwiftExt
minVersion: 5.1.0 # 指定バージョン以上かつ
maxVersion: 5.2.0 # 指定バージョンより小さい
APIKit:
url: https://github.com/ishkawa/APIKit
revision: b95a941 # コミット指定
Rswift:
url: https://github.com/mac-cain13/R.swift.Library
majorVersion: 5.2.0 #指定メジャーバージョン fromでもOK ex: 5系ならどれでもOK
SwiftyUserDefaults:
url: https://github.com/sunshinejr/SwiftyUserDefaults
from: 5.0.0 # majorVersionと同義
# 後は同様の書き方、細かい設定なので、割愛
バージョン記法
記法 | 指定内容 |
---|---|
majorVersion: n.m.i or from: n.m.i
|
指定メジャーバージョン n系ならどれでもOK |
minorVersion: n.m.i |
指定マイナーバージョン n.m系ならどれでもOK |
exactVersion: n.m.i or version: n.m.i
|
バージョン指定 versionでもOK |
branch: main |
指定ブランチ |
revision: xxxxxx |
コミット指定 |
※ XcodeGen2.18.0時点 |
2. 依存関係をTargetに記述
次にそれぞれのTargetにてXcodeGenのドキュメントを参考に依存関係記述していきます。
ポイントとしては、RxSwift
みたいなプロジェクトの中にあるライブラリの場合は、さらに指定が必要になります。
targets:
test:
type: application
platform: iOS
scheme: {}
deploymentTarget: "13.0"
sources:
- test
- path: "test/Resources/R.generated.swift"
optional: true
type: file
dependencies:
- target: TestFramework # Embedded Framework
- package: Action
- package: Reusable
- package: Rswift
- package: RxSwift
product: RxCocoa # RxSwift内部のRxCocoaを指定する
- package: RxSwift
product: RxRelay # RxSwift内部のRxRelayを指定する
- package: RxSwift
- package: RxSwiftExt
# 後は設定周りなので、本稿では割愛
TestFramework:
type: framework
platform: iOS
scheme: {}
deploymentTarget: "13.0"
sources:
- TestFramework
dependencies:
- package: APIKit
- package: SwiftyUserDefaults
# 後は設定周りなので、本稿では割愛
注意点
こちらでも記載がありますが、Xcodeより[File] -> [Swift Packages] -> [Add Package Dependency...]から行った場合は、ProjectName.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
に生成されます。
Xcodeから新たにライブラリを導入した場合、上記の更新対象ファイルをproject.yml
に落とし込む必要があり、めんどくさいです。
※ Package.resolved
は実際の取り扱いバージョン情報の定義がされています。CocoaPods
でいうPodfile.lock
のようなものです。
まとめ
導入自体はXcodeGenのドキュメント見ながら行えば、簡単にできます。
Xcode11よりIDE上で管理できるので効率化や管理コスト削減などは見込めると思います。
ただ注意点でも述べたようにproject.yml
に落とす作業が他と比べてめんどくさいです。
後、やっぱりCocoaPodsやCarthageに比べると対応しているものが少ないかなと思います。
なので、ライブラリ依存が少なく済む小規模のプロジェクトとかだと導入してみてもいいんじゃないでしょうか。