[Xcode/Swift] Carthage & CocoaPodsからSPMへの移行作業フロー

最近プロジェクトのSPM移行作業をやっているので、移行作業のフローを備忘録として残しておく。

対象はCarthageとCocoaPodsで管理してるライブラリ、というかそれ以外で管理してることはあんまりない気もするが。

移行作業

Carthage

作業対象のファイル

  • Cartfile
    • 不要なライブラリの宣言を削除
  • Cartfile.resolved
    • 同上
  • Carthage/Build
    • 対象のフォルダを削除

削除後、SPMに置き換えたいライブラリをXcode → File → Add Package Dependenciesから追加してプロジェクトに入れる

Buildターゲットからの削除

General → Frameworks, Libraries, and Embedded Contentから、SPMに置き換えたライブラリの.framework (.xcframework)を削除する

また、Build Phase → Link Binary With Librariesにも残骸が残っていたらそっちも消しておく。(↑の処理を先にしたらこっちは残らないはずだが一応確認しておくのがベター)

動作確認

Command + Shift + Kでビルドクリーン、rm -rf ~/Library/Developer/Xcode/DerivedData/*でキャッシュ諸々削除しておく

Command + B (or R)、テストファイルもあるなら一応Command + Uも実行して成功することを確認、問題なければ差分をPushしておけば移行作業完了


CocoaPods

作業対象のファイル

  • Podfile
    • SPMに移行したいライブラリの宣言を削除
  • Podfile.lock
    • 整合性を完璧にするため、Podfile.lockPods/ ディレクトリを一旦ゴミ箱にGOしておく。
      • rm -rf Podfile.lock Pods/

削除後、pod install or pod update(Podfile.lockを削除してないなら)で、Podの管理から対象のライブラリが消えていることを確認。

Carthageと違って、PodはFrameworks, Libraries, and Embedded Contentから自動で消えるので、移行したいSPMをそのまま取り込めばOK

動作確認

Command + Shift + Kでビルドクリーン、rm -rf ~/Library/Developer/Xcode/DerivedData/*でキャッシュ諸々削除しておく

Command + B (or R)、テストファイルもあるなら一応Command + Uも実行して成功することを確認、問題なければ差分をPushしておけば移行作業完了


移行にクセがある?ライブラリ

↑で書いたフローだけではビルドがすんなり通らないケースもあったので、ざっくりメモしておく。

メジャーアプデしてるライブラリ

Carthage (or Pods)ではv1系を使ってて、SPMでv2系になったみたいなパターン。

今の記法ではビルドエラーになったり、他に必要な依存パッケージが必要なものが出てきたら、公式のリポジトリを見てよしなに直す。

  • FloatingPanel
  • RealmSwift
  • ZipArchive

このあたりを使ってるならもしかしたらこれが当てはまるかも。

ウィジェットとかTestターゲットでもそのライブラリを使ってる場合

プロジェクトがウィジェット対応してたり、Testターゲットでライブラリを使ってたりするとビルドが通らなくなる。

なのでそっちにもGeneral → Frameworks, Libraries, and Embedded Contentにライブラリが入ってるかを確認して入ってなかったら入れておくとビルドが通る (はず)

Firebase関連

Carthage, Pods時代はFirebaseの各機能ごとに宣言して入れていたが、SPMからは一個のパッケージでまとめて必要な機能をターゲットに追加することになる。

Firebase DynamicLinkは2025年にサ終したのでSPMパッケージ対象にDynamicLinkは入ってない。

なのでDynamicLink関連は完全デッドコードになってる部分を削除しておくのが無難かも。

(昔のユーザがDynamicLink導線で入ってくるケースを考慮したとしても、そもそもサ終してるので削除自体は問題ない気もする)


まとめ

以上、CocoaPodsとCarthageからSPMへの移行フローをざっくりまとめ。

プロジェクトがレガシーなら100%完全移行は難しいケースが多いので、移行の際は以下のステップで向き合うのがよさそう。

  1. 移せるものは迷わずSPMへ
    • Firebaseなどの大手SDKや、メンテナンスが続いているライブラリは最優先で移行。パッケージ管理をXcode標準に寄せるだけで、ビルド速度や設定の複雑さはかなり解消される (はず)
  2. レガシーライブラリは「自作」を検討
    • 「数年前は便利だったが、今はSwiftの標準API(URLSessionAsync/Await など)で数行で書ける」というライブラリも多い。移行を機に、ライブラリ依存をやめてネイティブ実装に書き換えるのが最もクリーンな解決策
  3. どうしても無理なら「共存」も視野に
    • どうしても外せないレガシーがあるなら、無理にSPM化を急いでビルドエラーの沼にハマるより、そこだけPods/Carthageに残して「段階的に減らしていく」という判断がベター