简体   繁体   English

在 Objective-C 类中导入 Swift 协议

[英]Importing a Swift protocol in Objective-C class

I try to import a Swift Protocol named AnalyticProtocol into an Objective-C class named AnalyticFactory .我尝试导入斯威夫特协议名为AnalyticProtocol到一个名为Objective-C类AnalyticFactory

protocol AnalyticProtocol
{

}

I'm starting from an existing Objective-C project (I didn't create a new Swift project with xCode and I didn't found how configure my Objective-C project to be a Swift project in xCode 6 ).我从一个现有的 Objective-C 项目开始(我没有用 xCode 创建一个新的 Swift 项目,我没有找到如何在 xCode 6 中将我的 Objective-C 项目配置为一个 Swift 项目)。

In my Swift file I included the .h file named MyProjectName-Swift.h but the compiler return me an error telling me that it doesn't exist .在我的 Swift 文件中,我包含了名为MyProjectName-Swift.h.h文件,但编译器返回一个错误,告诉我它不存在 So, I created a .h file named MyProjectName-Swift.h which is actually empty (I don't know what I should put inside).所以,我创建了一个名为MyProjectName-Swift.h.h文件,它实际上是空的(我不知道应该放什么)。

In the Apple documentation they said that I have to include my .h file named MyProjectName-Swift.h in my .m file.Apple 文档中,他们说我必须在我的.m文件中包含名为MyProjectName-Swift.h .h文件。 But I need to include it not into my .m file but into my .h .但是我不需要将它包含在我的.m文件中,而是包含在我的.h Does this can be problematic?这可能有问题吗?

When I try to compile I've got this error: :0: error: xxxAnalyticFactory.h:39: cannot find protocol declaration for 'AnalyticProtocol'当我尝试编译时出现此错误: :0: error: xxxAnalyticFactory.h:39: 找不到“AnalyticProtocol”的协议声明

And the incriminated code:以及被指控的代码:

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

I think I don't understand well how can I import a Swift protocol into an Objective-C class.我想我不太明白如何将 Swift 协议导入到 Objective-C 类中。

Does anyone see an error in what I'm doing?有没有人看到我正在做的事情有错误?

You need to add the @objc attribute to your Swift protocol like so:您需要将@objc属性添加到您的 Swift 协议中,如下所示:

@objc protocol AnalyticProtocol {

}

It is not possible to import the Xcode generated Swift header in objC header files.无法在 objC 头文件中导入 Xcode 生成的 Swift 头文件。

So, since you want to use Swift code in an objC header file, you will need to "forward declare" the classes and protocols you want to use in the objC header file, like this:因此,由于您想在 objC 头文件中使用 Swift 代码,您需要“前向声明”要在 objC 头文件中使用的类和协议,如下所示:

@protocol AnalyticProtocol;

You can now use the protocol in your objC class declaration:您现在可以在 objC 类声明中使用该协议:

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

In your implementation file (the objC .m file), you can import the Xcode generated Swift header ("ProductModuleName-Swift.h") file and the correct implementation AnalyticProtocol will now be known to the compiler.在您的实现文件(objC .m 文件)中,您可以导入 Xcode 生成的 Swift 头文件(“ProductModuleName-Swift.h”)文件,现在编译器将知道正确的实现AnalyticProtocol

This is also described in the section "Using Swift from Objective-C" in the Apple Docs这也在Apple Docs 的“使用 Objective-C 中的 Swift”部分中有所描述

Note that XCode will give a warning in the objC header file when you use the forward declared protocol ("Cannot find protocol definition for 'AnalyticProtocol'), but this is can be ignored - the implementation will be found at compile time.请注意,当您使用前向声明的协议(“找不到 'AnalyticProtocol' 的协议定义)时,XCode 将在 objC 头文件中给出警告,但这可以忽略 - 将在编译时找到实现。

For anybody who simply needs to adopt a protocol – you can do this in two steps, without generating any warnings or errors:对于任何只需要采用协议的人 - 您可以分两步完成,而不会产生任何警告或错误:

  1. In your .swift file, add @objc before the protocol name:在您的.swift文件中,在协议名称前添加@objc

     @objc protocol AnalyticProtocol { }
  2. In your .m file, import the generated Swift header and adopt the protocol in a private category.在您的.m文件中,导入生成的 Swift 标头并采用私有类别中的协议。 (The header file is named automagically): (头文件是自动命名的):

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

This is Apple's recommended approach.这是 Apple 推荐的方法。 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您可以在此处了解有关混合和匹配 Objective-C 和 Swift 的更多信息: https : //developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html

We can use swift protocols in Objective C with few changes to the code.我们可以在目标 C 中使用 swift 协议,只需对代码进行少量更改。 Also, @objc declared protocols let you have optional and required methods without default implementations.此外,@objc 声明的协议让您拥有可选和必需的方法,而无需默认实现。 It comes with pros and cons.它有利有弊。

We could actually re-name the protocol name to a more descriptive when using in Objective C. I make use of "@objc(alias_name)".在 Objective C 中使用时,我们实际上可以将协议名称重命名为更具描述性。我使用“@objc(alias_name)”。

Here is the code, Let's have a swift protocol with @objc attribute and alias name to use in the ObjC code.这是代码,让我们有一个带有@objc 属性和别名的 swift 协议,以便在 ObjC 代码中使用。

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

Now lets farword declare our protocol in .h file现在让 farword 在 .h 文件中声明我们的协议

@protocol ObjTableViewReloadable;

You can now conform to this protocol in .m file and add required methods implementation.您现在可以在 .m 文件中遵守此协议并添加所需的方法实现。

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

If your are creating a framework, the required import如果您正在创建一个框架,所需的导入

#import "ProductModuleName-Swift.h"

changes to:更改为:

#import <ProductModuleName/ProductModuleName-Swift.h>

In this case you also must make the swift protocol public :在这种情况下,您还必须公开swift 协议:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM