不是在Xcode 6中创建的Swift到Objective-C头

Dav*_*sen 239 xcode objective-c swift

我最近一直在努力将Swift添加到现有项目中,以现实世界的方式进行尝试.

在向项目添加Swift源文件后,我没有遇到"桥接标题"的问题,即Objective-C到Swift.

但是*-Swift.h应该公开Swift类标题@objc或ObjC类的子类的头文件无处可寻:-(

在我的主应用程序代码(仍然是Objective-C)中,我没有看到任何关于如何使用Swift编写的新子类的使用的具体说明.

我是主要开发人员的应用程序拥有相当大的代码库(70.000行),因此一次性转换它是不可能的.

Dav*_*sen 164

现在它有效.

  1. 项目必须具有包含空格的产品模块名称.
  2. 在"打包"下的"构建设置"中,必须将" 模块"设置为" ".

最后工作.感谢大家的帮助:-)

  • 在`Packaging`下的`Build Settings`中,我的`Defines Module`设置为`Yes`,我创建了一个没有空格的`Product Module Name`.XCode 6不生成"*-Swift.h". (64认同)
  • 另外一个注意事项:我首先尝试在目标级别设置上述属性,但它不起作用,未生成文件"*-Swift.h".当我在项目级别设置它时,它工作. (25认同)
  • 我也有同样的问题.我为项目和目标设置了`定义模块'为'是',并定义了一个'产品模块名称',*没有空格*,但我似乎无法生成这个文件. (22认同)
  • 您不能仅在实现中导入-swift头文件(.h). (13认同)
  • 以防万一其他人像我一样困惑...我不得不在这里盲目运气,只需导入标题,因为它不会自动完成. (8认同)
  • 另请注意:项目中不会添加实际文件.它生成到"DerivedSources"下的临时构建目录中. (6认同)
  • 请注意,"ProductModuleName-Swift.h"实际上不会像Klaas所提到的那样出现在您的项目中.键入#import"ProductModuleName-Swift.h"(即使它不会自动完成)和构建(如sgawbwall所说).在我的情况下这是有效的. (3认同)
  • 您应该提交有关空格的错误报告.如果您尝试在Swift模块名称中使用空格,Xcode应该会抱怨.http://bugreport.apple.com (2认同)
  • 确保选择“全部”(“构建设置”视口的左上角)。仅选择“基本”时您不会看到该选项 (2认同)

mac*_*uff 122

我有类似的问题,发现你只能添加

#import “ProductModuleName-Swift.h”

到obj-c .m文件,而不是.h文件,用于找到伞头

  • 对于未来的搜索者:在您的标题中,通过在.h文件的顶部执行@class YourSwiftClass来转发声明(而不是导入伞标题) (14认同)
  • 如果我需要在头文件中使用Swift枚举怎么办? (4认同)
  • 这是正确的,如果我需要在objc头中使用Swift类,该怎么办?我尝试使用前向声明,它也不起作用. (2认同)
  • 哎呀,对不起,前方声明有效.我忘了添加分号:P (2认同)

pet*_*are 58

我发现在生成文件之前我必须修复所有构建错误.

对我来说问题是它是一个鸡/蛋问题,因为在我实际注释掉#import声明之前我没有看到任何构建错误:

//#import "ProductModuleName-Swift.h"

这揭示了我的Swift代码中的一堆其他错误.

一旦我修复了这些新的错误并成功完成了源码构建,我就取消了对#import宾果游戏的注释!标题已创建并正确导入:)

  • 这是一个很好的观点,也是在Xcode中打开"在错误后继续构建"设置的一个很好的理由. (9认同)
  • 看到“鸡/蛋问题”之后,我意识到了我的问题,比喻好 (2认同)

Joh*_*son 43

如果项目模块名称中包含空格,则必须使用下划线替换空格.

例如,如果您的项目名称是"我的项目",您将使用:

#import"My_Project-Swift.h"

  • 如果项目模块名称中包含连字符,则还应使用下划线替换它们.因此,如果您的项目名称是"My-Project",请使用#import"My_Project.h" (10认同)
  • 此外,如果项目模块名称以数字开头,则还应使用下划线替换."1st Project"将是"_st_Project-Swift.h" (5认同)

Lou*_*ell 42

如果你像我一样,你可能会错误地标题.在猛击我的脑袋一段时间之后,我在DerivedData中寻找文件,确定它就在那里.在我的设置上(我相信使用标准的派生数据文件夹):

cd ~/Library/Developer/Xcode/DerivedData
find * -iname '*Swift.h'
Run Code Online (Sandbox Code Playgroud)

会找到它.如果该文件夹中没有任何内容匹配,则Xcode不会生成它.

我正在使用Xcode版本6.2(6C86e)


Luc*_*ier 31

*唯一重要的是:*

在目标中使用定义的"产品模块名称",然后使用-Swift.h

#import <Product Module Name>-Swift.h

// in each ObjectiveC .m file having to use swift classes
// no matter in which swift files these classes sit.
Run Code Online (Sandbox Code Playgroud)

无论"定义模块"参数是否设置为"是"或"否",或者未设置"产品模块名称"项目.

提醒:Swift类必须从NSObject派生或者用@objc属性标记才能暴露给ObjectiveC/Foundation || 可可 ...


Ken*_*ner 25

我想补充一个原因,你可能会发现这个问题 - 我正在创建一个混合了Swift和Objective-C代码的框架.我无法在框架外导入Swift类 - 我检查了-Swift.h文件,它正在生成但是为空.

事实证明这个问题非常非常简单 - 我没有宣布我的任何Swift课程公开!一旦我将public关键字添加到类中,我就可以在框架内外的类中使用它们.

另外值得注意的是,在框架内部(仅在另一个答案中提及.m文件)我必须将-Swift.h文件导入为:

#import <FrameworkName/FrameworkName-Swift.h>
Run Code Online (Sandbox Code Playgroud)

  • 至少在当前的XCode 7预发布中,直到你继承自NSObject,它们将不会在生成的swift头中可用. (3认同)
  • 在Framework I中我还注意到,为了使用Swift类,它们应该从NSObject继承(甚至@objc也无济于事),并且所有方法/属性都应该是公共的. (2认同)
  • 哦,是的,你对导入的暗示终于为我做了诀窍!非常感谢! (2认同)

小智 14

我有同样的问题.添加第一个Swift文件之前,您似乎必须调整设置(定义模块和产品模块名称).

如果你之后这样做,即使你添加了更多Swift文件或删除Swift文件并创建一个新文件,也不会为该项目生成"*-Swift.h"文件.

  • 怎么办?我正在改变Swift和ObjC代码.我的Project-Swift.h没有更新.我甚至试图删除头文件. (2认同)
  • 我不得不写这个,http://dev.iachieved.it/iachievedit/?p = 980.在添加Swift文件之前更新构建设置的提示对我来说很关键. (2认同)

Dee*_*G M 12

文件名始终以您的目标名称开头.它被称为产品名称,但实际上它是目标名称.因此,如果您希望它为新目标构建,请准备好期待that_target-Swift.h文件.

解决这个问题的一种方法是

  1. 为每个目标添加一个预处理器,它是目标本身的名称(不含空格).防爆.MY_TARGET=1.在每个目标的项目设置 - >构建设置 - >预处理器宏中添加此项.
  2. 如果您使用的是PCH文件,

在PCH文件中添加这些行

#if MY_TARGET==1
#include "My_Target-Swift.h"
#elif THAT_TARGET==1
#include "That_Target-Swift.h" 
#endif
Run Code Online (Sandbox Code Playgroud)

使用PCH文件的优点是您不必在任何地方都包含标题.

  1. 如果您没有使用PCH文件,只需在单个标题中添加这些相同的行,并在需要使用swift类的任何位置包含该标题.

这应该工作得很好.


gjp*_*jpc 12

这是另一个未生成moduleName-Swift.h的变体.

我决定在我的项目中包含IOS图表但不想将源代码混合在同一目录中,因此我将Charts Project文件夹放在代码的项目文件夹旁边.我将Charts项目拖到Project的Navigator Bar中,并将框架包含在General项目设置的项目目标的Embedded Binaries列表中,并在Build Options部分的项目Build Settings选项卡中将Embedded Content Contains Swift Code开关设置为yes .

无论此处建议的其他开关或设置如何,我的项目的moduleName-Swift.h文件都不会生成.最后,使用Lou Z寻找-Swift.h文件的方法,我看到在我的项目的Charts.framework/Headers /中的xcode Build目录深处生成了一个Charts-Swift.h文件.

使用Daniel Gindi的ios-charts Swift包而不包含我项目源代码目录中的代码的解决方案是添加:

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

绘制我项目数据的模块.


Nic*_*ahl 12

请允许我分享我在旧的objc项目中使用Swift的经验.我没有必要Defines moduleYES.

在我的情况下,我需要手动确保有一个objc桥接标题.我的构建设置中仅存在生成的接口标题名称.

缺少桥接标题

这导致生成MyApp-Swift.h文件,但没有任何我的Swift类的痕迹.

Apple文档说,在添加第一个swift文件时,系统会提示您创建桥接标头.好吧,我不是.我手动添加了一个MyApp-Bridging-header.h文件并在"Objective-C Bridging Header"字段中指向它.这使我的MyApp-Swift.h文件变成了我的Swift类.

文档:将Swift导入Objective-C


Ech*_*lon 10

如果XCode实际上生成了-Swift.h头文件(深入DerivedData内部),但它没有引用您的Swift类,请确保您还定义了桥接头.我阅读文档的方式暗示我只需要从Swift调用Objective-C,但似乎也需要从Objective-C调用Swift.

请参阅我的回答:https://stackoverflow.com/a/27972946/337392

编辑:这是因为公共与内部访问修饰符,我最终发现在Apple文档中解释: -

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


Bri*_*tta 7

借调很多人在这里所拥有的,但添加了相关的屏幕截图.Swift和Obj-C代码当然可以共存.这不是一场全部或全部比赛.

要访问Objective-C中的Swift文件,您需要做的就是将此调用添加到您的Obj-C文件中(在.m/implementation文件中):

#import "{product_module_name}-Swift.h"
Run Code Online (Sandbox Code Playgroud)

(其中{product_module_name}表示项目的产品模块名称).不要试图猜测您的产品模块名称或找出带有空格和特殊字符的边角情况,只需转到项目中的构建设置选项卡并输入"产品模块名称" - 检查员将向您展示.我的预期是我没想到的.如果您感到困惑,请查看此屏幕截图.

在此输入图像描述

要使Obj-c代码在Swift中工作,您只需添加一个桥接头文件并在那里导入相关的Obj-C头文件.


Tom*_* C. 6

此答案解决了以下用例:您可能已经拥有一些调用 Swift 类的 Objective-C 代码,然后您开始收到此错误。

如何解决问题

以下步骤最终为我解决了所有问题。我在上面读到有人提到“鸡和蛋”,正是这个概念引导我进行了这个程序。这个明确的过程表明,在生成标头之前,必须删除任何引用 Swift 类的 Objective-C 代码。

  1. 注释掉 Objective-C 实现文件中的 #import "ProductModuleName-Swift.h" 语句
  2. 注释掉 Objective-C 实现文件中对 Swift 类的任何引用
  3. 清洁与建造
  4. 解决所有错误/警告
  5. 删除对#import "ProductModuleName-Swift.h" 语句的注释
  6. 清理和构建(成功或修复任何剩余的错误,验证此时您没有引用 Objective-C 中的任何 Swift 类。如果是,请暂时将这些注释掉)
  7. 验证“ProductModuleName-Swift.h”是通过Cmd-Clicking生成 的 #import "ProductModuleName-Swift.h" 语句的类名
  8. 删除 Objective-C 实现文件中引用 Swift 类的代码的注释。
  9. 正常清理和构建(应该生成“ProductModuleName-Swift.h”,并且可以正常使用引用 Swift 类的 Objective-C 代码)

Nota Bene:上面给出的关于将空格更改为下划线和将定义模块更改为 YES 的答案在执行此过程时仍然适用,Apple 文档中指定的规则也是如此。

桥接头路径

在一个错误中,在构建过程中没有找到文件 ProductModuleName-Bridging-Header.h。这个事实产生了一个错误

<未知>:0:错误:桥接头“/Users/Shared/Working/abc/abc-Bridging-Header.h”不存在

对错误的仔细检查表明该文件永远不会存在于所描述的位置,因为它实际上位于(错误的路径

'/Users/Shared/Working/abc/abc/abc-Bridging-Header.h'。快速搜索目标/项目构建设置以手动进行更正,然后再次自动生成 abc-Swift.h 文件。

构建设置


use*_*759 5

最重要的是这个文件是不可见的!!!至少它在 Xcode6 beta5 中。您的工作区中不会有名为“YourModule-Swift.h”的文件。只需确保您有模块名称并将模块定义为 yes,并在您的 Objective-C 类中使用它。


Kak*_*hah 5

好的,这是你真正需要的所有东西!

1.删​​除你添加的所有swift文件,并编译代码,没有任何错误.

----------

在此输入图像描述

----------

2.转到"项目"构建设置,然后设置产品模块名称.项目必须具有不包含空格的产品模块名称.

----------

在此输入图像描述

----------

3.Defines模块必须在项目中的"打包"下的"构建设置"中设置为"是",而不是目标!

----------

在此输入图像描述

----------

4.现在在file-> newFile->中创建一个swift文件或一个视图控制器

----------

在此输入图像描述

----------

它会要求创建一个桥接头,允许它制作一个.如果您拒绝了一次,则必须手动添加-Bridging-Header.h

5.在控制器中添加@objc,告诉编译器有一些swift文件需要暴露给ObjectiveC

----------

在此输入图像描述

----------

6.建立项目并在任何objectiveC控制器中导入#import"-Swift.h",它将起作用!您可以按住Command键单击它以查看实际文件!

----------

在此输入图像描述

----------

希望这可以帮助!


Ant*_*ton 3

您必须在 Objective-C 类中导入标头,即:

\n\n
#import \xe2\x80\x9cProductModuleName-Swift.h\xe2\x80\x9d\n
Run Code Online (Sandbox Code Playgroud)\n\n

它是自动生成的,在引用中它说“目标中的任何 Swift 文件都将在包含此导入语句的 Objective-C .m 文件中可见”。

\n

  • 但是,当我这样做时,我收到构建错误,AppName-Swift.h 不存在。然而,AppName-Bridging-Header.h 确实存在。 (24认同)
  • @DavidKristensen:你得到解决了吗?因为我也遇到了同样的问题 (5认同)