Swift Package ManagerでObjective-Cを扱うには
昨今Objective-Cでアプリの新規開発をすることはないと思いますが、長年メンテナンスされてきたアプリのリファクタリングなどでObjective-C製のアプリを触ることがあるかもしれません。
また、現代のiOSアプリ開発において、パッケージ管理の方法もSwift Package Manager(以下、SPM)が主流となっています。
そこで、Objective-CコードをSPMで管理する際に注意すべきTipsを備忘録がてら記載します。
Swiftと混在できない
最初の注意点として、Objective-CファイルとSwiftファイルをひとつのターゲットとして管理することはできません。
例としてMixedProductというライブラリについて考えます。
MixedProductライブラリはSwiftとObjective-Cで書かれた実装に依存していることを仮定します。
let package = Package(
name: "MixedProduct",
products: [
.library(
name: "MixedProduct",
targets: ["MixedProduct"]
)
],
targets: [
.target(
name: "MixedProduct",
dependencies: ["SwiftModule", "ObjCModule"]
),
.target(
name: "SwiftModule"
),
.target(
name: "ObjCModule"
)
]
)
本来であれば、ひとつのターゲットとして管理したいところですが、ファイルの混在が許されていないため、別々のターゲットをそれぞれSwiftコードを格納しているSwiftModuleとObjective-Cコードを格納しているObjCModuleとして定義しています。
MixedProductは、いずれのターゲットもdependenciesとして受け入れることができます。
もちろん、MixedProduct自体はSwiftでもObjective-Cでも構いませんが、これまで書いてきた通り、どちらかに統一しなければなりません。
上の例では母体となるMixedProductがSwiftModuleとObjCModuleをdependenciesとして定義していますが、状況によってはSwiftModuleがObjCModuleを引き受けても構いません。
ただし、お互いのターゲットが参照し合うことはできず、下記のエラーでパッケージを読み込むことはできません。
cyclic dependency declaration found: SwiftModule -> ObjCModule -> SwiftModule;
includeディレクトリ
Objective-CのコードをSPMで管理する際にはヘッダーファイルをincludeディレクトリに格納する必要があります。

Animalというパッケージを作ったとすると、その配下にincludeディレクトリを作成します。
そして、ヘッダーファイルはincludeディレクトリに格納し、実装ファイルはAnimalディレクトリ直下に配置していきます。
これは SPMがincludeという名前のディレクトリにあるヘッダーを自動的に公開するからです。
Swiftをヘッダーファイルにインポートする
Objective-CファイルではSwiftで記述されたパッケージを@import ModuleSwiftと記述することでインポートが可能です。しかし、ヘッダーファイルへのインポートがうまく動作しないことがあります。
そもそもまずは、
- Swiftパッケージ内のSwiftクラスが、
@objc属性でマークされていること - Swiftパッケージ内のSwiftクラスが、
publicであること -
Bridging-Header.hの設定
を確認していただきたいのですが、それでもコンパイルできない場合にはxcconfigに下記を追加することで解決します。${YOUR_SWIFT_MODULE}を適宜変更して利用してください。
OTHER_SWIFT_FLAGS = -Xcc "-fmodule-map-file=${OBJROOT}/GeneratedModuleMaps-${PLATFORM_NAME}/${YOUR_SWIFT_MODULE}.modulemap"
これは明示的に特定のmodulemapを読み込むことで、リンクの解決を図りインポートが成功します。
参考: https://forums.swift.org/t/swift-cant-see-objc-methods-that-include-package-symbols/65732/9
おわり
以上です。
他にも遭遇したら追記します。
誰かの参考になれば幸いです。
Discussion