Objective-C
Swift

Objective-CコードからSwiftのクラス/プロトコルを使う方法(フレームワーク開発編)

More than 3 years have passed since last update.

おさらい

Swiftで作成したクラスをObjective-C側で使いたい場合、Objective-Cソースで次のように宣言します。

#import "ProductModuleName-Swift.h"

// 例:#import "MyApp-Swift.h"

そうすることで、SwiftでNSObjectを継承したクラスや@objcを付けたクラスを、Objective-Cから自由に使えるようになります。

// Swift
public class SwiftClass : NSObject { ... } // または @objc public class SwiftClass {}
public protocol SwiftProtocol { ... }
// Objective-C
#import "MyApp-Swift.h"

// ※ "Note that you cannot subclass a Swift class in Objective-C"なので注意
@interface MyClass : NSObject < SwiftProtocol >
@property (nonatomic) SwiftClass *obj;
@end

ポイントは、

  • SwiftではNSObjectを継承するか(クラスの場合)、@objcを付けて宣言する(クラス/プロトコルの場合)
  • Objective-C側で「#import "ProductModuleName-Swift.h"」を記述する

の2点です。Qiitaだと「Objective-CベースのプロジェクトからSwiftのクラスを呼び出す」や「SwiftとObjective-Cの相互利用する際の注意」が参考になりますね。

あと、書籍「開発のプロが教える Swift標準ガイドブック」にも当然載っています(ちょびっと宣伝)。

フレームワーク内で使いたい

それでは、このブリッジの仕組みをフレームワークを作っているときにも活用したい場合、どのように書いたらよいでしょうか?Swiftソース内の記述はよいとして、ProductModuleName-Swift.hをどうやって#importすればいいか、という話です。

何も考えずに、ProductModuleNameにフレームワーク名(Build Settingsの[Packaging]-[Product Module Name]です)を入れてみましょう。

#import "MyFramework-Swift.h"
// → 'MyFramework-Swift.h' file not found.

はい、エラーが出てしまいました。

フレームワーク名を入れているにもかかわらず、「そのようなファイルは存在しない」と怒られています。とはいえこのファイルは自動的に生成されるファイルで、ないと言われても何かできるわけでもなく、困ってしまいますね。

この場合、次のように書けばオッケーです。

#import <ProductName/ProductModuleName-Swift.h>

// 例:#import <MyFramework/MyFramework-Swift.h>

フレームワークのProduct Module Nameだけを記述するのではなく、他のフレームワークをインポートするときと同じように、Product Name(これもBuild Settingsの[Packaging]にあります)との組み合わせで書く必要があるわけです。

まとめ

Swiftで定義・宣言したクラスやプロトコルをObjective-Cから使いたい場合、次のポイントを守れば自由に使えます。

  • Swiftソースでは、NSObjectを継承するか@objcを付けるかして、Objective-Cに公開することを明示する
  • Objective-Cでは、どこで使うかによってインポートするときのパスを変える(下表)
条件 書き方
同じアプリターゲット #import <ProductModuleName-Swift.h>
同じフレームワーク #import <ProductName/ProductModuleName-Swift.h>

今自分が見ているソースで何を作っているか、で使い分けるわけですね。

参考サイト

Appleの「Using Swift with Cocoa and Objective-C」だと、「Mix and Match」の「Swift and Objective-C in the Same Project」に載っています。