Swift到Objective-C头文件不包含Swift类

TJe*_*Jez 17 objective-c swift

我试图在Objective-C代码中使用Swift类,但是我的Swift类似乎没有出现在生成的头文件中.结果,我的构建失败了"使用未声明的标识符'HelloWorld'".

我使用模板创建了一个名为TestApp的项目.

我的目标中有以下构建设置:

  • 产品名称:TestApp
  • 产品模块名称:TestAppModule
  • 定义模块:是的

Apple的文档说要使用,#import <TestApp/TestAppModule-Swift.h>但这不起作用.

相反,我#import "TestAppModule-Swift.h"在我的".m"文件中使用.它似乎找到了这个.

我能够导航到它,它看起来像这样......

// Generated by Swift version 1.0 (swift-600.0.34.4.5)

#if defined(__has_include) && __has_include(<swift/objc-prologue.h>)
# include <swift/objc-prologue.h>
#endif

...etc...
Run Code Online (Sandbox Code Playgroud)

但没有在那里定义的类.

我在项目中有一个Swift文件,看起来像这样......

class HelloWorld {    
    func hello() {
        println("hello world")
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么这不使用标准头文件位置#import <TestApp/TestAppModule-Swift.h>

如何在头文件中获取我的swift类,这样我就不会得到"未声明的标识符"错误?

Log*_*gan 19

这是我如何使它工作.你可以在这里看到更大规模的答案.

改变这个:

class HelloWorld {    
    func hello() {
        println("hello world")
    }
}
Run Code Online (Sandbox Code Playgroud)

至:

@objc class HelloWorld { 

    class func newInstance() -> HelloWorld {
        return HelloWorld()
    }

    func hello() {
        println("hello world")
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在你的ObjC文件中:

#import "TestApp-Swift.h"
Run Code Online (Sandbox Code Playgroud)

并且这样打电话:

HelloWorld * helloWorld = [HelloWorld newInstance];
[helloWorld hello];
Run Code Online (Sandbox Code Playgroud)

  • 更新:这里提到@echelon答案作为对官方答案的评论,以便对某人有所帮助。我已经准备好一切。objc关键字,我的swift类是NSObject的子类。仍然没有用。事实证明,正如echelon在他的回答中提到的那样,即使我们不会在Swift代码中调用obj-c,我们也需要拥有桥接头。很奇怪,但是行得通。 (2认同)

Ech*_*lon 15

tl; dr如果你在Objective-C和Swift之间进行任何交叉调用,请确保你有一个桥接头.

我有完全相同的问题:我可以在DerivedData中看到-Swift.h文件,但它没有提到我的Swift类.我正确导入头文件,定义模块设置为YES,产品模块名称正确.我试着删除并重新添加Swift文件,清理buiild,退出XCode等,没有运气.

然后我意识到我的项目中没有-Bridging-Header.h文件,大概是因为我从之前的项目中将它拼凑在一起的方式.应该不是问题,因为我还没有(还)从Swift调用Objective-C.但是当我添加一个桥接头,并在构建设置(Swift编译器 - 代码生成 - > Objective-C桥接头)中引用它的路径时,它神奇地修复了问题 - 我的-Swift.h文件突然充满了SWIFT_CLASS( )善良!

所以我猜测桥接头是这个过程的基础,即使你没有使用Swift的Objective-C.


更新:我终于理解了这一点.它与公共/内部访问修饰符有关.不确定我是否最初错过了这个或者它是Apple文档的补充,但它现在明确指出: -

默认情况下,生成的标头包含使用public修饰符标记的Swift声明的接口.如果您的应用目标具有Objective-C桥接标头,它还包含标有内部修饰符的那些.

  • 如果我有一个框架,而不是应用程序,我如何使用非公共 swift 类。不支持将桥接标头与框架目标一起使用。 (2认同)

Mat*_*ges 11

#import "TestAppModule-Swift.h"在.m文件中使用是正确的.如果需要引用.h中的类,请使用@class前向声明.

此外,如果要使用Objective-C中的Swift类,则必须使用该@objc属性标记Swift类.Xcode将只包含在生成的标头中归属的类.另见本文档.

  • 文档指出:“如果您的Swift类是Objective-C类的后代,则编译器会自动为您添加`@ objc`属性。但是,在最新的Xcode 7下,情况似乎不再如此(至少对于UIViewController子类而言)。我必须手动添加注释。 (2认同)

小智 9

类应声明为@objc 公共