这是预期的编译器行为,并且有很好的理由。
我认为大多数遇到此问题的人是从他们切换Application Target
到Framework Target
并开始将C和Objective C标头添加到框架的伞形标头之后引起的,他们期望它具有与应用程序的Bridging标头相同的行为,但行为不同。伞头实际上是为混合快速obj-c框架指定的,其目的是将API暴露给您的框架在Objective-c或c中拥有的外部世界。这意味着我们放在其中的标题应该在公共范围内。
它不应用作将不属于框架的Objective-C / C标头暴露给框架的快速代码的地方。因为在这种情况下,这些标头也将作为框架模块的一部分公开给外界,这通常不是我们想要做的,因为它破坏了模块性。(这就是为什么在框架模块中允许非模块化包含默认为NO的原因)
为了向您的框架swift代码公开Objective-C / C库,我们应该为该库定义一个单独的swift模块。然后import YourLegacyLibrary
可以使用标准的swift 。
让我在一些典型的场景上进行演示:嵌入libxml2
到我们的框架中。
1.首先,您需要创建一个module.modulemap
看起来像这样的文件:
对于OSX框架:
module SwiftLibXML2 [system] {
header "/usr/include/libxml2/libxml/xpath.h"
export *
}
对于iOS框架:
module SwiftLibXML2 [system] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/libxml2/libxml/xpath.h"
export *
}
它所做的只是将报头和它引用的任何其他报头包装在swift模块中,这样swift就可以为这些C接口生成swift绑定了。
2.然后在xcode项目目录中创建一个文件夹SwiftLibXML2
,并将此module.modulemap放在此处
3.在“ 构建设置”中,添加$(SDKROOT)/usr/include/libxml2
到标题搜索路径
4.在“ 构建设置”中,添加$(SRCROOT)/SwiftLibXML2
到“ 导入路径”
5.在Project的General选项卡下,添加libxml2.tbd
到Linked Frameworks and Libraries。
现在,您需要通过以下方式导入此模块:
import SwiftLibXML2
(如果您想看一个更完整的module.map示例,我建议您参考处的Darwin的module.modulemap /usr/include/module.modulemap
,您需要在此安装Xcode命令行工具,并参考OS X El Capitan中的Missing / usr / include)