Swift to Objective-C头未在Xcode 6中创建

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

在向项目中添加Swift源文件时,我对获得“桥接头”没有任何问题,也就是说,Objective-C到Swift。

但是*-Swift.h头文件应该公开Swift类,标记为@objc或ObjC类的子类,是地方:-(

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

我是首席开发人员的应用程序有一个相当大的代码库(70.000行),所以一次性过渡它是不可能的。

95192 次浏览

你必须在Objective-C类中导入一个头文件,它是:

#import “ProductModuleName-Swift.h”

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

现在它起作用了。

  1. 项目必须有一个产品模块名,其中包含空格。
  2. 定义模块必须设置为是的在构建设置,在包装下。

最后的作品。感谢大家的帮助:-)

如果你的项目模块名中有空格,你必须用下划线替换空格。

例如,如果你的项目名称是“My project”,你可以使用:

#进口“My_Project-Swift.h”

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

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

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

#import "ProductModuleName-Swift.h"

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

唯一重要的是:*

在目标中使用定义的“产品模块名”,后跟-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.

无论“定义模块”参数设置为“是”或“否”,或“产品模块名称”项目未设置。

提醒:Swift类必须派生自NSObject或被标记为@objc属性,以便暴露给ObjectiveC / Foundation || Cocoa…

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

我发现了一个对我很管用的小窍门。

  1. 在你的appDelegate.h文件和ProductName-Prefix中创建你的#import "ProductModuleName-Swift.h"pch文件。如果你在xcode 6中没有它,你可以用为什么ProjectName-Prefix ?在Xcode 6中自动创建pch ?来创建它
  2. 命令+shift+k来清理你的代码,如果你收到一个关于“ProductModuleName-Swift.h”的错误,将它从appDelegate.h文件中删除。
  3. 再次清理代码。现在一切都会像魔法一样起作用
  4. 如果你再次收到关于“ProductModuleName-Swift.h”的错误,现在在appDelegate.h文件中重新创建,并再次清理代码。

每次你收到这个错误的时候都要做这个工作(从appDelegate.h文件中删除并创建“ProductModuleName-Swift.h”,然后清理你的代码)来静音它。

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

对我来说,问题是这是一个先有鸡还是先有蛋的问题,在我实际上注释掉#import语句之前,我没有看到任何构建错误:

< p > <代码> / / #进口“ProductModuleName-Swift.h” < /代码> < / p >

这显示了我的Swift代码中的一堆其他错误。

一旦我修复了这些新错误并成功地获得了源代码构建,我就取消了#import的注释,对了!头文件被创建并正确导入:)

文件名的前面总是你的目标名称。它被称为产品名称,但实际上它是目标名称。 因此,如果你想为一个新目标构建它,准备好期待that_target-Swift.h文件。< / p >

一种处理方法是

  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

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

  1. 如果您不使用PCH文件,只需在单个头文件中添加这些相同的行,并在需要使用swift类的任何地方包含该头文件。

这应该可以正常工作。

项目中没有创建实际文件 ([ProductModuleName] -Swift.h)。Cmd +单击导入,要么实时生成(并在内存中),这样你就可以看到链接是如何完成的,要么在Xcode缓存目录中打开一个文件,但它不在项目目录中。

你需要将定义模块项目道具(在目标的Build Settings中)设置为是的,如果你的模块名中有空格或破折号——在[ProductModuleName]- swift .h文件的所有导入中使用_。

你可以在所有使用swift类型的.h和.m文件中导入它,也可以在.pch文件中导入它。

所以如果我的模块(项目)被命名为“测试项目”,我将像这样导入它,在我的项目的。pch文件中(就在那里):

#import "Test_Project-Swift.h"

如果你像我一样,你可能把标题名搞错了。在我的头猛击了一段时间后,我在DerivedData中寻找文件,果然它在那里。在我的设置(使用标准派生数据文件夹,我相信):

cd ~/Library/Developer/Xcode/DerivedData
find * -iname '*Swift.h'

会找到的。如果文件夹中没有匹配的内容,Xcode就不会生成它。

我使用的Xcode版本6.2 (6C86e)

如果Xcode实际上生成了你的-Swift.h头(在DerivedData的深处),但它没有引用你的Swift类,请确保你也定义了一个桥接头。我阅读文档的方式暗示我只需要从Swift调用Objective-C,但似乎从Objective-C调用Swift也是必要的。

请看我的答案:https://stackoverflow.com/a/27972946/337392

编辑:这是因为公共和内部访问修改器,正如我最终在苹果文档中发现的解释:-

默认情况下,生成的头部包含Swift接口 用公共修饰符标记的声明。它还包含了 如果你的应用目标有 Objective-C桥接头。

我找到了这个解决方案

  • 创建SwiftBridge.h
  • 导入" ProductModuleName-Swift.h "
  • 将此.h文件公开(重要)选择该文件->在“显示文件检查器”中(右栏)->将其公开

