Objective-CクラスでのSwiftプロトコルのインポート


115

という名前AnalyticProtocolのObjective-Cクラスに、という名前のSwiftプロトコルをインポートしようとしていAnalyticFactoryます。

protocol AnalyticProtocol
{

}

私は既存のObjective-Cプロジェクトから始めています(xCodeを使用して新しいSwiftプロジェクトを作成しておらず、Objective-CプロジェクトをxCode 6のSwiftプロジェクトとして構成する方法もわかりませんでした)。

私のSwiftファイルに.h名前付きのファイルを含めましたMyProjectName-Swift.hが、コンパイラーはそれが存在しないことを示すエラーを返します。そこで、実際には空の.h名前のファイルを作成しましたMyProjectName-Swift.h(何を入れればよいかわかりません)。

、アップルのドキュメント彼らは私が含まれるように持っていることを言った.hという名前のファイルMyProjectName-Swift.hに私に.mファイルを。しかし、私はそれを私の.mファイルではなく私の中に含める必要があります.h。これは問題になりますか?

コンパイルしようとすると、次のエラーが発生します::0:エラー:xxxAnalyticFactory.h:39: 'AnalyticProtocol'のプロトコル宣言が見つかりません

そして、差別されたコード:

@interface AnalyticFactory : NSObject
{
    Class<AnalyticProtocol> _analyticProtocolClass; // The type of the analytic class currently used.
}

SwiftプロトコルをObjective-Cクラスにインポートする方法がよくわかりません。

誰かが私がやっていることでエラーを見ますか?


チェックアウトのObjective-Cとの統合スウィフトをビデオに周りの30:40でWWDC 2014のビデオ、彼らはObjective-Cのクラスにアクセススウィフトプロトコルに方法について説明します。
ジェイミーフォレスト

回答:


224

次の@objcようにSwiftプロトコルに属性を追加する必要があります。

@objc protocol AnalyticProtocol {

}

25
回答ありがとうございます。問題はまだ解決しません。
Jean Lebrument 2014

問題を再現するサンプルプロジェクトを投稿できますか?
ジェイミーフォレスト2014

@objcを追加すると、SwiftクラスをObj-Cにインポートするのに役立ちました
serg

19
@objcは常に機能するとは限りません。プロトコルに準拠している場合@interface.hファイルにプロトコルを追加すると機能しないことがあります。ただし、ファイルのプライベート@interfaceにプロトコルを追加することで、問題を.m修正できます(少なくとも、私にとっては時々あります)。だからあなたの上@implementation@interface MyController() <AnalyticProtocol>
Adam

1
Xcode 8は編集中に文句を言うこともありますが、実際にビルドすると、この回答とコメントに従って、エラーは解消されます。
ロジャーピングルトン2016年

76

Xcodeで生成されたSwiftヘッダーをobjCヘッダーファイルにインポートすることはできません。

したがって、objCヘッダーファイルでSwiftコードを使用する必要があるため、次のように、objCヘッダーファイルで使用するクラスとプロトコルを「前方宣言」する必要があります。

@protocol AnalyticProtocol;

これで、objCクラス宣言でプロトコルを使用できます。

@interface AnalyticFactory : NSObject
{
    Class<AnalyticProtocol> _analyticProtocolClass; // The type of the analytic class currently used.
}

実装ファイル(objC .mファイル)で、Xcodeによって生成されたSwiftヘッダー( "ProductModuleName-Swift.h")ファイルをインポートすると、正しい実装AnalyticProtocolがコンパイラーに認識されます。

これについては、Appleドキュメントの「Objective-CからのSwiftの使用」セクションでも説明しています

前方宣言されたプロトコルを使用すると、XCodeはobjCヘッダーファイルに警告を表示しますが(「 'AnalyticProtocol'のプロトコル定義が見つかりません)、これは無視できます-実装はコンパイル時に見つかります。


19
Xcodeがコンパイルして正常に動作するときに、プロトコルが見つからないという警告が表示されるのはなぜですか?警告を削除する方法はありますか?
オーレン、2015

ただし、このクラスのプロトコルメソッドを呼び出すことはまだできません。エラーが発生しますNo visible @interface for <ClassName> declares the selector <protocolMethodName>
Elsa

「xxxxのプロトコル定義が見つかりません」という警告が生成されます
JAHelia

51

プロトコルを採用する必要があるだけの場合–警告やエラーを生成せずに、2つのステップでこれを実行できます。

  1. あなたの .swift、ファイルの追加、@objcプロトコル名の前に:

    @objc protocol AnalyticProtocol {
    
    }
  2. あなたには.m、ファイル、生成されたスウィフトヘッダをインポートし、プライベートカテゴリでプロトコルを採用しています。(ヘッダーファイルは自動的に名前が付けられます):

    #import "ProductModuleName-Swift.h"
    
    @interface AnalyticFactory () <AnalyticProtocol>
    
    @end

これはAppleが推奨するアプローチです。Objective-CとSwiftの混合と照合の詳細については、https//developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.htmlをご覧ください。


1
フォワード宣言の有無にかかわらず、まだ警告が表示されます。拡張機能でプロトコルを使用しています。
Cristi Băluță 2017年

インポートできません#import "AnalyticProtocol-Swift.h"。WhateverProtocol-Swift.hはあなたが言ったように自動生成されないようです。
Hlung、2017年

2
これでうまくいきました。このページの他の提案や回答は機能しませんでした。私はSwift 4を使用しています。
ポールスボー

1
これは警告を削除する唯一の方法でした(プロトコルがヘッダーファイルにある場合でも機能します)
David P

1
同じリンクはWebArchiveを経由して提供されています:web.archive.org/web/20170310053717/https://developer.apple.com/...
リチャードTopchii

3

フレームワークを作成している場合、必要なインポート

#import "ProductModuleName-Swift.h"

変更:

#import <ProductModuleName/ProductModuleName-Swift.h>

この場合、迅速なプロトコルも公開する必要があります:

@objc public protocol AnalyticProtocol {
  func something();
}

3

コードをほとんど変更することなく、Objective Cで迅速なプロトコルを使用できます。また、@ objcで宣言されたプロトコルを使用すると、デフォルトの実装なしで、オプションのメソッドと必須のメソッドを使用できます。それは長所と短所が付属しています。

Objective Cで使用する場合、実際にはプロトコル名をよりわかりやすい名前に変更できます。「@ objc(alias_name)」を使用します。

これがコードです。ObjCコードで使用する@objc属性とエイリアス名を持つ迅速なプロトコルを用意しましょう。

@objc(ObjTableViewReloadable) protocol TableViewReloadable: class {
   func reloadRow(at index: IndexPath)
   func reloadSection(at index: Int)
   func reloadTable()
}

これで、farwordが.hファイルでプロトコルを宣言できるようになります

@protocol ObjTableViewReloadable;

これで、.mファイルでこのプロトコルに準拠し、必要なメソッド実装を追加できます。

#import "MyApp-Swift.h"
@interface MyObjcViewController () <ObjTableViewReloadable>

これを投稿していただきありがとうございます。私はダートよりも古いレガシーコードを探しています。このアプローチが機能する場合、それは私に多大な苦痛を節約します。:)
エイドリアン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.