我的项目由6个目标组成:
> App
>核心
> CoreTest
>总结
> WatchKit扩展
> WatchKit应用程序
我已经能够添加一个具有一个目标成员资格(App)的Swift类,并使用从App-Bridging-Header.h传递的ObjectiveC代码
“ObjectiveC into Swift code”范例就像一个魅力。
相反,我正在努力使用“Swift into ObjectiveC code”范例。
在特定情况下,我需要在ObjectiveC .m文件中使用一个新的Swift类,该文件是四个目标的成员。
到目前为止我一直在做的是:
>将新的Swift文件添加到Core项目,指定四个成员资格(App,Core,Summary,WatchKit Ext)
> XCode要求为三个项目创建-Bridging-Header.h Core,Summary和WatchKit Ext(App-Bridging-Header.h已经存在,因为之前已经使用过),我同意(不知道为什么它会创建这些文件)在我添加我的Swift类的同一组文件夹中但是没关系)
>我创建了Swift类,在课前添加了@objc键
>我去检查是否为所有模块设置了Objective-C Generated Interface Header Name,是的
>我去检查所有模块中的Defines Module是否设置为No,并在主项目中设置为Yes,是的
>我写下了所有四个目标的-Swift.h文件的导入
>在我的Objective-C类中,我尝试使用我的新Swift类,显然它似乎工作(甚至自动完成)
>我尝试构建项目,但它没有说找不到-Swift.h文件
我已经关注了Mix and Match guide of Apple和许多SO线程,包括this one似乎显然是为了解决我的同样问题,但它不起作用。
还尝试过删除派生数据以及多次清理整个项目而没有运气。
编辑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头的导入集。
我正在使用相对Build Settings属性中指定的模块名称。请注意,由于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类
> XCode创建了Bridging Header
>在仅由App使用的ObjectiveC文件中插入#import“ProjectName_App-Swift.h”
>在此文件中使用Swift类
>它汇编!我可以使用Swift类
当为多个目标定义Swift类并且这些多个目标使用ObjectiveC文件时,它不起作用。构建错误是这样的:目标X – >找不到“ProjectName_TargetY-Swift.h”文件。
好像目标无法看到其他目标-Swift.h文件。
我究竟做错了什么?
谢谢你的帮助
解决方法
如果项目有多个目标,则无法在一个.m ObjectiveC文件中导入“-Swift.h”文件。
因此,必须采用一种解决方案,即更改SWIFT_OBJC_INTERFACE_HEADER_NAME构建设置并使其在不同目标中保持相同。
为此,请将生成此属性的指令从$(SWIFT_MODULE_NAME)-Swift.h更改为$(PROJECT_NAME)-Swift.h,如here所述
It is also possible to set the Product Module Name setting in Build Settings to be the same across your modules (I set it to $(PROJECT_NAME)),so that the -Swift.h file that is generated has the same name across all modules. This eliminates the need for adding/checking preprocessor macros.
按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代码上给出错误。问题是由于进口的位置,如here所述:
Exactly where at the top of a .m file you #import the hidden bridging header can make a difference. The usual sign of trouble is that you get an “UnkNown type name” compile error,where the unkNown type is a class declared in Objective-C. The solution is to #import the .h file containing the declaration for the unkNown type in your Objective-C files as well,before you #import the hidden bridging header. Having to do this can be an annoyance,especially if the Objective-C file in question has no need to kNow about this class,but it resolves the issue and allows compilation to proceed.
在最后,代码编译并在设备和模拟器上运行!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。