外部ライブラリをラップするライブラリを作成して社内で使いまわすということをWindowsやAndroidでは当然のようにやってきたのですが、iOSでは簡単にできない場合があります。それはObjective-Cで書かれたライブラリをSwiftのFrameworkでラップする場合です。
FrameworkでObjective-CのFrameworkの組み込み時にエラー
error: using bridging headers with framework targets is unsupported
プロジェクトにObjective-Cで書かれたFrameworkを組み込む場合、Bridging Headerを追加して参照できるようにします。Frameworkで同じようにするとエラーが発生してビルドできません。エラーメッセージそのままですが、FrameworkではBridging Headerが使えないようです。
ググってもObjective-CのFrameworkを修正する方法ばかり
ではどうやって組み込むのかどうか、ググって調べてもObjective-CのFrameworkを修正してビルドし直すという方法ぐらいしか見つかりませんでした。しかし、今回のFrameworkはサードパーティー製でソースコードは手元になく修正はできません。
FrameworkでObjective-CのFrameworkを組み込む
module.modulemapを作成する
そこでmodule.modulemapを追加修正することで対応します。Frameworkは実態はただのフォルダなので中身を開くことができます。今回使用していたFrameworkの中身はこうなっていました。
ここにModulesというフォルダを追加します。
そしてこのModulesフォルダの中にmodule.modulemapというファイルを新規で作成します。
Bridging Headerでimportしているヘッダーファイルを追加する
続いてmodule.modulemapに参照するヘッダーファイルを指定します。指定するのはBridging Headerでimportしているヘッダーファイルです。Bridging Headerの指定方法は基本的に外部ライブラリ開発元が公開しているはずなので、そちらを参照してください。例えばBridging Headerは下記のようになっていた場合、
#ifndef FrameworkName_Bridging_Header_h #define FrameworkName_Bridging_Header_h #import <FrameworkName/Header.h> #endif /* FrameworkName_Bridging_Header_h */
module.modulemapは下記のようになります。
framework module FrameworkName { umbrella header "Header.h" export * module * { export * } link framework "FrameworkName" }
Bridging Headerでimportしているヘッダーファイルが複数の場合
module.modulemapで指定できるヘッダーファイルは1つだけです。このため、もしBridging Headerは下記のようになっていた場合、
#ifndef FrameworkName_Bridging_Header_h #define FrameworkName_Bridging_Header_h #import <FrameworkName/Header1.h> #import <FrameworkName/Header2.h> #import <FrameworkName/Header3.h> #endif /* FrameworkName_Bridging_Header_h */
この3つのヘッダーファイルをimportするヘッダーファイルを新規で作成する必要があります。
framework module FrameworkName { umbrella header "Header.h" export * module * { export * } link framework "FrameworkName" }
module.modulemapを同様に作成して、「Versions/A/Headers/」の中にmodule.modulemapで指定したHeader.hを新規で作成して下記のように中身を書いておきます。
#import <Foundation/Foundation.h> #import <FrameworkName/Header1.h> #import <FrameworkName/Header2.h> #import <FrameworkName/Header3.h>
これでBridging HeaderなしでFrameworkをビルドできるようになります。当然Framework内のソースコードから外部ライブラリを参照できるようになります。