はじめに
みなさん、こんにちは。
iOS / tvOSアプリデペロッパーのhiroakitです。
この記事ではSwiftでCあるいはC++で書かれたライブラリを利用する方法についてご紹介いたします。
この記事の執筆時に使用した開発環境は以下の通りです。
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.12.6
BuildVersion: 16G1114
$ xcrun -find xcode build
/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild
$ xcodebuild -version
Xcode 9.2
Build version 9C40b
$ xcrun -find clang
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
$ clang --version
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
動機
Cライブラリ (e.g, OpenJPEG) をSwiftのフレームワークにして利用したいことがあると思います。
この記事では説明用に以下のCのライブラリで進めたいと思います。
- libExample.a
- include/Example.h
- include/ExampleEncoder.h
このライブラリをSwiftで書かれたアプリがフレームワークでインポートして利用したいとします。
import UIKit
import Example
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
ExampleEncoder.run(urlString: "https://www.example.com/", profile: "path/to/profile")
}
}
この場合、CライブラリをSwiftでラップしてフレームワークにするときに、 下記のように .modulemap
ファイルを用意する必要があります。
framework module Example {
umbrella header "Example.h"
export *
module * { export * }
header "ExampleEncoder.h"
}
このExample.frameworkをアプリ側で追加したら、そのフレームワークのパスをXcodeプロジェクトの下記設定項目に設定する必要があります。
- FRAMEWORK_SEARCH_PATHS
- LIBRARY_SEARCH_PATHS
.modulemap
ファイルとは
.modulemap
ファイルとはCライブラリで利用しているヘッダーファイルをClang Modulesを通じてSwiftに伝えるために必要なものです。
以下は.modulemap
ファイルの形式を示したものです。module map言語を使い記述します。
[explicitopt] [frameworkopt] module module-id attributesopt {
/* module-member */
}
なお、module map言語はClangのメジャーバージョン間で動作保証がされていません。そのため、Xcodeが内包しているClangのメジャーバージョンが変わった場合、この辺りの動作について開発者の意図通りになっているか確認する必要があります。
The module map language is not currently guaranteed to be stable between major revisions of Clang.
まとめ
modulemapを用意することでCライブラリをSwiftで利用する方法についてご紹介しました。
modulemapは一発でうまくいかないこともあるので、その辺りの覚悟とセットでご用意ください。
参考資料にmodulemapの例を記載しました。
参考資料
- IBM-Swift/CommonCrypto
- IBM-Swift/OpenSSL
- [CommonCrypto-60118.1.1 - Apple Open Source] (https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60118.1.1/include/module.modulemap.auto.html)