在xcode8中找不到ModuleName-Swift.h文件 [英] ModuleName-Swift.h file not found in xcode8

查看:1423
本文介绍了在xcode8中找不到ModuleName-Swift.h文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力研究混合的Swift和ObjectiveC项目而没有运气。

I'm trying to work on a mixed Swift and ObjectiveC project with no luck.

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

My project is made of 6 targets:


  • App

  • 核心

  • CoreTest

  • 摘要

  • WatchKit Extension

  • WatchKit App

  • App
  • Core
  • CoreTest
  • Summary
  • WatchKit Extension
  • WatchKit App

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

I've been able to add a Swift class that has one target membership (App) and uses ObjectiveC code passing from the App-Bridging-Header.h The "ObjectiveC into Swift code" paradigm works like a charm.

相反,我正在努力应对Swift into ObjectiveC code范式。
在特定情况下,我需要在ObjectiveC .m文件中使用一个新的Swift类,该文件是四个目标的成员。

Instead, I'm struggling with the "Swift into ObjectiveC code" paradigm. In the specific case I need to use a new Swift class inside an ObjectiveC .m file that is member of four targets.

我一直在做什么到目前为止是这样的:

What I've been doing so far is this:


  1. 向Core项目添加一个新的Swift文件,指定四个成员资格(App,Core,Summary,WatchKit Ext)

  2. XCode要求为三个项目创建 -Bridging-Header.h Core,Summary和WatchKit Ext(App-Bridging-Header.h已经存在,因为它是以前使用过,并且我同意(不知道为什么它在我添加我的Swift类的同一组文件夹中创建那些文件但是没关系)

  3. 我创建了Swift类添加<强健> @objc 键

  4. 我去检查 Objective-C生成的界面标题名称是否设置为所有模块,是的,

  5. 我去检查所有模块中定义模块是否设置为并设置为在主项目中,是的,

  6. 我写下了所有四个目标的 -Swift.h 文件的导入

  7. 在我的Objective-C类中,我尝试使用我的新Swift类,显然它似乎工作(甚至自动完成)

  8. 我尝试构建项目但它没有说找不到 -Swift.h 文件

  1. Add a new Swift file to the Core project specifying the four memberships (App, Core, Summary, WatchKit Ext)
  2. XCode asks to create -Bridging-Header.h for three projects Core, Summary and WatchKit Ext (App-Bridging-Header.h already exists since it was used previously), and I consent (don't know why it creates those files inside the same group folder where I add my Swift class but nevermind)
  3. I create the Swift class adding the @objc key before class
  4. I go check if Objective-C Generated Interface Header Name is set for all modules, and yes it is
  5. I go check if Defines Module is set to No in all modules and set to Yes in the main project, and yes it is
  6. I write down the imports for the -Swift.h files for all the four targets
  7. Inside my Objective-C class I try to use my new Swift class, apparently it seems to work (even autocompletion)
  8. I try to build the project but it fails saying that the -Swift.h file is not found

我跟着 Apple的混合和匹配指南和许多SO线程,包括这一个看起来很明显解决我的同样问题,但它不起作用。

I've followed the Mix and Match guide of Apple and many SO threads including this one that seems apparently to address the same problem of mine but it doesn't work.

还见过这个这个但没有用。

还试图删除派生数据以及清理整个项目几次没有运气。

Have tried also to Delete Derived Data as well as cleaning the whole project several times with no luck.

编辑1:更多细节

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

This is the declaration of my Swift class import RealmSwift

@objc class MyClass: Object {}

这是Swift的使用片段ObjectiveC中的类

This is the snippet of usage of the Swift class inside ObjectiveC

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

如果我避免使用#import ...- Swift.h,那么构建失败说我是使用Undeclared标识符MyClass,这听起来很合理。

If I avoid using #import ...-Swift.h the build fails saying that I'm making use of an Undeclared idenfier "MyClass" and this is sound.

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

If I do use #import ...-Swift.h files it says that module X cannot find module Y and so on.

编辑2:Swift模块名称

按查看每个目标的 SWIFT_OBJC_INTERFACE_HEADER_NAME 属性我看到它是使用以下语法构建的 $(SWIFT_MODULE_NAME)-Swift.h 我是否需要更改 SWIFT_MODULE_NAME MODULE_NAME

By looking at the SWIFT_OBJC_INTERFACE_HEADER_NAME property of each target I've seen that it is built using this syntax $(SWIFT_MODULE_NAME)-Swift.h do I need to change SWIFT_MODULE_NAME to MODULE_NAME?

编辑3:进口

这是.m ObjectiveC文件中Swift头的导入集。
我正在使用相对Build Settings属性中指定的模块名称。请注意,由于WatchKit Extension目标在目标名称中有空格,因此其中包含'_'字符。

This is the set of imports for Swift headers in .m ObjectiveC file. I'm using the module names specified in relative Build Settings properties. Notice that one has '_' character since WatchKit Extension target has a space in the target name.

#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创建了桥接标题

  • 在ObjectiveC文件中插入#importProjectName_App-Swift.h仅由App使用

  • 利用Swift这个文件中的类

  • 它编译!我可以使用Swift类

  • Added a Swift class only in target App
  • XCode created the Bridging Header
  • Inserted #import "ProjectName_App-Swift.h" in ObjectiveC file used only by App
  • Made use of Swift class inside this file
  • It compiles! And I'm able to use the Swift class

当为多个目标定义Swift类并且多个目标使用ObjectiveC文件时目标它不起作用。构建错误是这样的:目标X - >ProjectName_TargetY-Swift.h文件未找到。
好​​像目标无法看到其他目标-Swift.h文件。

When the Swift class is defined for multiple targets and ObjectiveC file is used by those multiple targets it doesn't work. The build errors are like this: Target X -> "ProjectName_TargetY-Swift.h" file not found. Seems like a target cannot see other targets -Swift.h files.

我做错了什么?
感谢您的帮助

What am I doing wrong? Thanks for your help

推荐答案

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

The assumption I made in Edit 4 turned out to be the correct one. If a project has multiple targets the "-Swift.h" files cannot be imported all in one .m ObjectiveC file.

所以有一个解决方案必须采用,并且要更改 SWIFT_OBJC_INTERFACE_HEADER_NAME 构建设置,并使其在不同目标中保持一致。
为此,请将 $(SWIFT_MODULE_NAME)-Swift.h 生成此属性的指令更改为 $(PROJECT_NAME)-Swift.h ,如下所述这里

So there is one solution that must be adopted and it is to change the SWIFT_OBJC_INTERFACE_HEADER_NAME build setting and making it the same across different targets. To do so change the instruction that generates this property from $(SWIFT_MODULE_NAME)-Swift.h to $(PROJECT_NAME)-Swift.h as explained here


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

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类中受益。

After doing this Clean Build Folder by pressing Alt and going into Product menu. Since name of header is shared among targets now it can be imported once in the .m ObjectiveC file and all targets can benefit from Swift classes.

如果构建之后仍然显示错误,确保Cmd点击其名称可以从XCode到达标题。它应该打开一个包含类似代码的文件:

If after building it still shows the error, ensure that the header can be reached from XCode by Cmd clicking on its name. It should open a file that contains code similar to this:

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

如果需要确保生成这些标题,请打开终端并使用这个命令

If need to ensure that those headers are being generated open a terminal and use this command

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

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

You should see one header for each target

发生的另一个问题在这些更改之后,对我来说,它开始在我没有触及的ObjectiveC代码上给出错误。问题是由于进口的位置,如所报告的那样。这里

Another issue that happened to me after those changes is that it started giving errors on ObjectiveC code that I didn't touch. The problem was due to the position of the import, as reported here:


正好在.m文件的顶部你#import隐藏的桥接头可以有所作为。通常的问题是你得到一个未知类型名称编译错误,其中未知类型是在Objective-C中声明的类。解决方案是在#import隐藏的桥接头之前#import包含Objective-C文件中未知类型声明的.h文件。必须这样做可能会令人烦恼,特别是如果有问题的Objective-C文件不需要知道这个类,但它解决了问题并允许继续编译。

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.

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

At the very end the code compiles and runs on device and simulator!

这篇关于在xcode8中找不到ModuleName-Swift.h文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