现在你可以

#import "SwiftBridge.h"

而不是ProductModuleName-Swift.h

这是一个变通的解决方案,对于下一个版本的Xcode,我认为这个问题将得到解决。 祝你好运< / p >

只是提醒那些在项目名称中使用“。”的人。对于Swift版本的桥接头文件,Xcode将用下划线“_”替换“。”。奇怪的是,生成的Bridging-Header.h不会用下划线替换句点。

例如,一个名为My的项目。项目将具有以下桥接头文件名。

Bridging-Header.h(自动生成)

My.Project-Bridging-Header.h

Swift.h

My_Project.h

我希望这能帮助那些像我一样用了大姨妈却被困住的人。该文件可以在以下位置找到。

Macintosh HD /用户/ 用户 /图书馆/开发/ Xcode / DerivedData / My.Project-fntdulwpbhbbzdbyrkhanemcrfil /构建/中间体/ My.Project.build Debug-iphonesimulator / My.Project.build / DerivedSources

当心

乔恩

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

问题变得非常非常简单——我没有将我的任何Swift类声明为public!一旦我将public关键字添加到类中,我就可以从框架内外的类中使用它们了。

同样值得注意的是,在框架内(只有在。m文件内,另一个答案提到),我必须导入-Swift.h文件:

#import <FrameworkName/FrameworkName-Swift.h>

这个答案解决了你可能已经有一些Objective-C代码调用Swift类,然后你开始收到这个错误的用例。

如何解决问题

接下来的步骤最终为我解决了所有问题。我在上面读到有人提到“鸡和蛋”,正是这个概念让我想到了这个过程。这个显式的过程表明,在生成头文件之前,必须删除任何引用Swift类的Objective-C代码。

    注释掉#import "ProductModuleName-Swift.h"语句 你的Objective-C实现文件
  1. 注释掉Objective-C实现文件中的任何引用 李迅速类< / >
  2. 清洁,构建
  3. 解决所有错误/警告
  4. 删除#import "ProductModuleName-Swift.h"语句上的注释
  5. 清洁,验证你在Objective-C中没有引用任何Swift类. build(成功地或修复任何剩余的错误)。如果是的话,暂时把这些注释掉)
  6. 验证“ProductModuleName-Swift.h”是由 cmd - click生成的 在#import "ProductModuleName-Swift.h"语句的类名上
  7. 删除Objective-C实现文件中引用Swift类的代码上的注释。
  8. <李>清洁,正常构建(“ProductModuleName-Swift.h”应该是 生成和你的Objective-C代码引用Swift类可以 正常使用)

注意:关于将空格更改为下划线和上面给出的定义模块为YES的答案在执行此过程时仍然适用,正如苹果公司的文档中指定的规则一样。

桥接头路径

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

< p > & lt;未知>:0:错误:桥接头 /Users/Shared/Working/abc/abc- bridging - header .h不存在

对错误的进一步检查表明,该文件永远不会存在于描述的位置,因为它实际上位于(错误的道路)

' /用户/共享/工作/ abc / abc / abc-Bridging-Header.h’。快速搜索目标/项目构建设置,手动进行更正,abc-Swift.h文件再次自动生成。

build-settings

这里是没有生成的moduleName-Swift.h的另一个变体。

我决定在我的项目中包含IOS图表,但不想将源代码混合在同一个目录中,所以我将图表项目文件夹放在我代码的项目文件夹旁边。我将图表项目拖到我的项目的导航栏中,并将框架包含在我的项目目标的嵌入二进制文件< em > < / em >列表中的一般项目设置中,并在我的项目的< em > < / em >构建选项部分的< < em >构建设置/ em >选项卡中将嵌入式内容包含Swift代码开关设置为yes。

我的项目的moduleName-Swift.h文件永远不会生成,不管这里建议了什么其他开关或设置。最后,使用Lou Z的方法查找-Swift.h文件,我看到在我的项目的xcode Build目录Charts.framework/Headers/深处生成了一个Charts-Swift.h文件

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

#import "Charts/Charts-Swift.h"

到记录项目数据的模块。

如果你以前能够构建一个项目,没有与“ProductModuleName-Swift.h” not found错误相关的问题,而现在你又得到了那个讨厌的错误,原因可能是你最近的更改。

对我来说,这是由(偶然)不正确的.swift文件编码。恢复更改并手动恢复即可完成这项工作。

我很难确定我的模块名/objective-c对swift头文件的导入。我在这里也读了很多文章。

但你的项目名称的最终答案,包括所有的特殊字符(是它'。'或一个数字或一个空格)-你可以在目标的构建设置下的“产品模块名称”中找到适合你的文本。

例如,我的目标名称以数字-“1mg”开头,上面提到的字段显示“_mg”作为我的模块名。

所以我使用#import "_mg-Swift.h",它工作了。

