我最近一直在努力将Swift添加到一个现有的项目中,以便在现实世界中进行尝试。
在向项目中添加Swift源文件时,我对获得“桥接头”没有任何问题,也就是说,Objective-C到Swift。
但是*-Swift.h头文件应该公开Swift类,无论是标记为@objc的类还是ObjC类的子类,都找不到:-(
在我的主应用程序代码(仍然是Objective-C)中,我没有看到任何关于如何使用我的新子类的具体说明,用Swift编写。
我是首席开发人员的应用程序有一个相当大的代码库(70.000行),所以一次性过渡它是不可能的。
文件名的前面总是您的目标名称。它被称为产品名称,但实际上它是目标名称。
因此,如果你想为一个新目标构建它,准备好期待that_target-Swift.h文件。
一种处理方法是
为每个目标添加一个预处理器,它是目标本身的名称(不带空格)。MY_TARGET = 1。将此添加到项目设置->构建设置->预处理器宏为每个目标。
如果您正在使用PCH文件,
在PCH文件中添加这些行
#if MY_TARGET==1
#include "My_Target-Swift.h"
#elif THAT_TARGET==1
#include "That_Target-Swift.h"
#endif
使用PCH文件的优点是您不必在任何地方都包含头文件。
如果您不使用PCH文件,只需在单个头文件中添加这些相同的行,并在需要使用swift类的任何地方包含该头文件。
这应该可以正常工作。
项目中不创建实际文件([ProductModuleName]-Swift.h)。Cmd +单击导入,要么实时生成(并在内存中),这样你就可以看到链接是如何完成的,要么在Xcode缓存目录中打开一个文件,但它不在项目目录中。
你需要将定义模块项目道具(在目标的构建设置中)设置为Yes,如果你的模块名中有空格或破折号,在[ProductModuleName]- swift .h文件的所有导入中使用_。
你可以在所有使用swift类型的.h和.m文件中导入它,也可以在.pch文件中导入它。
所以如果我的模块(项目)被命名为“测试项目”,我将像这样导入它,在我的项目的。pch文件中(就在那里):
#import "Test_Project-Swift.h"
只是提醒那些在项目名称中使用“。”的人。对于Swift版本的桥接头文件,Xcode将用下划线“_”替换“。”。奇怪的是,生成的Bridging-Header.h不会用下划线替换句点。
例如,一个名为My的项目。项目将具有以下桥接头文件名。
Bridging-Header.h(自动生成)
My.Project-Bridging-Header.h
Swift.h
My_Project.h
我希望这能帮助那些像我一样用了大姨妈却被困住的人。该文件可以在以下位置找到。
麦金塔HD / \用户/用户/ Library /开发商Xcode DerivedData /我。Project-fntdulwpbhbbzdbyrkhanemcrfil /构建/ Intermediates构建Debug-iphonesimulator /我的项目。项目构建- DerivedSources。
当心
Jon
这个答案解决了你可能已经有一些Objective-C代码调用Swift类,然后你开始收到这个错误的用例。
如何解决问题
接下来的步骤最终为我解决了所有问题。我在上面读到有人提到“鸡和蛋”,正是这个概念让我想到了这个过程。这个显式的过程表明,在生成头文件之前,必须删除任何引用Swift类的Objective-C代码。
Comment out the #import "ProductModuleName-Swift.h" statement in
your Objective-C implementation file
Comment out any references in the Objective-C implementation file to
Swift Classes
Clean & Build
Resolve all errors/warnings
Remove the comment on the #import "ProductModuleName-Swift.h" statement
Clean & build (successfully or fix any remaining errors, verify that you are not referencing any Swift classes in Objective-C at this point. If so temporarily comment these out)
Verify that "ProductModuleName-Swift.h" is generated by Cmd-Clicking
on the class name of the #import "ProductModuleName-Swift.h" statement
Remove the comment on the code referencing Swift classes in the Objective-C implementation file.
Clean & Build as normal (the "ProductModuleName-Swift.h" should be
generated and your Objective-C code referencing Swift Classes can be
used as normal)
注意:在执行此过程时,关于将空格更改为下划线和将定义模块更改为YES的答案仍然适用,正如Apple文档中指定的规则一样。
桥接头路径
在一个错误中,在构建过程中没有找到文件ProductModuleName-Bridging-Header.h。这一事实产生了一个错误
< unknown>:0:错误:桥接头
“/Users/Shared/Working/abc/abc- bridging - header .h”不存在
对错误的进一步检查表明,该文件永远不会存在于所描述的位置,因为它实际上位于(错误的路径)
' /用户/共享/工作/ abc / abc / abc-Bridging-Header.h’。快速搜索目标/项目构建设置,手动进行更正,abc-Swift.h文件再次自动生成。
这里是没有生成的moduleName-Swift.h的另一个变体。
我决定在我的项目中包含IOS图表,但不想将源代码混合在同一个目录中,所以我将图表项目文件夹放在我代码的项目文件夹旁边。我将图表项目拖到项目的导航栏中,并将框架包含在项目目标的“通用项目设置”的“嵌入式二进制文件”列表中,并在“构建选项”部分的“构建设置”选项卡中将“嵌入内容包含Swift代码”开关设置为“是”。
我的项目的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"
到记录项目数据的模块。
附议很多人在这里,但增加一个相关的屏幕截图。Swift和Obj-C代码当然可以共存。这不是全有或全无的游戏。
要在Objective-C中访问Swift文件,你所需要做的就是将这个调用添加到你的Obj-C文件中(在.m /实现文件中):
#import "{product_module_name}-Swift.h"
(其中{product_module_name}表示项目的产品模块名称)。而不是尝试猜测你的产品模块名称或找出带有空格和特殊字符的角落案例,只需进入项目中的构建设置选项卡并键入“产品模块名称”-检查器将显示给你。我的经历是我没有预料到的。如果你感到困惑,可以看看这个屏幕截图。
为了让Obj-c代码在Swift中工作,你只需要添加一个桥接头文件,并导入相关的Obj-c头文件。
好的,这些都是你真正需要的东西!
1.删除您添加的所有swift文件,并编译代码,没有任何错误。
----------
----------
2.转到“Projects”构建设置,并设置产品模块名称。
项目必须具有不包括空格的产品模块名称。
----------
----------
3.“定义模块”必须在“生成设置”中,在“打包”下,在项目中设置为“是”,而不是“目标”!
----------
----------
4.现在创建一个swift文件或视图控制器,在file-> newFile->中
----------
----------
它会请求创建一个桥接头,允许它创建一个桥接头。
如果你拒绝了一次,你必须手动添加一个-Bridging-Header.h
5.在控制器中添加@objc,告诉编译器有一些swift文件需要暴露给objecvec
----------
----------
6.构建项目并在任何objective - c控制器中导入#import "-Swift.h",它就可以工作了!你可以Command-click它来查看实际的文件!
----------
----------
希望这能有所帮助!