Edited at

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

More than 5 years have 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のサブクラスにする!