寄付窓口はこちら

SwiftのアプリでCやC++、Objective-Cのフレームワークを使おう | try! Swift Tokyo 2019 1-13

Swiftは強力で、また、比較的新しい言語です。世の中にはC言語や、C++Objective-Cで書かれたオープンソースライブラリが多くあります。ユニークなアプリを作るチャンスを3倍にするために、これを利用する手はないのでしょうか? あります! このトークでは、C、C++Objective-Cの関係性を説明するための基本をなぞり、SwiftのプロジェクトにDependencyを追加する方法をデモします。

f:id:niwatako:20190321163737j:plain

[f:id:niwatako:20190321163912j:plain

Spotifyというかなり大きなコードを扱っています。その中にはC, Objective-C, C++など多くのコードが含まれています。

f:id:niwatako:20190321163944j:plain

Cがうまれ、組み込みなどに使われていました。クラスやオブジェクトに対応していませんでした

C++をつくりC拡張でObjectOrientedProgramingをサポートしました。

Objective-CC++と同じ時期に生まれましたが、Cの上に薄いレイヤーが乗っているという形です。

ソースファイルをコンパイルするように

.mmファイルを見たことがある人

Swiftは2014年に生まれました、Cocoaと作業できるように生まれてきた。ObjectiveCの多くを使える。ランタイムライブラリも使っている。1つのプログラムで走ることができる。

SwiftはCとダイレクトにコミュニケーションすることができる。C++とダイレクトにコミュニケーションは出来ない。

4言語のコネクションが話してみたら面白いと思いました。

f:id:niwatako:20190321164156j:plain

生花のようです

f:id:niwatako:20190321164219j:plain

使うものを選んだら、配置していく

アプリケーションはゴールを考え、ふさわしいライブラリを選んでくる。目的はプレゼンテーションなり、枝や花を選んでくるが、これはCやObjC,C++ということになります。

おかしなところや足りないことがあれば補足していく。

これで一歩下がって全体を見ていく

f:id:niwatako:20190321164317j:plain

ObjCフレームワークを足すとき、バニラObjCというフレームワークを使ってきました。サードパーティのものも扱っていく必要がありますがセットアップは似ています。

Xcodeproject、あるいはFrameworkをリンクする。

SwiftClassでVanillaObjCをImportする

randmStringをコールする

これで全部が出来上がる

C++

f:id:niwatako:20190321164430j:plain

libBasicCppLibを作っています。

ダイレクトにはコミュニケーションできないので間にObjective-Cを挟まないといけない

ラッパーをmから.mmに名前を付け替え、C++Objective-Cを両方コンパイルできるように成る。

Objective-Cフレームワークの中でリンクしてモジュールをインポートしてObjectiveCのファンクションをコールする

CはStaticLibとしてコンパイルされる

f:id:niwatako:20190321164552j:plain

randomStringのみです

自動的にヘッダーファイルを読むわけではない。Cのヘッダーは読めない。

module map というファイルを作成する

f:id:niwatako:20190321164652j:plain

Headerを加えていく、exportするとサブモジュールの中身すべてがexportされる

モジュールマップのディレクトリに対してSWIFT_INCLUDE_。。。を指定する

依存関係を指定できました

f:id:niwatako:20190321164739j:plain

Objective-CはSwiftにトランスレーションしやすい

C++はCを使わなくてはいけない、でもインターフェースがデベロッパーフレンドリーでない

フレンドリーに、詳細を省くために、ラッパーを使うということに成る

f:id:niwatako:20190321164831j:plain

古いObjecitve-CがあればNS_SWIFT_NAMEで名前を変換する必要がある

Cはまた別物

ポインタがあります。

f:id:niwatako:20190321164903j:plain

値を指定しているのではなく先頭のアドレスを挿しています。

Swiftからは安全ではない、Cライブラリにどのようにポインタのメモリが管理されているかわからない

f:id:niwatako:20190321164957j:plain

これで全く終わりかと言うとそうではない、間違っている場所がある、マニュアルメモリ管理が必要

randomString functionでメモリを開放する必要がある。ありやすいやり方がある。

f:id:niwatako:20190321165024j:plain

Int → Int32にはtype castが必要

f:id:niwatako:20190321165104j:plain

f:id:niwatako:20190321165119j:plain

Closureのタイプキャスト

f:id:niwatako:20190321165239j:plain

コンテキストをキャプチャするローカル関数からは形成することは出来ない

コンテキストは一連のすべての変数

クロージャー、ローカルファンクションの中でSwiftにおいては別の変数を含んでいます。

コンテキストキャプチャリングをするのは、コンパイラは、アウターファンクションの中で使われているものを使うということになります。

SwiftではどれくらいC関数をクロージャーの中にホールドしておくべきかわからないので、キャプチャされたコンテンツを許可しない

f:id:niwatako:20190321165414j:plain

そこでコントロールが必要になる

getNextValueのライフタイムを管理してやる必要がある。

f:id:niwatako:20190321165439j:plain

最後に C++

Cから学んだことをそのまま使えます

f:id:niwatako:20190321165504j:plain

NSStringはCStringを通って、C++Objective-Cの間に存在する

f:id:niwatako:20190321165522j:plain

一つのパラメータをとってくる、ラップするためにObjCの中でラッパークラスを作ります。

f:id:niwatako:20190321165608j:plain

f:id:niwatako:20190321165611j:plain

プロセッサーのマクロの部分ですが、これはC、それからC++、ObjCで使われているます

f:id:niwatako:20190321165643j:plain

そしてタイプを指定して上げる必要がある

そして、Swiftだけのライブラリにこれを限定する必要はなく、C++、ObjCで使っていくことが可能

f:id:niwatako:20190321165732j:plain