🍎

Objective-CでSwiftファイルを読み込むには?

2021/11/12に公開

Objective-CのプロジェクトでSwiftファイルの定数を使う場面があり、詰まったのでメモも兼ねて手順を記事にしてみました!

今回やりたいこと

今回やりたいことしては、Objective-Cのプロジェクトでボタンを押した時にSampleという文字列ではなく、Swiftで定義してあるhelloTextという定数のHello World!を表示させたいです。

1.プロジェクトのBuildSettingsを設定する

まずは画像のように、BuildSettingsのDefines ModuleをNo(デフォルト設定)から Yes に変えます。
Defines Moduleを直訳すると、モジュールの定義という意味になります。これは、フレームワークのヘッダーと一緒にmodule.modulemapファイル(場合によってはmodule.private.modulemap)をインストールするようXcodeに指示するためです。
Swift コードを使用したいObjective-C の .m のファイルには、必ずSwift コード用に Xcode が生成したヘッダファイル(SampleProject1-Swift.h)を import する必要があります。Xcodeで生成されたヘッダーファイルをインポートすることで、プロジェクトのObjective-Cコード内からSwiftで宣言された型を扱うことができるようになります。
これにより、後に説明するSampleProject1-Swift.hファイルが生成され、使えるようになります。

2. 既存のSwiftファイルを書き換える

Swiftファイルのクラス・定数&変数はObjective-Cファイルではそのまま使えません。
少し手を加えてあげる必要があります。

やりたいことを、もう一度確認!
今回やりたいことしては、「ボタンを押した時にSampleという文字列ではなく、Swiftで定義してあるhelloTextという定数のHello World!を表示させる」ということです。

storyboard側

前提として、storyboard側ではIBOutletでそれぞれ、textLabelとbuttonをつなげてあります。

Swiftファイル側

まず、クラスに@objcMembersをつけるか、メソッドの前に @objc をつけておく必要があります。
今回は定数を扱うので、@objcMembersをclass TextModelの前につけます。

(旧)変更前↓

import Foundation

class TextModel : NSObject {
    let helloText:String = "Hello World"

}

(新)変更後↓

import Foundation

@objcMembers class TextModel : NSObject {
    let helloText:String = "Hello World"

}

TextModel

Objective-Cファイル側

Objective-C側ではまず、SampleProject1-Swift.hをインポートする必要があります。このインポートを行わないと、Swiftで書かれたクラスやメソッドをObjective-C側に読み込むことができません。

(旧)変更前↓

#import "ViewController.h"
#import <UIKit/UIKit.h>

@interface ViewController()

@property (strong, nonatomic) IBOutlet UILabel *textLabel;
@property (strong, nonatomic) IBOutlet UIButton *button;

@end

@implementation ViewController

- (void)viewDidLoad{
    [super viewDidLoad];
    
}

- (IBAction)showText:(UIButton *)sender {
    self.textLabel.text =  @"Sample";
}
@end

(新)変更後↓

#import "ViewController.h"
#import <UIKit/UIKit.h>
#import "SampleProject1-Swift.h" //←ここでimport

@interface ViewController()

@property (strong, nonatomic) IBOutlet UILabel *textLabel;
@property (strong, nonatomic) IBOutlet UIButton *button;

@end

@implementation ViewController

- (void)viewDidLoad{
    [super viewDidLoad];
    
}

- (IBAction)showText:(UIButton *)sender {
    TextModel *model = [[TextModel alloc] init]; //←ここでSwift側のクラスをObjective-Cで定義
    self.textLabel.text = [model helloText]; //←定義したmodelの定数を呼び出す
}
@end

3. ビルドして確認

今回はボタンタップ時にtextLabelが Hello World に変わればSwift側の定数が呼び出されているということになります。
それでは、ビルドしてみましょう!Swift側の定数が呼び出されているか確認してみます。

Hello World が呼ばれましたね!
これでSwift側の定数が呼び出されていることが確認できました。もちろん上記の方法でメソッドなども呼び出すことができます。もし、Objective-C上でSwiftで定義した定数&変数、メソッドなどを使わなければならない場合があったら参考にしてみてください!
今後は私の方でも更に理解を深め、より詳しく解説できるよう記事をアップデートしていく予定ですのでよろしくお願い致します!
読んでいただきありがとうございました!

参考記事

・SwiftとObjective-C連携 with Xcode
https://qiita.com/ysn/items/fa85612cb5adf9a4c05d#objective-cからswiftを呼び出す方法
・Swift を Cocoa や Objective-C と使用する
http://transxcode.com/Swift/Swift1.0.0/SwFObjC/SwiBaSe7.html
・Objective-CプロジェクトでSwiftプログラムのメソッド、プロパティへのアクセス方法【Swift5】
https://program-life.com/980
・Objective-CからSwiftのクラスを使用する。
https://nullpoint.hatenablog.com/entry/2017/05/23/230812

Discussion