Swift的Objective-C报头不包含Swift类。

时间:2022-09-07 07:45:47

I'm attempting to use Swift classes in my Objective-C code, however my Swift classes don't seem to appear in the generated header. As a result, my build fails with "Use of undeclared identifier 'HelloWorld'".

我试图在Objective-C代码中使用Swift类,但是我的Swift类似乎并没有出现在生成的标题中。因此,我的构建失败了“使用未声明的标识符HelloWorld”。

I used the templates to create a project called TestApp.

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

I have the following Build Settings in my target:

我的目标如下:

  • Product Name : TestApp
  • 产品名称:TestApp
  • Product Module Name : TestAppModule
  • 产品模块名称:TestAppModule。
  • Defines Module : Yes
  • 定义模块:是的

Apple's documentation says to use #import <TestApp/TestAppModule-Swift.h> but this doesn't work.

苹果的文档说明使用#import ,但这不行。

Instead, I'm using #import "TestAppModule-Swift.h" in my ".m" file. It seems to find this.

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

I'm able to navigate to it, and it looks like this...

我可以导航到它,它看起来像这样…

// 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...

but no classes defined in there.

但是没有定义的类。

I have a Swift file in the project that looks like this...

我在这个项目中有一个快速的文件,看起来像这样…

class HelloWorld {    
    func hello() {
        println("hello world")
    }
}

Why isn't this working using the standard header file location #import <TestApp/TestAppModule-Swift.h>?

为什么不使用标准头文件位置#导入 ?

How can I get my swift classes in that header file, so I won't get the "undeclared identifier" error?

如何在头文件中获得swift类,因此我将不会得到“未声明的标识符”错误?

7 个解决方案

#1


16  

Here's how I have gotten it to work. You can see a more large-scale answer here.

这是我的工作方式。你可以在这里看到更大规模的答案。

Change this:

改变:

class HelloWorld {    
    func hello() {
        println("hello world")
    }
}

To:

:

@objc class HelloWorld { 

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

    func hello() {
        println("hello world")
    }
}

Then, In your ObjC file:

然后,在你的ObjC文件中:

#import "TestApp-Swift.h"

And call like this:

并调用如下:

HelloWorld * helloWorld = [HelloWorld newInstance];
[helloWorld hello];

#2


14  

tl;dr Ensure you have a bridging header if you're doing any cross-calling between Objective-C and Swift.

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

I had the exact same problem: I could see the -Swift.h file in DerivedData but it made no mention of my Swift classes. I was importing the header file correctly, the Defines Module setting was YES, and the Product Module Name was correct. I tried deleting and re-adding the Swift files, clean buiild, quitting XCode, etc, with no luck.

我有一个完全相同的问题:我能看到-斯威夫特。h文件在DerivedData,但它没有提到我的Swift类。我正确地导入了头文件,定义的模块设置是YES,并且产品模块名称是正确的。我尝试删除和重新添加Swift文件,干净的bui,退出XCode等,没有运气。

Then I realised I had no -Bridging-Header.h file in my project, presumably due to the way I'd cobbled it together from a previous project. Shouldn't be a problem because I was not (yet) calling Objective-C from Swift. But when I added a bridging header, and referred to its path in the build settings (Swift Compiler - Code Generation -> Objective-C Bridging Header), it magically fixed the problem - my -Swift.h file was suddenly full of SWIFT_CLASS() goodness!

然后我意识到我没有- bridgingheader。h文件在我的项目中,大概是由于我从先前的项目中拼凑起来的方法。不应该是个问题,因为我还没有从Swift调用Objective-C。但是,当我添加一个桥接头,并在构建设置中引用它的路径时(Swift编译器-代码生成-> Objective-C桥接头),它神奇地解决了问题—我的-Swift。h文件突然充满了SWIFT_CLASS()的好处!

So I'm guessing the bridging header is fundamental to the process, even if you're NOT using Objective-C from Swift.

所以我猜想桥接头是这个过程的基础,即使你不使用Swift的Objective-C。


UPDATE: I finally understand this. It is related to public/internal access modifiers. Not sure if I missed this originally or if it's an addition to the Apple docs, but it now clearly states:-

更新:我终于明白了。它与公共/内部访问修饰符相关。我不确定我是否漏掉了这个,或者它是苹果文档的一个补充,但它现在清楚地说明了:-。

By default, the generated header contains interfaces for Swift declarations marked with the public modifier. It also contains those marked with the internal modifier if your app target has an Objective-C bridging header.

默认情况下,生成的头包含与公共修饰符标记的Swift声明的接口。如果你的应用目标有一个Objective-C桥接头,它也会包含那些带有内部修饰符的标记。

#3


9  

It is proper to use #import "TestAppModule-Swift.h" in your .m files. If you need to reference a class in a .h, use the @class forward declaration.

使用#import“TestAppModule-Swift”是正确的。在你的。m文件中。如果需要在.h中引用一个类,请使用@class forward声明。

Further, if you want to use a Swift class from Objective-C, the Swift class must be marked with the @objc attribute. Xcode will only include classes with that attributed in the generated header. See also this documentation.

此外,如果您想要使用Objective-C中的Swift类,那么Swift类必须用@objc属性标记。Xcode只包含在生成的标题中包含该属性的类。看到这个文档。

#4


7  

Class should be declared as @objc public class

类应该声明为@objc public类。

#5


2  

A more convenient way would be to inherit from NSObject. Like so:

更方便的方法是继承NSObject。像这样:

