0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

XcodeGen+Cocoapods環境でのSwiftPackageManagerの導入

Posted at

はじめに

今回Swift Package Managerを導入してみました。
Swift Package Manager自体はすでに数年前からあり、Xcode11が発表された段階でXcodeに統合されました。
そのため既に導入しているプロジェクトが多いと思います。

しかし現在継続して運用しているプロジェクトではXcodeGen+CocoaPodsという環境であり導入が遅れていました。
その上記のような環境である点を踏まえ、導入手順やつまづいた箇所をまとめました。

なぜSwift Package Manager導入に思い至ったか

ビルド時間の解消に向けて

CocoaPodsを導入しており、なおかつCocoaPodsBinaryも導入していました。
その為ある程度はプロジェクトビルド時におけるPods自体のビルド時間は抑えられていましたが、Binary化出来ずそのままになっていたPodが何個かありました。
プロジェクトの構成の問題もあるかもしれませんが、これらのPodが差分ビルド時でも毎回ビルドされていました。
Swift Package Managerに導入することにより毎回ビルドがされなくなるのではと考え導入を行いました。

導入して変わったこと

  • [初回] xcodegen generate後にResolve Packagesが発生 → +30~40秒ほど
  • [毎回] 1回当たりのビルド時間改善 → -5~10秒ほど

上記の結果はPodsを複数Swift Package Managerに移行した合算になります。
移行したものは下記の通りになります。

  • SVGKit
  • Reachability
  • GoogleSignIn
  • Realm
  • AFNetworking
  • Firebase
  • RxSwift
  • RxOptional
  • RxDataSources
  • SwiftyXMLParser

移行したPodsが増えるほど1回当たりのビルド時間は減りますが、Resolve Packagesの時間は増えていきます。
しかしResolve Packagesはxcodegen generate後の初回のみ待てばよいのでトータルではマイナスになっています。

現在の環境

  • Xcode 14.0.1
  • XcodeGen 2.29.0
  • CocoaPods 1.11.3
  • CocoaPodsBinary 0.4.4

導入について

導入の手順

手順は以下の通りとなります。

  1. Podfileから対象のPodの記載を削除
  2. project.ymlのpackages:にPackageを記載
  3. project.ymlのtargets:にPackageを記載

1.Podfileから対象のPodの記載を削除

まず、Podfileから対象のPodを削除します。
Podでバージョンを指定していた場合、Swift Package Managerでも指定するのでメモして下さい。
次にpod installコマンドによりPodfile.lockを更新します。
これによりCocoaPodsで使用していたライブラリが削除されます。

2.project.ymlのpackages:にPackageを記載

Projectで導入するPackageを記載していきます。
まずはXcodeでPackageが提供されているか確認して下さい。
確認手順は以下の通りとなります。

  1. Xcodeを開く
  2. File -> Add Package から Swift Package Managerのウィンドウを開く(画像参照)
  3. ウィンドウ右上の検索窓にURLを記入
  4. 対象のPackageが表示され、プロジェクトに追加できればOK
    スクリーンショット 2022-12-21 12.06.14.png

次に確認したPackageをproject.ymlに記載します。
packages:の配下にPackage名とURL、そしてブランチやバージョン等の指定が必要になります。

project.yml
name: SampleProject
packages:
  Firebase:
    url: https://github.com/firebase/firebase-ios-sdk
    exactVersion: 8.15.0
  GoogleSignIn:
    url: https://github.com/google/GoogleSignIn-iOS
    exactVersion: 6.1.0
  Realm:
    url: https://github.com/realm/realm-swift
    exactVersion: 10.16.0

こちらは備考になります。
Packageのバージョン指定には他の指定方法も行えます。
よく使うであろう記述方法をピックアップしておきます。

project.yaml
exactVersion: 8.15.0 // バージョン指定:8.15.0を指定
maxVersion: 8.15.0 // バージョン指定:8.15.0以下を指定
branch: master // ブランチ指定:masterを指定

他の細かな指定方法についてはこちらを確認して下さい。

3.project.ymlのtargets:にPackageを記載

Targetsで導入するPackageを記載します。
こちらはPackageによってはproduct:の指定まで必要になります。

project.yaml
targets:
    SampleTarget:
        dependencies:
            - package: GoogleSignIn
            - package: Realm
              product: RealmSwift
            - package: Firebase
              product: FirebaseAnalytics
            - package: Firebase
              product: FirebaseMessaging
            - package: Firebase
              product: FirebaseCrashlytics
            - package: Firebase
              product: FirebasePerformance

Packageにどのようなproductが含まれているかはPackage.swiftを閲覧することで確認出来ます。
XcodeのShow the Project NavigatorからPackageを選択することでPackage.swiftを確認することが出来ます。

Realm/Package.swift
let package = Package(
    name: "Realm",
    platforms: [
        .macOS(.v10_10),
        .iOS(.v11),
        .tvOS(.v9),
        .watchOS(.v2)
    ],
    products: [
        .library(
            name: "Realm",
            targets: ["Realm"]),
        .library(
            name: "RealmSwift",
            targets: ["Realm", "RealmSwift"]),
    ],

導入について - 個別編

FirebaseCrashlytics

CocoaPodsで導入している場合、BuildPhasesにスクリプトを記述していると思います。
しかしCocoaPodsからSwift Package Managerに変更することにより書き換える必要があります。

  • TARGESのBuildPhasesを開く
  • RunScriptで行っているスクリプトを書き換える
    • 旧:${PODS_ROOT}/FirebaseCrashlytics/run
    • 新:${BUILD_DIR%Build/*}SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run

XcodeGenの場合はBuildPhasesでの書き換えではなく、project.yml内のscripts:を書き換える必要があります。

まとめ

今後について

1回当りのビルド時間は減らすことが出来ました。
しかしブランチを切り替えてxcodegen generateを走らせた際のResolve Packagesで待たされるのが億劫に感じます。
キャッシュ化が行えないのか調べてみましたが基本的にはライブラリ側がxcframeworkに対応していないと難しそうです。
xcodegen自体から脱却するもありかと思いますので今後はそちらを調べてみようかと思います。

参考

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?