ゴール
自作Swiftフレームワークから、別のObjective-Cライブラリを参照できるようにする。
※例えばObjCで作った自作ライブラリを新たにSwift Frameworkで使い、そのSwift frameworkをアプリで利用するようなケースを想定。
※管理が面倒なので言語別になにかを用意するとか、言語ごとに参照するファイルが違うとかは無し。
利用するもの
Clang Modules
http://clang.llvm.org/docs/Modules.html
modulemap言語というものを利用し、headerをbinary形式にプリプロセスしたもの。
依存関係なども記述できるが、ここの記述でheaderの公開設定などをするのは実用的ではなさそう。
explicit修飾子という明示的importを強制する修飾子をつけてもコード候補には上がってしまう。
今回対象外のもの
Objective-c static library
headerの解釈がSwiftから利用できないため不採用。
ただしStatic Framework化すると利用できます。
※Dynamic Framework化しても良い
Bridging Header
ObjC libraryをSwift Frameworkから参照しようとする場合はBriging Headerを作ってもライブラリの利用はできません・・・。
サンプル
2つのObjC Static libraryをSwift frameworkに包む方法。
- static libraryを2つ作る。
- 2つともstatic frameworkにする。
- 各static frameworkのumbrella headerをmoduleとして宣言したmodule.modulemapファイルを作成する。
4. それぞれのframework内にModulesフォルダを作成し配置
5. 各static frameworkのumbrella headerを包んだumbrella headerを作成する
6. 5.でつくったumbrella headerのmodule.modulemapファイル(umbrella module)を作成する
※__has_includeマクロを仕込むといいみたい。
7. 5.6.で作ったumbrella frameworkおよびumbrella module、frameworkを以下のように配置する
8. 利用するprojectに各frameworkおよび,umbrella module, umbrella header(framework.h)をimportする。
9. user header search pathにumbrella headerのpathを指定
10. Swiftで利用する場合のみSwift compilerのimport pathにumbrella moduleを指定
完成
framework同士に依存関係がなければ必要なものだけをまとめSDKとなる。
備考
内包するObjC frameworkはdynamic frameworkでも可能。ただしdynamic frameworkを含む場合は、最終的に利用するアプリでObjC frameworkを含む全ての内包しているframeworkを直接参照していなくてもembedded frameworkとして定義する必要がある。
これはswift frameworkとObjC frameworkがstatic linkではないためである。
注意点
いわゆるumbrella frameworkなので、framework内で外部のframework(自分でupdateできないもの)を含むことはオススメしない。ある程度知識があっても、ハマりやすいポイントは多く、気が付きにくい。
あくまで自作のまとめ程度がよい。