目标的构建设置中的产品模块名称给出了正确的模块名称,这将为您的项目工作

这可能是一个明显的点(也许太明显了),但是您必须在项目中至少有一个swift文件来生成头文件。如果您正在编写样板或配置代码,意图稍后编写swift,则导入将不起作用。

请允许我分享我在一个旧的objc项目中尝试使用Swift的经验。我不需要将Defines module设置为YES

在我的情况下,我需要手动确保有一个objc桥接头。在我的构建设置中只出现了生成的接口头名称。

缺少桥接头

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

苹果文档说,当你添加你的第一个swift文件时,会提示你创建一个桥接头。我没有。我手动添加了一个MyApp-Bridging-header.h文件,并在“Objective-C Bridging Header”字段中指向它。这使得我的MyApp-Swift.h文件被我的Swift类填充。

文档:将Swift导入Objective-C

我不得不从我的Objective C项目中删除WatchOS2 swift代码。在那之后XCode才提供生成-Swift.h

在我的情况下,我必须将部署目标设置为至少“OS X 10.9”,并且自动生成-Swift.h报头。请记住,当您更改部署目标版本时,您可能会得到许多弃用警告,特别是当您有一个旧的和非常大的Objective C代码库时。在我们的例子中,我们在XIB文件中也有很多工作要做。视图类。

我也有类似的问题,但我的项目之前正在编译,在几个文件代码更改后突然出现错误。我花了一段时间才弄清楚为什么我的project-swift.h文件会出现“文件未找到”错误。我所做的代码更改有一些错误。Xcode并没有指出这些错误,而是一直显示“文件未找到错误”。然后我得到了之前版本的代码,并与新代码进行了逐一的比较和合并文件。在每个文件合并后,编译项目以查找错误。所以底线是,如果你的代码中有错误,Xcode会在myproject-swift。h文件中显示" file not found error "您的项目中很可能存在编译错误。清除这些错误,它将工作。

项目必须有一个不包含空格的模块名。 “定义模块”必须在“生成设置”中的“打包”下设置为“是”。 注释掉#import语句:

如果您在导入“ProductModuleName-Swift.h”时仍然有错误,那么

/ / #进口“ProductModuleName-Swift.h”

这显示了我的Swift代码中的一堆其他错误。

一旦我修复了这些新的错误,并成功地获得了源代码构建,我取消了#import的注释,没错!头文件被创建并正确导入:)

附议很多人在这里,但增加一个相关的屏幕截图。Swift和Obj-C代码当然可以共存。这不是全有或全无的游戏。

要在Objective-C中访问Swift文件,你所需要做的就是将这个调用添加到你的Obj-C文件中(在.m /实现文件中):

#import "{product_module_name}-Swift.h"

(其中{product_module_name}表示项目的产品模块名称)。而不是尝试猜测你的产品模块名称或找出带有空格和特殊字符的角落案例,只需进入项目中的构建设置选项卡并键入“产品模块名称”-检查器将显示给你。我的经历是我没有预料到的。如果你感到困惑,可以看看这个屏幕截图。

enter image description here

为了让Obj-c代码在Swift中工作,你只需要添加一个桥接头文件,并导入相关的Obj-c头文件。

好的,这些都是你真正需要的东西!

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

----------

enter image description here

----------

< p > <强> 2。转到“Projects”构建设置,并设置产品模块名称。 项目必须有一个不包含空格的产品模块名称

----------

enter image description here

----------

3.“定义模块”必须在“生成设置”中,在“打包”下,在项目中设置为“是”,而不是“目标”!

----------

enter image description here

----------

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

----------

enter image description here

----------

它将请求创建一个桥接头,允许它创建一个桥接头。 如果你已经拒绝了一次,你将不得不手动添加一个-Bridging-Header.h

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

----------

enter image description here

----------

6.构建项目并在任何objective - c控制器中导入#import "-Swift.h",它就可以工作了!你可以Command-click它来查看实际的文件!

----------

enter image description here

----------

希望这能有所帮助!

如果您正在使用Cocoapods之类的东西(并且在工作空间而不是项目中工作),请尝试在打开工作空间和构建之前打开项目并构建它。YMMV。

有时你只需要在obj-c .m文件上取消设置,然后重新设置目标成员。

文件正在生成,但Xcode无法找到它(我使用Lou Zell的答案来证明它正在生成)。

这是我对混合ObjC/Swift框架的修复(Xcode 9.2):

  1. 在finder (TargetName-Swift.h)中搜索,在DerivedData中找到预期生成的文件
  2. 将它拖到XCode和取消复制文件中的项目中。
  3. 单击XCode中的文件并打开文件检查器(右侧面板的第一个选项卡)。
  4. 位置相对于组更改为相对于构建产品

前两个步骤应该可以让你很好地构建和使用你的项目,但最后两个步骤允许它在其他计算机上工作(即在团队项目中协作时仍然可以工作)。