詳細は公式ドキュメント「Swift and Objective-C in the Same Project」を参照。
今後、SwiftとObjective-Cでの相互連携が当たり前になっていくのだと思います。
てなわけで、それぞれのファイルで定義したクラスにアクセスする方法をメモしておきます。
結論から書くと、それぞれBridgeとなるファイルが生成され、そこを経由してやりとりする、というのがおおまかな流れになります。
[追記]
Swiftで宣言されたprotocolをObjC側で利用する
Swiftでただ宣言しただけではブリッジ用のファイルに書き出されないため、ObjeC側で利用できません。
@objc
をつけて宣言する必要があります。
@objc protocol Hoge {
var name: String?
func fuga()
}
利用するときは型にProtocol名をそのまま使います。
var aHoge: Hoge?
NSObjectを継承していないクラスをObjective-C側で利用する
Swift側でNSObject
を継承をさせると、自動的にブリッジとなるファイル<#ProductName#>-swift.h
ファイルが生成されます。
が、逆を返せばNSObject
を継承していないSwiftのクラスはそのブリッジのファイルに書きだされません。
しかし、@objc
attributeを利用すればNSObject
を継承していなくてもObjective-C側から利用することが可能になります。
具体的には以下。
@objc(SomeClass)
class SomeClass {
// ファクトリメソッドを定義しておく
class function create() -> SomeClass {
return SomeClass()
}
func doMethod() -> () {
println("Perform a method!")
}
}
// Objective-C側での利用
SomeClass *someClass = [SomeClass create];
// インスタンスメソッドも呼べる
[someClass doMethod];
Objective-C内でSwiftで定義したクラスを利用する
Objective-C側でSwiftで定義されたクラスを利用するには、Xcodeが自動生成するProjectName-Swift.h
ファイルをimportします。
あとは普通にObjC側から、Swiftで定義したクラスを利用することが出来ます。
import UIKit;
class TestView: UIView {
init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.greenColor()
}
}
#import "ObjcViewController.h"
// Swift側の定義を読み込む
#import "ProjectName-Swift.h"
@interface ObjcViewController ()
// Swiftで定義したUIViewクラスを保持
@property (nonatomic, strong) TestView *testView;
@end
@implementation ObjcViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.testView = [[TestView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:self.testView];
}
@end
Swift内でObjective-Cで定義したクラスを利用する
今度は逆のパターンです。
Swift内で、Objective-Cで定義したクラスを利用する方法です。
こちらのケースの方が多いのではないでしょうか。
さて、こちらもブリッジとなるヘッダファイルを介して利用します。
ただし、こちらの場合は、Swiftプロジェクト内にObjCファイルを生成しようとすると、ProjectName-Bridging-Header.h
を生成しますか? と聞かれ、「はい」と答えると生成されるようです。
このヘッダファイルに、Swift内で使用したいObjective-Cクラス用のヘッダファイルをimportさせます。
#import "ObjcViewController.h"
比較的簡単に連携できそうなのでSwiftも問題なく使えるんじゃないでしょうか。
今から楽しみです。