我正在尝试没有运气的Swift和ObjectiveC混合项目。
我的项目由6个目标组成:
我已经能够添加一个具有一个目标成员资格(App)的Swift类,并使用从 App-Bridging-Header.h 传递的ObjectiveC代码。“将ObjectiveC转换为Swift代码”范例就像一个魅力。
取而代之的是,我正在苦苦应对“ Swift into ObjectiveC代码”范例。在特定情况下,我需要在ObjectiveC .m文件中使用一个新的Swift类,该文件是四个目标的成员。
到目前为止,我一直在做的是:
我遵循了Apple的Mix and Match指南以及许多SO线程,其中包括该线程,显然可以解决我的相同问题,但它不起作用。
还尝试了删除衍生数据以及清理整个项目几次,但都没有运气。
编辑1:更多详细信息
这是我的Swift类导入RealmSwift的声明
@objc class MyClass: Object {}
这是在ObjectiveC中使用Swift类的摘要
MyClass *app = [[MyClass alloc] init];
如果我避免使用#import …- Swift.h,则构建失败会说我正在使用未声明的标识符“ MyClass”,这很合理。
如果我确实使用#import …- Swift.h文件,则说明模块X找不到模块Y,依此类推。
编辑2:Swift模块名称
通过查看每个目标的 SWIFT_OBJC_INTERFACE_HEADER_NAME 属性,我看到它是使用 $(SWIFT_MODULE_NAME)-Swift.h 语法 构建的 。是否需要将 SWIFT_MODULE_NAME 更改为 MODULE_NAME ?
编辑3:进口
这是.m ObjectiveC文件中Swift标头的导入集。我正在使用在相对的“构建设置”属性中指定的模块名称。注意,由于WatchKit Extension目标在目标名称中有一个空格,因此它具有“ _”字符。
#import "ProjectName_App-Swift.h" #import "ProjectName_Core-Swift.h" #import "ProjectName_Summary-Swift.h" #import "ProjectName_WatchKit_Extension-Swift.h"
编辑4:-Swift.h文件的交叉可见性
我尝试了以下方法:
当为多个目标定义了Swift类,并且这些多个目标使用了ObjectiveC文件时,它将不起作用。生成错误是这样的:找不到目标X->“ProjectName_TargetY-Swift.h”文件。似乎一个目标无法看到其他目标-Swift.h文件。
我究竟做错了什么?谢谢你的帮助
我在Edit 4中所做的假设被证明是正确的。如果项目有多个目标,则无法将“-Swift.h”文件全部导入到一个.m ObjectiveC文件中。
因此,必须采用一种解决方案,即更改 SWIFT_OBJC_INTERFACE_HEADER_NAME的 构建设置,并使其在不同目标上相同。这样做的改变,产生从这个属性的指令 $(SWIFT_MODULE_NAME)-Swift.h 到 $(PROJECT_NAME)-Swift.h
还可以将“构建设置”中的“产品模块名称”设置设置为在您的模块之间相同(我将其设置为$(PROJECT_NAME)),以便生成的- Swift.h文件在所有模块中具有相同的名称。 。这消除了添加/检查预处理器宏的需要。
完成此操作后,按Alt并进入“产品”菜单,即可清理构建文件夹。由于标头名称在目标之间共享,现在可以将其一次导入.m ObjectiveC文件,并且所有目标都可以从Swift类中受益。
如果构建后仍然显示错误,请确保通过Cmd单击其名称可以从XCode到达标头。它应该打开一个包含类似于以下代码的文件:
SWIFT_CLASS("_TtC27ProjectName_Summary11MyClass") @interface MyClass : NSObject - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; @end
如果需要确保正在生成这些标头,请打开终端并使用此命令
find ~/Library/Developer/Xcode/DerivedData -name "*Swift.h"
您应该为每个目标看到一个标题
这些更改之后发生在我身上的另一个问题是,它开始给我没有碰到的ObjectiveC代码带来错误。问题出在这里,是由于进口的位置:
正是在.m文件顶部的位置,#import隐藏的桥接标头可以有所作为。麻烦的通常迹象是,您收到“未知类型名称”的编译错误,其中未知类型是在Objective- C中声明的类。解决方案是,在#import隐藏的桥接头文件之前,#import .h文件也包含Objective- C文件中的未知类型的声明。这样做可能会很烦,特别是如果所讨论的Objective-C文件不需要了解此类时,它可以解决问题并允许进行编译。
最后,代码将在设备和模拟器上编译并运行!