在Objective-C类中导入Swift协议

时间:2014-06-06 09:15:59

标签: objective-c swift

我尝试将名为AnalyticProtocol的Swift协议导入名为AnalyticFactory的Objective-C类。

protocol AnalyticProtocol
{

}

我从现有的Objective-C项目开始(我没有用xCode创建一个新的Swift项目,我也没有找到如何配置我的Objective-C项目xCode 6中的Swift项目)。

在我的Swift文件中,我包含了名为.h的{​​{1}}文件,但编译器返回错误,告诉我它不存在。 所以,我创建了一个名为MyProjectName-Swift.h的{​​{1}}文件,该文件实际上是空的(我不知道应该放在里面)。

Apple documentation中,他们说我必须在我的.h文件中包含名为MyProjectName-Swift.h的{​​{1}}文件。但我需要将其不包含在我的.h文件中,而是包含在我的MyProjectName-Swift.h中。这会有问题吗?

当我尝试编译时,我发现了这个错误::0:错误:xxxAnalyticFactory.h:39:无法找到' AnalyticProtocol' 的协议声明

以及有罪的代码:

.m

我想我不太了解如何将Swift协议导入Objective-C类。

有没有人在我正在做的事情中看到错误?

5 个答案:

答案 0 :(得分:192)

您需要将@objc属性添加到Swift协议中,如下所示:

@objc protocol AnalyticProtocol {

}

答案 1 :(得分:69)

无法在objC头文件中导入Xcode生成的Swift头。

所以,既然你想在objC头文件中使用Swift代码,你需要"转发声明"要在objC头文件中使用的类和协议,如下所示:

@protocol AnalyticProtocol;

您现在可以在objC类声明中使用该协议:

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

在您的实现文件(objC .m文件)中,您可以导入Xcode生成的Swift标头(&#34; ProductModuleName-Swift.h&#34;)文件,现在正确的实现AnalyticProtocol编译器已知。

这也在&#34;使用Swift from Objective-C&#34;在Apple Docs

请注意,当您使用前向声明的协议时,XCode将在objC头文件中发出警告(&#34;无法找到&#39; AnalyticProtocol&#39;的协议定义),但这可以忽略 - 实现将在编译时找到。

答案 2 :(得分:37)

对于任何只需要采用协议的人 - 您可以分两步执行此操作,而不会产生任何警告或错误:

  1. .swift文件中,在协议名称前添加@objc

    @objc protocol AnalyticProtocol {
    
    }
    
  2. .m文件中,导入生成的Swift标头并采用私有类别的协议。 (头文件自动命名):

    #import "ProductModuleName-Swift.h"
    
    @interface AnalyticFactory () <AnalyticProtocol>
    
    @end
    
  3. 这是Apple推荐的方法。您可以在此处了解有关混合和匹配Objective-C和Swift的更多信息:https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html

答案 3 :(得分:6)

我们可以在目标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>

答案 4 :(得分:0)

如果您要创建框架,则需要导入

#import "ProductModuleName-Swift.h"

更改为:

#import <ProductModuleName/ProductModuleName-Swift.h>

在这种情况下,您还必须将快速协议公开

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