【Objective-C】Objective-CプロジェクトでSwiftプログラムのメソッド、プロパティへのアクセス方法【Swift5】

2020年8月26日

今回はObjective-Cで作られているプロジェクト、すなわちObjective-CプログラムからSwiftプログラムのメソッドやプロパティへのアクセス方法をご紹介します。

  1. Objective-CプログラムからSwiftプログラムを使用可能にする方法
  2. Objective-CでSwiftプログラムのメソッド(関数)を呼び出す方法
  3. Objective-CでSwiftプログラムのプロパティ(ゲッター/セッターメソッド)を呼び出す方法

1. Objective-CプログラムからSwiftプログラムを使用可能にする方法

#import "[Product Name]-Swift.h"

Objective-CプログラムからSwiftプログラムを使用可能にする方法はとても簡単で、プロダクトネームに-Swift.hをつけてimportするだけです。

これだけで複数のSwiftプログラムがimportされるので、仮にSwiftプログラム名が「Hoge.swift」「Test.Swift」と2つあっても"[Product Name]-Swift.h"のみで両方使用可能です。

単純ミスで私が引っかかったのが
#import "[Swift File Name]-Swift.h" ではなく #import "[Product Name]-Swift.h" ということです。

ProductNameはプロジェクトを作る時に記述した名前、またはPROJECTに設定している名前を設定します。上記画像ですとプロジェクト名は「ObcCallSwift」なので

#import "ObcCallSwift-Swift.h"

となります。

2. Objective-CでSwiftプログラムのメソッド(関数)を呼び出す方法

Swiftで用意したメソッドを呼び出す方法もとても簡単です。

import UIKit

class TestObject: NSObject {
    
    @objc func hoge() -> Void {
        print("hoge")
    }
    
    @objc func hogeString() -> NSString {
        return "hogeString"
    }
}

まずSwiftで上記のように@objcをつけたメソッドを用意します。

#import "ViewController.h"

#import "ObcCallSwift-Swift.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    TestObject *testObject = [[TestObject alloc] init];
    [testObject hoge];
    
    NSString *str = [testObject hogeString];
    NSLog(@"str:%@",str);
    
}

@end

次に呼び出したいところで上記のように呼び出します。
たったこれだけでメソッドを呼び出すことができます。

hoge
2019-07-10 10:02:27.183756+0900 ObcCallSwift[15618:927167] str:hogeString

実行すると結果は上記のようなログがでます。

1点、注意点があるとすれば戻り値はObjective-Cにない型は使えません。
つまり、StringはNSString、ArrayはNSArrayにするなどObjective-Cで使える型に合わせておく必要があります。

3.Objective-CでSwiftプログラムのプロパティ(ゲッター/セッターメソッド)を呼び出す方法

あまり記事になってないですが、メソッドだけではなくObjective-Cプログラムのプロパティ(@propaty ~~~)と同じようなことをSwiftプログラムで実行させることもできます。

import UIKit

class TestObject: NSObject {
    
    var name_ : NSString = ""
    @objc func name() -> NSString {
        return name_
    }
    @objc func setName(_ p : NSString) -> Void {
        name_ = p
    }
    
    var age_ : Int = 0
    @objc func age() -> Int {
        return age_
    }
    @objc func setAge(_ p : Int) -> Void {
        age_ = p
    }
}

まずSwiftプロジェクトで上記のように記述します。
1つの変数に対し、ゲッターメソッド、セッターメソッドを用意するイメージです。

#import "ViewController.h"

#import "ObcCallSwift-Swift.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    TestObject *testObject = [[TestObject alloc] init];
    
    testObject.name = @"Ken";
    NSLog(@"testObject.name:%@",testObject.name);
    
    testObject.age = 10;
    NSLog(@"testObject.age:%d",testObject.age);
    
}

@end

次に使用したいところで上記のように記述します。
testObjectというインスタンスを1つ作り、先ほど作ったセッターメソッド 、ゲッターメソッドをつかって読み書きを行なっています。

2019-07-10 10:02:27.183788+0900 ObcCallSwift[15618:927167] testObject.name:Ken
2019-07-10 10:02:27.183798+0900 ObcCallSwift[15618:927167] testObject.age:10

これを実行すると上記のようなログがでます。
ちゃんとプロパティに値がセットされていることがわかりますね。

注意点があるとすれば、メソッドの戻り値同様、Objective-Cにない型は使えません。
つまり、StringはNSString、ArrayはNSArrayにするなどObjective-Cで使える型に合わせておく必要があります。

まとめ

このようにObjective-CプロジェクトでSwiftを使う場合、ある程度のことはできます。
Objective-CプロジェクトでSwiftどうしても使いたい!というケースは少ないと思いますが、Objective-CプロジェクトをSwiftで書き直すよりは早い場合もあるので工数と検討して試してみるのもいいと思います。