Objective-CクラスからSwift関数を呼び出す


84

古いObjective-Cプロジェクトがあり、新しいSwift関数とオブジェクトを呼び出したいので、ファイル「<ProjectName>-Bridging-Header.h」と「<ProjectName>-Swift.h」を作成しました。

SwiftからObjective-Cに関数を呼び出すのは簡単でしたが、逆の問題があります。

そこで、単純なクラス「System.Swift」を作成しました。

import Foundation

@objc class System : NSObject {

    @objc func printSome() {
        println("Print line System");
    }
    
}

今、私はここ<...>-Swift.h私がこれを書いたファイルの中にドキュメントに従おうとしました

@class System;

@interface System : NSObject

-(void)printSome;

@end

そして、Objective-Cクラス内にインポートしました。この時点で、Objective-CコードのObjective Cクラス(現在はUIViewController)内で、「printSome」メソッドを呼び出そうとしました。

- (void)viewDidLoad
{
    [super viewDidLoad];
    System * sis = [[System alloc] init];
    [sis printSome];
    //any additional setup after loading the view from its nib.
}

今、私は次のエラーがあります:

アーキテクチャi386の未定義のシンボル: " OBJC_CLASS $ _System"、参照元: "ObjectiveC_Class_That_Call_Swift_Object"のobjc-class-ref.o ld:アーキテクチャi386のシンボルが見つかりませんclang:エラー:リンカーコマンドが終了コード1で失敗しました(使用-v呼び出しを確認する)


リンカーエラーがあります。それは:(1)Xcodeは、Objective-Cブリッジヘッダーと生成されたヘッダーにSwiftコードの名前を付けるときに、ターゲット名ではなく製品モジュール名を使用するか、(2)それらのObjective-CヘッダーをインポートするようにしてくださいSwiftコードにアクセスするObjective-C.mファイルにSwiftで生成されたヘッダーをインポートする前のタイプ?Objective-Cコードに#import“ ProductModuleName-Swift.h”がありますか?
petert 2014

はい、ドキュメントを読みましたが、「ProductModelName」の名前は正しいです...ビルド設定内で製品モデルが設定されていないというバグがあります...私も設定しています...
Eloreden 2014

@petert 2番目のポイントをよりよく説明できますか?私は...私がやったeverithing書いた
Eloreden

問題は解決しました。プロジェクト呼び出し<ProductModelName> -Swift.hに新しい.hファイルを追加しましたが、コンパイラーがこのオブジェクトを表示できない場合でも作成するため、これは必要ありません。作成した新しいファイルを削除しましたが、すべて完全に実行されます。TNXのpetert
Eloreden

あなたはあなた自身の質問に答えることができます-それは他の人を助けるかもしれません。
petert 2014

回答:


50

問題は解決しました。以前.hObjective-Cクラスに新しいファイルを作成して含めました<ProductModuleName>-Swift.hが、後で発見したように、コンパイラが必要なファイルを非表示で作成するため、この手順は必要ありません。

<ProductModuleName>-Swift.hクラスに含めるだけで、機能するはずです。


3
パラメータ付きの関数はどうですか?
Arnlee Vizcayno 2014

3
パラメータと戻り値を使用してSwift関数にアクセスすることも、パラメータと戻り値を使用せずにSwift関数にアクセスすることもできません。理由はわかりません。私のSwiftクラスはNSObjectです。Foundationフレームワークをインポートしました@objc。クラスと関数にはプレフィックスが付いています。-Swift.h自動的に作成されています。私を悩ませているのは、クラス自体を呼び出すことはできますが、クラス内の関数を呼び出すことはできないということです。誰かが理由を知っていますか?
デヴィッド・Gölzhäuser


2
です<productModuleName>-.Swift.h(ではありませんmodel)。
SwiftArchitect 2015

2
製品名にスペースが含まれている場合は、次のようにアンダースコアに置き換えてください#import "My_Project-Swift.h"
EricRobertBrewer 2016

41

それは奇妙ですが、うまくいくでしょう

1) Add @objc  to  Swift class

2) Add in .m 
    #import "(ProjectName)-Swift.h"

3) Call from .h
    @class SwiftClass;

4)On SwiftClass 
   click "Command" + Left Click (Apple Documantation)

