SwiftとObjective-Cの相互利用する際の注意

  • 189
    Like
  • 0
    Comment
More than 1 year has passed since last update.

とりあえずObjCとswiftを相互利用する時にいくつかハマったので書きたいと思います。

ちゃんとここ読んでいればわかることなんですが
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/

Swiftの中でObjective-Cのクラスを使う

SwiftのプロジェクトでObjCのファイルを追加しようとするとXcodeがダイアログを出し、
プロジェクトの設定を変更してSwiftとObjC間の連携ができるようにしてくれます。

具体的に以下の様な設定変更をします。

  • プロジェクトに <# ProductName #>-Bridging-Header.h という名前のファイルを追加
  • Build SettingsのObjective-C Bridging Header に上記ファイル名を設定

そしてSwiftで作成したObjCのプロジェクトを利用しようとするとObjCのクラスが見つからずコンパイルエラーになります。

Swift
let objcObj = MyObjCObject() // コンパイルエラー

早速ここでハマったのですが、Swift内でクラスを解決するためには上記で追加されたファイルに
import文を書く必要があります。

#ProductName#-Bridging-Header.h
#import "MyObjCObject.h"

こうすることでSwift内でObjCのクラスを呼び出すことができるようになります。

Swift
let objcObj = MyObjCObject() // 今度は通る

逆に言うとSwift内で利用したいObjCのクラスはすべて上記ヘッダーファイルにimport文を書かなければなりません。

ダイアログで設定変更するとこのヘッダーファイルが追加されていることに気づかなくてハマりました・・・・

Objctive-Cの中でSwiftのクラスを利用する

今度は逆にObjCのなかでSwiftのクラスを使います。
こちらは簡単で<# ProductName #>-Swift.hというファイルが自動生成されるのでそれをimportするだけです。

Objective-C
#import "ProductName-Swift.h"

が、使おうとするとまたしてもコンパイルエラーになりました。。。

Objective-C
MySwiftObject *swiftObj = [MySwiftObject new]; // コンパイルエラー

今度はなんでだ!とここでまたハマったのですが、
ObjCで利用したいSwiftクラスはNSObjectのサブクラスである必要が有ることがわかりました。
NSObjectのサブクラスでないと上記自動生成のヘッダーファイルに宣言が現れません。

Swift
class MySwiftObject: NSObject {
// implementation
}

こうすることでObjC内でSwiftのクラスが利用可能になりました。

Objective-C
MySwiftObject *swiftObj = [MySwiftObject new]; // 今度は通る

まとめ

自分だけかもしれませんが下記の2つを忘れないように注意しましょう!

  • <# ProductName #>-Bridging-Header.hにimport文を書く!
  • SwiftのクラスはNSObjectのサブクラスにする!