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