我在Swift中编写了SearcherProtocol
,需要实现一个必须使用此协议的Objective-C类FileSearcher
。
所以我尝试了这个:
#import <Foundation/Foundation.h>
@interface FileSearcher : NSObject <SearcherProtocol>
// ... class content
@end
编译器告诉我
找不到&#39; SearcherProtocol&#39;
的协议声明
相应的桥接头文件(modulename-Swift.h
)正在FileSearcher.m
内导入。
将SearcherProtocol
导入FileSearcher.h
会引发另一个编译错误:module name-swift.h file not found
有没有人知道我做错了什么?
我正在使用Xcode 6 Beta 5.
修改
以下是Swift中的协议声明:
@objc protocol SearcherProtocol
{
var searchNotificationTarget: SearchCompletedProtocol? { get }
var lastSearchResults: [AnyObject] { get set }
func search(searchParam: String, error: NSErrorPointer) -> Bool
}
SearchCompletedProtocol:
@objc protocol SearchCompletedProtocol
{
func searchCompletedNotification(sender: AnyObject!)
}
答案 0 :(得分:31)
发生这种情况有两个常见原因:
<强> 1。获取模块名称:
如果swift协议和Objective C都在同一个项目中,那么根据apple,您只需要确保获得正确的模块名称。
对于Xcode6 beta 5,您可以在BuildSettings-&gt; Packaging-&gt;产品模块名称下找到它
一个常见的错误是认为每个swift文件/类都有自己的文件,但是它们都被放入一个大的项目名称中。
如果模块名称有空格,则会出现进一步的错误,这些错误应替换为下划线。
编辑:
通过您的协议,我创建了一个名为“测试”的测试项目。编译完美,它有文件:
TestObjClass.h
#import <Foundation/Foundation.h>
#import "Test-Swift.h"
@interface TestObjCClass : NSObject <SearcherProtocol>
@end
TestObjClass.m
#import "TestObjCClass.h"
@implementation TestObjCClass
@end
TestProtocol.swift
import Foundation
@objc protocol SearcherProtocol
{
var searchNotificationTarget: SearchCompletedProtocol? { get }
var lastSearchResults: [AnyObject] { get set }
func search(searchParam: String, error: NSErrorPointer) -> Bool
}
@objc protocol SearchCompletedProtocol
{
func searchCompletedNotification(sender: AnyObject!)
}
<强> 2。避免循环引用:
Mitrenegades的回答解释了这一点,但如果您的项目需要使用使用swift协议的显式objc类(而不仅仅是使用协议),那么您将遇到循环问题。原因是swift协议被定义为swift-objc头,然后定义到你的obj-c类定义,然后再定义到swift-objc头。
Mitrenegades解决方案是使用objective-c协议,是一种方式,但如果你想要一个swift协议,那么另一种方法是重构代码,以便不直接使用objective-c类,而是使用协议(例如一些基于协议的工厂模式)。无论哪种方式都适合您的目的。
答案 1 :(得分:22)
当你有
时#import "moduleName-Swift.h"
在你希望成为委托的.h文件中的,并且在桥接头文件中也有.h文件,那里有一个循环引用,导致moduleName-Swift.h编译失败。对于@james_alvarez的测试项目,它可能正在工作,因为您不需要将TestObjClass.h包含在桥接头中。
我最好的方法是组合objc文件,这些文件需要是swift编写的类的委托,但是还需要包含在桥接头中,以便其他swift文件可以访问这个objc类,就是创建一个objc:
中的单独协议文件MyProtocol.h:
@protocol MyDelegate <NSObject>
-(void)didDoThis;
-(void)didDoThat;
@end
ViewController.h:
#import "MyProtocol.h"
@interface ViewController : UIViewController <MyDelegate>
MyProject的桥接-Header.h
#import "MyProtocol.h"
#import "ViewController.h"
答案 2 :(得分:19)
我知道这是很久以前的事了,但是我在为Swift代码添加协议时遇到了同样的问题,而且它没有被添加到-Swift.h头文件中,因此&# 34;找不到协议声明&#34;
问题是我的协议没有标记为 Public 。我改变了我的协议:
@objc protocol MyProtocol { //etc.... }
到此:
@objc public protocol MyProtocol { //etc.... }
我还不完全确定我为什么需要&#39; Public&#39;但似乎没有其他人,但嘿,它有效...
答案 3 :(得分:1)
确保在ObjectiveC文件中包含自动生成的Swift标头。它将与项目模块的名称相同,后跟-Swift.h
。
例如,如果您的项目模块是 MyTarget ,那么您将使用:
#import "MyTarget-Swift.h"
如果您在目标C文件中输入导入,则不会自动完成。您可以通过在键入后单击标题来验证您是否拥有正确的文件。
答案 4 :(得分:-2)
在.h文件
中导入委托@protocol AnalyticProtocol;
并将其添加到.swift文件
@objc public protocol AnalyticProtocol {
}
答案 5 :(得分:-3)
尝试将#import "Product_Module_Name-Swift.h"
添加到Product_Module_Name-Prefix.pch
文件中。这对我来说是固定的,而且你现在可以从任何objc文件访问你的swift文件。