5) To see "-Swift.h" -> click "Command" + Left Click

アプリは-Swift.hでこのクラスのインターフェースを生成します

例:SWIFT_CLASS( "_ TtC10Project17220PLHelper")@ interface PLHelper

  • (void)notifyForDownloading:(NSDictionary *)userInfo;
  • (instancetype)init OBJC_DESIGNATED_INITIALIZER; @終わり

@objc (MyClassName)
nielsbot 2014

12
私と同じ愚かな間違いをするかもしれない人のために。ステップ2では、あなたが使用していることを確認し(ProjectName)-Swift.hしないで (ClassName)-Swift.h
Hlung 2015

ありがとう@Svitlana、信じられないほど、それはうまくいきました!!! ただし、追加したメソッドをクラスの他の場所に移動するなど、これらの手順を何度も再試行する必要があります。
Scofield Tran 2016年

1
3) @class SwiftClassName;私を救った
MazenKasser19年

33

ProjectName "MyFirstProjectOnSwift"とswiftクラス名 "mySwiftClass"があり、objectiveCクラスが "MyObjectiveCLass"であると仮定します。

次の手順は次のとおりです。-

  1. 「MyObjectiveCLass.m」に#import「MyFirstProjectOnSwift-Swift.h」を追加します

  2. MyObjectiveCLass.hに@classmySwiftClassを追加します。

  3. 次に、MyObjectiveCLass.mで

    mySwiftClass * myClass = [mySwiftClass new]; {swiftメソッドを呼び出したい場所ならどこでも、このように呼び出す。}

  4. [myClass methodName];


2
mySwiftClass * myClass = [mySwiftClassnew]機能しません>>>>>
Hari Narayanan

@HariNarayananそうすべきではありません。明確な派生データを考えて、プロジェクトを再開してください。
Anubhav Giri 2017

12

Objective-Cの.mファイルにインポートされている-Swift.hファイルを確認します。

#import <YourProjectName-Swift.h>

その行をクリックし、左クリック-[定義にジャンプ]。

このファイルは、手動ではなく自動的に含める必要があります。


2

をインポートしてもクラスが表示されない場合<ProductModuleName>-Swift.h

クラスがネイティブクラス(例UIViewController)をサブクラス化していることを確認するか、少なくともユーティリティクラスの場合は、サブクラスにしNSObjectます。クラスが表示されます。


2

この投稿に出くわした人や他の答えが機能しない人のためのちょっとした追加のヒント:Swiftクラスを「公開」と宣言する必要があるかもしれません。

例:

@objc public class MySwiftClass: NSObject {


0

Obj-CからSwiftに移行されるプロジェクトでObjective-CからSwiftコードを実行するための推奨される方法は、ブリッジ/プロキシパターンを使用することです。

  1. ブリッジを実装します。

import Foundation

@objc class AnalyticsPropertyBridge: NSObject {

private var analytics: AnalyticsManager = AnalyticsManager()

@objc func refreshProperties() {

    self.analytics.set(AnalyticsProperty.clientType)
}

}

  1. アンブレラファイル(Bridging-Header)にobjC呼び出し元モジュールを含めます。

#import "CallerModule.h"

  1. 最後に、呼び出し元の.mファイルで、2つの問題があります。

3.aアンブレラファイルのインポート:

#import "MyProject-Swift.h"

3.bブリッジを呼び出します。

[[AnalyticsPropertyBridge new] refreshProperties];

利点:コードはObjcから呼び出されるため、迅速なコードが@objcで汚れることはありません。時間が経つにつれて、ObjCはプロジェクトで削減され、最終的に花嫁は削除されます。


-1

誰かがまだ問題を抱えているなら、ここに良い記事があります。

SwiftとObjective-Cの相互運用性の設定

  1. この記事では、SwiftファイルをObjCにインポートする方法と、ObjcファイルをSwiftにインポートする方法について詳しく説明します。
  2. また、プロジェクト名にスペースが含まれている場合に一般的に直面する問題にも対処します。
  3. また、「製品モジュール名」フラグについても説明します。

これは理論的には質問に答えることができますが、ここに答えの本質的な部分を含め、参照用のリンクを提供することが望ましいでしょう
Arghya Sadhu
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.