在xcode8中找不到ModuleName-Swift.h文件

我试图在没有运气的混合Swift和ObjectiveC项目上工作。

我的项目是由6个目标组成的:

  • 应用
  • 核心
  • CoreTest
  • 概要
  • WatchKit扩展
  • WatchKit应用程序

我已经能够添加一个具有一个目标成员资格(App)的Swift类,并使用从App-Bridging-Header.h传递的ObjectiveC代码。“ObjectiveC into Swift code”范例就像一个魅力。

相反,我正在用“Swift into ObjectiveC code”范式挣扎。 在具体的情况下,我需要在四个目标的成员ObjectiveC .m文件中使用一个新的Swift类。

我到目前为止所做的是这样的:

  1. 添加一个新的Swift文件到Core项目,指定四个成员(App,Core,Summary,WatchKit Ext)
  2. XCode要求为三个项目Core,Summary和WatchKit Ext(App-Bridging-Header.h已经存在,因为它以前使用过)创build了-Bridging-Header.h ,并且我同意(不知道为什么它会在里面创build这些文件相同的组文件夹,我添加我的Swift类,但从来没有)
  3. 我在课前创build了Swift类,添加了@objc
  4. 我去检查是否为所有模块设置Objective-C生成的接口标题名称 ,是的
  5. 我去检查Defines模块是否在所有模块中设置为No ,并且在主项目中设置为Yes ,是的
  6. 我记下所有四个目标的-Swift.h文件的导入
  7. 在我的Objective-C类里,我尝试使用我的新Swift类,显然它似乎工作(甚至自动完成)
  8. 我试图build立该项目,但它没有说-Swift.h文件没有find

我遵循苹果公司的混合和匹配指南和许多SO线程,包括这个似乎显然是为了解决我的同样的问题,但它不工作。

也见过这个 ,但没有工作。

已经尝试删除派生数据以及清理整个项目几次,没有运气。

编辑1:更多细节

这是我的Swift类导入RealmSwift的声明

@objc class MyClass: Object {} 

这是ObjectiveC中Swift类的使用片段

 MyClass *app = [[MyClass alloc] init]; 

如果我避免使用#import …- Swift.h,构build失败,说我正在使用未声明的标识符“MyClass”,这是健全的。

如果我使用#import …- Swift.h文件,它说模块X找不到模块Y等等。

编辑2:Swift模块名称

通过查看每个目标的SWIFT_OBJC_INTERFACE_HEADER_NAME属性,我已经看到它是使用这种语法$(SWIFT_MODULE_NAME)-Swift.h构build的 ,是否需要将SWIFT_MODULE_NAME更改为MODULE_NAME

编辑3:import

这是.m ObjectiveC文件中Swift头文件的导入集合。 我正在使用相关的“生成设置”属性中指定的模块名称。 请注意,由于WatchKit扩展目标在目标名称中有一个空格,因此具有“_”字符。

 #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创build了桥接头
  • 在仅由App使用的ObjectiveC文件中插入#import“ProjectName_App-Swift.h”
  • 在这个文件里面使用了Swift类
  • 它编译! 而且我可以使用Swift类

当Swift类被定义为多个目标而ObjectiveC文件被这些多个目标所使用时,它不起作用。 生成错误是这样的:目标X – >“ProjectName_TargetY-Swift.h”文件未find。 看起来像一个目标不能看到其他目标-Swift.h文件。

我究竟做错了什么? 谢谢你的帮助

我在编辑4中所做的假设是正确的。 如果项目有多个目标,则“-Swift.h”文件不能全部导入到一个.m ObjectiveC文件中。

所以有一个必须采用的解决scheme,那就是改变SWIFT_OBJC_INTERFACE_HEADER_NAME构build设置,并使其在不同目标上相同。 为此,请将生成此属性的指令从$(SWIFT_MODULE_NAME)-Swift.h更改$(PROJECT_NAME)-Swift.h ,如此处所述

也可以将“生成设置”中的“产品模块名称”设置设置为在模块中相同(我将其设置为$(PROJECT_NAME)),以便生成的-Swift.h文件在所有模块中具有相同的名称。 这消除了添加/检查预处理器macros的需要。

完成这个清理生成文件夹后,按Alt键进入产品菜单。 由于标题的名称在目标之间共享,因此可以在.m ObjectiveC文件中导入一次,所有目标都可以从Swift类中受益。

如果在构build之后仍然显示错误,请确保可以通过点击Cmd的名称从XCode到达头部。 它应该打开一个包含类似这样的代码的文件:

 SWIFT_CLASS("_TtC27ProjectName_Summary11MyClass") @interface MyClass : NSObject - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; @end 

如果需要确保生成这些头文件,请打开terminal并使用此命令

 find ~/Library/Developer/Xcode/DerivedData -name "*Swift.h" 

您应该为每个目标看到一个标题

这些变化之后发生的另一个问题是它开始给我没有碰到的ObjectiveC代码给出错误。 问题是由于import的地位,正如这里所报道的那样:

确切地说,在.m文件的顶部,#import隐藏的桥接头可以有所作为。 通常的麻烦是你得到一个“Unknown type name”编译错误,其中未知types是在Objective-C中声明的一个类。 解决的办法是#import你的Objective-C文件中包含未知types声明的.h文件,在#import隐藏的桥接头之前。 不得不这样做可能是一个烦恼,特别是如果Objective-C文件不需要知道这个类,但它解决了这个问题,并允许编译进行。

最后代码编译并运行在设备和模拟器上!

我有类似的问题,几乎花了一整天的时间来解决这个问题,同时遵循来自其他开发人员在StackOverflow和其他一些来源的build议。

我是从XCode 7.3.1升级到XCode 8.2.1和Swift 2.2到Swift 3.0.1。
就我而言,我发现PROJECT_NAME-Swift.h文件没有在下面创build:

~/Library/Developer/Xcode/DerivedData/PRODUCT-NAME-hdkrxixrxbiorwesffpqvefxsrzl/Build/Intermediates/PRODUCT-NAME.build/Debug/PRODUCT-NAME.build/Objects-normal/x86_64/PRODUCT-NAME-Swift.h.

我想它试图从上面的path引用这个头文件,因此错误。 我手动复制它。 这之后没做干净的build造。 这解决了我的问题,swift头文件开始创build进一步编译和构build。

对于我的情况,它在Xcode 8中运行正常,但文件

 #import "Project-Swift.h" 

如LucioB所述缺lessimport

使用Xcode 9可以消除这些错误