SwiftからObjective-Cメソッド/C関数を呼ぶ

SwiftからObjective-Cメソッドを呼ぶ

macOS Mojava 10.14.6 / Xcode 11.3.1 / Swift 5.0
SwiftからObjective-Cのインスタンスメソッドを呼ぶ方法について説明する。
Objective-Cのクラスにインタフェースの異なる複数のインスタンスメソッドを実装し、Swiftから呼び出してみる。Objective-C と Swift では型の体系が異なるので、引数と戻り値の扱いには適切な型変換が必要となる。自動的に型変換がなされる場合と、明示的にキャストが必要な場合がある。

ブリッジング・ヘッダファイルの作成

Objective-Cクラスのヘッダファイルへの参照を記述する。
ファイル名はプロジェクト名 + "-Bridging-Header.h" とする。これがないと Objective-Cクラスの認識ができずコンパイルができない。

引数と戻り値の型がNSString型のメソッド

引数の文字列のアルファベットを大文字にして返す。Swift の String型と Objective-C の NSString型の変換は自動的に行われる。戻り値はオプショナル型になる。

引数と戻り値の型が NSInteger型のメソッド

引数の値を2倍にして返す。Swift の Int型と Objective-C の NSInteger型の変換は自動的に行われる。

引数と戻り値の型が NSNumber型のメソッド

上記と同じ仕様の数値を扱うメソッドだが、引数と戻り値をNSNumber型とする。
Int型とNSNumber型の間の明示的な型変換が必要となる。

引数と戻り値を配列にしたメソッド

引数で渡された配列の要素の数値を10倍にして返す。
要素の型を指定しないレガシーな配列宣言の場合、要素の型はSwifの「Any」と同じようなものになる。引数の配列の要素にInt型の値を代入すれば、型の推論によりメソッドに渡るときには自動的にNSNumberオブジェクトに変換される。また戻り値の配列の要素もNSNumberオブジェクトになるので取り出すときは明示的にInt型にキャストする。
なお、配列の要素の型をジェネリックとして NSNumber型にすると、引数の要素を明示的にキャストしなくてはならないので面倒。

SwiftからC関数を呼ぶ

SwiftからC関数を呼ぶ方法を一例だけあげる。
Objective-Cの場合と同じようにブリッジング・ヘッダファイルを作成する。

関数の定義

引数に渡された文字列のアルファベットを大文字に変換する。引数は char型の配列とし、要素の文字を直接更新する。

Swiftから呼び出す

文字列をC関数の引数に指定するためには、Swift文字列(Stringオブジェクト)を char型の配列に変換する必要がある。以下の関数で行っている。
SwiftからC関数を直接呼ぶのではなく、Objective-Cにラップしたメソッドを呼ぶこともできる。この方法であれば Objective-Cは Cとの親和性があるので 文字列(NSStringオブジェクト)を char型の配列に変換するのが一文で済む。
NewPractice_Swift/19_0bjcCall