🛠️

Xcode 16: Local Swift Packageの仕様

2024/12/27に公開

Local Swift Packageを使った開発をしていて、Xcode 16へのマイグレーションで躓いたポイントを記録しておきます。

Local Swift Packageの構成の仕方は2種ある

  • プロダクトコードの一部として取り込む(InternalPackage1)
  • Package Dependenciesの一つとして参照する(InternalPackage2)


Local Swift Package2種

前者はTest PlanにPackage内のテストを指定することができますが、後者はできないという違いがあります。(3rd Party製のものとは違い、ソースコードをXcode上で直接編集できるという部分に差はありません。)

プロダクトコードの一部として取り込む手順

Package.swiftの入っているディレクトリをプロジェクトのソースツリーにドラッグ&ドロップすれば取り込めます。



Package Dependenciesの一つとして参照する手順

プロジェクトのメニューからAdd Package Dependencies…を選択して流れに沿えば参照できます。





Local Swift Packageの読み込みはそのパッケージがどこにあるかで読み込み方が変わる

以下のようなディレクトリ構造があったとします。

.
├── LocalPackage-A
│   └── Package.swift
└── LocalPackage-B
    ├── Package.swift
    └── Demo
        ├── LocalPackage-C
        │   └── Package.swift
        ├── Package.swift (ダミーで必要)
        ├── AppProject
        └── AppProject.xcodeproj
Local Package 読み込み可否 備考
LocalPackage-A パッケージのアイコンに矢印がつく
LocalPackage-B 不可
LocalPackage-C


パッケージのアイコンの違い

仕様をまとめると

  • xcodeprojと並列階層にあるローカルのパッケージは普通に読み込める
  • xcodeprojの上位階層にあるローカルパッケージは自分自身を含むので読み込めなくなった?
    • Xcode 15まではダミーのPackage.swiftがあれば読み込めた
  • xcodeprojを含まない、かつ並列階層でないディレクトリにあるローカルパッケージは読み込めるが、シンボリックリンクのような矢印がアイコンにつく

といったところでしょうか。

この新しい仕様だと、Swift Package ManagerでOSSライブラリを配布する場合にリポジトリ内にXcode Projectを含めてそこからライブラリのPackageを読み込むというスタイルがやりづらくなりました。残念です。が、そもそもSwift Package Managerで3rd PartyのライブラリをFetchする際に余計なデモプロジェクトのソースコードまで入ってくること自体がちょっと微妙だったので、Apple的にはデモプロジェクトは別リポジトリにしてねという意思表示なのかもしれません。

それでもOSSライブラリのリポジトリにデモプロジェクトを含めたい場合

xcodeprojの上位階層にあるローカルパッケージが読み込めないだけなので、一度デモプロジェクトとライブラリのディレクトリを独立した場所に移してデモプロジェクトでライブラリを読み込んだ後、ディレクトリ構造を元に戻して、テキストエディタでproject.pbxprojを編集して参照するパスを書き換えてあげれば動きはします。ただ、この場合はダミーのPackage.swiftが必要になりますので忘れずに追加してください。

/* Begin PBXFileReference section */
-    1CD5D7752D1E78990088B889 /* SomePackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = SomePackage; path = /Users/user/Desktop/SomePackage; sourceTree = "<absolute>"; };
+    1CAF1DBB2D1E6D4800189DE0 /* SomePackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = SomePackage; path = ..; sourceTree = "<group>"; };
/* End PBXFileReference section */

Discussion