目标C到具有多个目标的Swift头文件


69

我已经通过import语句从Objective C(针对目标“ MyApp”)成功调用了我的Swift类:

#import "MyApp-Swift.h"

我现在创建了一个名为“ MyAppLite”的新目标

编译新目标时,出现错误,因为代码需要“ MyApp-Swift.h”,但是编译器正在创建“ MyAppLite-Swift.h”

因此,我需要为#import要编译的目标创建条件Swift / ObjC标头。

怎么做,还是有更好的办法?

Answers:


81

也可以Product Module NameBuild Settings各个模块中将设置设置为相同(我将其设置为$(PROJECT_NAME)),这样<project>-Swift.h生成的文件在所有模块中都具有相同的名称。这样就无需添加/检查预处理程序宏。


1
当您在项目中创建第一个Swift文件时,xcode会要求您将桥接标头添加到项目中。就我而言,它仅将所需的配置添加到第一个构建目标。因此,我还需要通过配置Objective-C Bridging Header
Kevin R

我发现这导致了构建过程中的问题,并且在它们之间进行切换时,我需要清理构建文件夹。我相信,因为它们都共享相同的项目名称,所以它们都建立在相同的文件夹中。
Saltymule

11
我“米不知道,但我的感觉是,与搞乱Product Module Name提交到App Store的时候,会影响以后的东西,可能;)......改变Objective-C Generated Interface Header Name。在对方的回答说明已经没有意义
丹Rosenstark

2
@Yar刚看到您的评论。最初是我的感觉,但是该应用程序已经在App Store中存在了一段时间,这并不是问题。但是,如果我使用的是最新版本的Xcode,则应使用Mike Fay的解决方案tbh。这个答案是在SWIFT_MODULE_NAME可用之前做出的。
C0D3LIC1OU5 2015年

上帝祝福你!在所有目标中使用相同的模块名称,可以避免我在混合Swift / ObjC项目中使用自定义swift类遇到糟糕的问题,这仅在发行版中发生!非常感谢!
Vitalii Gozhenko

63

我发现解决此问题的最佳方法是在Xcode共享项目设置中。您可以搜索以下设置:

Objective-C生成的接口头名称*

如果将该值设置为通用标头名称,例如“ MyProject-Swift.h”,它将被应用于每个目标,并且可以安全地在任何Objective-C文件中使用导入声明。如果需要,这使您可以继续为每个目标使用唯一的产品模块名称。

我已经在Xcode版本6.4(6E35b)中对此进行了测试。

*注意:这将显示在您的Swift编译器设置下,仅当您将Swift源文件添加到项目时,该设置才可见。此外,如果目标没有任何关联的Swift源,则该目标的构建设置将看不到Swift编译器选项。

祝好运!


3
这是IMO的最佳解决方案。
拉斐尔·诺布雷2015年

2
原来这个值是$(SWIFT_MODULE_NAME)-Swift.h...所以虽然这个答案是真棒,我知道如何调整SWIFT_MODULE_NAME的模块。
Dan Rosenstark

1
当我在这里时,我建议您使用一些明显的名称来减少混乱,例如,MidiDesignerAllTargets-Swift.h感谢您的出色回答,这是一个很好的发现。
Dan Rosenstark

1
如果您使用的是Xcode 7+,则这是最佳解决方案。
hdoria '16

1
它肯定在版本8.3.3(8E3004b)中仍然可用。
Mike Fay

41

如果您决定重命名目标或项目,或SWIFT_MODULE_NAME按预期使用,则先前的答案会有一些问题。

最通用的解决方案是将SWIFT_OBJC_INTERFACE_HEADER_NAMEProject(而不是Targets,Build Settings)下的(“ Objective-C生成的接口头名称”)更改为:

  • $(PROJECT_NAME)-Swift.h -每个项目一个;
  • $(SWIFT_MODULE_NAME)-Swift.h —每个模块一个(默认值)。

在此处输入图片说明


2
Xcode 8.3.3,Swift 3,确保通用/共享的swift文件属于每个目标,所有工作都在此之后进行。
克拉伊德达(Klajd Deda)

1
如何处理“ $(PROJECT_NAME)-Swift.h文件未找到”错误,如警告?
ViruMax

1
这应该是可以接受的答案,因为它显示了更多详细信息,尽管@ C0D3LIC1OU5的答案足够好
Sandeep Rana

1
这就是我要的东西。谢谢您的回答。
EmreÖnder'2

5

好吧,我唯一可以解决的方法是...

#ifdef IS_LITE
#import "MyApp_Lite-Swift.h"
#else
#import "MyApp-Swift.h"
#endif

请注意,如果我的产品模块名称中包含“非法”字符,则需要将它们替换为下划线。

希望有帮助!


这对我有用,因为在目标之间切换时,可接受的答案导致了构建问题。
Saltymule

5

我在每个构建(目标/方案)定义/添加的前缀头文件(<project> -Prefix.pch)中放入了适当的#import <project> -Swift.h语句。


这样做的好处是,可以更方便地在Objective-C中使用Swift类,并且在不需要显式导入标头的Swift体验和Objective-C体验之间具有更高的一致性。
paulmelnikow

0

唯一的工作方式如下:

1-从第一个目标(具有有效的桥接)进行构建设置选择目标C桥接标题
2-复制目标C桥接标题
3-打开另一个目标构建设置
4-粘贴它5-更改头文件到新的头文件(即目标Bh)

(现在您有两个目标的此选项)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.