class HelloWorld: NSObject {    
    func hello() {
        println("hello world")
    }
}

#6


0  

In my case the class was not being compiled, because I first added it to my test target only... After adding it to my main target (Build Phases -> Compile Sources), it was actual compiled and added to the header file.

在我的例子中,这个类没有被编译,因为我只把它添加到我的测试目标中…在将它添加到我的主要目标(构建阶段->编译源)之后,它被实际编译并添加到头文件中。

So much for TDD ;-)

TDD的太多了;-)

#7


0  

In my case, by following Apple guidelines, it did not work until I ran the project. The xcode editor kept flagging the unknown swift class, until i clicked "run". The build succeeded, and the swift method worked.

在我的案例中,按照苹果的指导方针,直到我运行这个项目,它才开始工作。xcode编辑器继续标记未知的swift类,直到我单击“run”。构建成功了,快速的方法奏效了。

#1


16  

Here's how I have gotten it to work. You can see a more large-scale answer here.

这是我的工作方式。你可以在这里看到更大规模的答案。

Change this:

改变:

class HelloWorld {    
    func hello() {
        println("hello world")
    }
}

To:

:

@objc class HelloWorld { 

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

    func hello() {
        println("hello world")
    }
}

Then, In your ObjC file:

然后,在你的ObjC文件中:

#import "TestApp-Swift.h"

And call like this:

并调用如下:

HelloWorld * helloWorld = [HelloWorld newInstance];
[helloWorld hello];

#2


14  

tl;dr Ensure you have a bridging header if you're doing any cross-calling between Objective-C and Swift.

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

I had the exact same problem: I could see the -Swift.h file in DerivedData but it made no mention of my Swift classes. I was importing the header file correctly, the Defines Module setting was YES, and the Product Module Name was correct. I tried deleting and re-adding the Swift files, clean buiild, quitting XCode, etc, with no luck.

我有一个完全相同的问题:我能看到-斯威夫特。h文件在DerivedData,但它没有提到我的Swift类。我正确地导入了头文件,定义的模块设置是YES,并且产品模块名称是正确的。我尝试删除和重新添加Swift文件,干净的bui,退出XCode等,没有运气。

Then I realised I had no -Bridging-Header.h file in my project, presumably due to the way I'd cobbled it together from a previous project. Shouldn't be a problem because I was not (yet) calling Objective-C from Swift. But when I added a bridging header, and referred to its path in the build settings (Swift Compiler - Code Generation -> Objective-C Bridging Header), it magically fixed the problem - my -Swift.h file was suddenly full of SWIFT_CLASS() goodness!

然后我意识到我没有- bridgingheader。h文件在我的项目中,大概是由于我从先前的项目中拼凑起来的方法。不应该是个问题,因为我还没有从Swift调用Objective-C。但是,当我添加一个桥接头,并在构建设置中引用它的路径时(Swift编译器-代码生成-> Objective-C桥接头),它神奇地解决了问题—我的-Swift。h文件突然充满了SWIFT_CLASS()的好处!

So I'm guessing the bridging header is fundamental to the process, even if you're NOT using Objective-C from Swift.

所以我猜想桥接头是这个过程的基础,即使你不使用Swift的Objective-C。


UPDATE: I finally understand this. It is related to public/internal access modifiers. Not sure if I missed this originally or if it's an addition to the Apple docs, but it now clearly states:-

更新:我终于明白了。它与公共/内部访问修饰符相关。我不确定我是否漏掉了这个,或者它是苹果文档的一个补充,但它现在清楚地说明了:-。

By default, the generated header contains interfaces for Swift declarations marked with the public modifier. It also contains those marked with the internal modifier if your app target has an Objective-C bridging header.

默认情况下,生成的头包含与公共修饰符标记的Swift声明的接口。如果你的应用目标有一个Objective-C桥接头,它也会包含那些带有内部修饰符的标记。

#3


9  

It is proper to use #import "TestAppModule-Swift.h" in your .m files. If you need to reference a class in a .h, use the @class forward declaration.

使用#import“TestAppModule-Swift”是正确的。在你的。m文件中。如果需要在.h中引用一个类,请使用@class forward声明。

Further, if you want to use a Swift class from Objective-C, the Swift class must be marked with the @objc attribute. Xcode will only include classes with that attributed in the generated header. See also this documentation.

此外,如果您想要使用Objective-C中的Swift类,那么Swift类必须用@objc属性标记。Xcode只包含在生成的标题中包含该属性的类。看到这个文档。

#4


7  

Class should be declared as @objc public class

类应该声明为@objc public类。

#5


2  

A more convenient way would be to inherit from NSObject. Like so:

更方便的方法是继承NSObject。像这样:

class HelloWorld: NSObject {    
    func hello() {
        println("hello world")
    }
}

#6


0  

In my case the class was not being compiled, because I first added it to my test target only... After adding it to my main target (Build Phases -> Compile Sources), it was actual compiled and added to the header file.

在我的例子中,这个类没有被编译,因为我只把它添加到我的测试目标中…在将它添加到我的主要目标(构建阶段->编译源)之后,它被实际编译并添加到头文件中。

So much for TDD ;-)

TDD的太多了;-)

#7


0  

In my case, by following Apple guidelines, it did not work until I ran the project. The xcode editor kept flagging the unknown swift class, until i clicked "run". The build succeeded, and the swift method worked.

在我的案例中,按照苹果的指导方针,直到我运行这个项目,它才开始工作。xcode编辑器继续标记未知的swift类,直到我单击“run”。构建成功了,快速的方法奏效了。