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」に載っています。