Help us understand the problem. What is going on with this article?

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のサブクラスにする!
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away