在 Objective-C 类中导入 Swift 协议

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

protocol AnalyticProtocol
{


}

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

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

苹果文档,他们说,我必须包括我的 .h文件名为 MyProjectName-Swift.h在我的 .m文件。但我需要包括它不到我的 .m文件,但到我的 .h。这会有问题吗?

当我尝试编译时,我得到了这个错误: : 0: error: xxxAnalyticFactory.h: 39: can not find protocol Declaration for‘ AnalyticProtocol’

还有犯罪代码:

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

我不太明白如何将 Swift 协议导入 Objective-C 类。

有人发现我做错了吗?

74579 次浏览

您需要像下面这样将 @objc属性添加到您的 Swift 协议中:

@objc protocol AnalyticProtocol {


}

对于任何只是需要采用协议的人来说,你可以分两步做到这一点,而不会产生任何警告或错误:

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

    @objc protocol AnalyticProtocol {
    
    
    }
    
  2. In your .m file, import the generated Swift header and adopt the protocol in a private category. (The header file is named automagically):

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

This is Apple’s recommended approach. You can learn more about mixing and matching Objective-C and Swift here: https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html

不可能将 Xcode 生成的 Swift 头文件导入到 objecC 头文件中。

因此,由于您希望在 objecC 头文件中使用 Swift 代码,所以您需要“转发声明”您希望在 objecC 头文件中使用的类和协议,如下所示:

@protocol AnalyticProtocol;

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

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

在您的实现文件中(对象 C。M 文件) ,可以导入 Xcode 生成的 Swift 头(“ ProductModuleName-Swift。H”)文件和正确的实现 AnalyticProtocol现在将为编译器所知。

这在官方 将 Swift 导入 Objective-C中也有描述

请注意,当您使用转发声明的协议时,XCode 将在 objecC 头文件中给出一个警告(“无法找到‘ AnalyticProtocol’的协议定义) ,但是可以忽略这一点——实现将在编译时被找到。

如果您正在创建一个框架,则所需的导入

#import "ProductModuleName-Swift.h"

更改:

#import <ProductModuleName/ProductModuleName-Swift.h>

在这种情况下,你还必须制定快速协议 公众人士:

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

我们可以在 C 目标中使用快速协议只需要对代码进行少量修改。另外,@objecc 声明的协议允许您拥有可选的和必需的方法,而不需要缺省实现。有利有弊。

在 Objective C 中使用时,我们实际上可以将协议名称重命名为更具描述性的名称,我使用“@objecc (alias _ name)”。

这是密码, 让我们在 OBC 代码中使用一个带有@objecc 属性和别名的快速协议。

@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>