LoginSignup
24
10

More than 3 years have passed since last update.

はじめに

前回の記事で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関係ある部分を抜粋しました。クリックで開きます。
project.yml
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上で確認ができます。

xcode.png

次に細かい定義に関して説明していきます。

1. プロジェクト全体で扱うPackageを定義

まずはXcodeGenのドキュメントを参考にプロジェクト全体で扱うパッケージをそれぞれ定義します。
url にて、リモート先を指定し、その後のパラメータでバージョンなどの細かい指定ができます。

今回は特にローカルで扱うものがなかったのですが、先述のドキュメントにも記載の通り導入ができます。

project.yml
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みたいなプロジェクトの中にあるライブラリの場合は、さらに指定が必要になります。

project.yml
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に比べると対応しているものが少ないかなと思います。

なので、ライブラリ依存が少なく済む小規模のプロジェクトとかだと導入してみてもいいんじゃないでしょうか。

24
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
10