とりあえず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のクラスが見つからずコンパイルエラーになります。
let objcObj = MyObjCObject() // コンパイルエラー
早速ここでハマったのですが、Swift内でクラスを解決するためには上記で追加されたファイルに
import文を書く必要があります。
#import "MyObjCObject.h"
こうすることでSwift内でObjCのクラスを呼び出すことができるようになります。
let objcObj = MyObjCObject() // 今度は通る
逆に言うとSwift内で利用したいObjCのクラスはすべて上記ヘッダーファイルにimport文を書かなければなりません。
ダイアログで設定変更するとこのヘッダーファイルが追加されていることに気づかなくてハマりました・・・・
Objctive-Cの中でSwiftのクラスを利用する
今度は逆にObjCのなかでSwiftのクラスを使います。
こちらは簡単で<# ProductName #>-Swift.hというファイルが自動生成されるのでそれをimportするだけです。
#import "ProductName-Swift.h"
が、使おうとするとまたしてもコンパイルエラーになりました。。。
MySwiftObject *swiftObj = [MySwiftObject new]; // コンパイルエラー
今度はなんでだ!とここでまたハマったのですが、
ObjCで利用したいSwiftクラスはNSObjectのサブクラスである必要が有ることがわかりました。
NSObjectのサブクラスでないと上記自動生成のヘッダーファイルに宣言が現れません。
class MySwiftObject: NSObject {
// implementation
}
こうすることでObjC内でSwiftのクラスが利用可能になりました。
MySwiftObject *swiftObj = [MySwiftObject new]; // 今度は通る
まとめ
自分だけかもしれませんが下記の2つを忘れないように注意しましょう!
- <# ProductName #>-Bridging-Header.hにimport文を書く!
- SwiftのクラスはNSObjectのサブクラスにする!