Swift编译器错误:“框架模块内的非模块头”;

现在我想把我的ObjC框架迁移到Swift,我得到了以下错误:

include of non-modular header inside framework module 'SOGraphDB'

引用是一个头文件,它只是定义了一个协议,我在一些类中使用这个头文件来使用这个协议。

这似乎与模块特性有关,但目前不太清楚如何修复,你知道解决方案吗?

更新:

这是一个Swift编译器错误。

更新2:

一个快速的解决方法(但不能解决根本原因)是将以下设置设置为yes: clang_allow_non_modular_incles_in_framework_modules = YES

98059 次浏览

头文件已分配给目标,但仅被标记为项目可见,只是更改为公共导致解决此错误。

你的头文件是公共的吗?

在项目资源管理器中选择头文件。然后在xcode右边的部分,你会注意到目标旁边有一个下拉菜单。把“项目”改成“公共”。这对我很管用。

public header

我想我解决了这个问题。我有一些在框架中使用sqlite3的模型代码。在我的案例中,罪魁祸首是<sqlite3.h>

问题是在我的Module/Module.h头文件中,我导入了一个公共头文件,导入了sqlite3.h>解决方案是隐藏所有sqlite3_xxx类型,并确保它们 没有出现在任何公共场所。所有对sqlite3的直接引用都是私有或项目可见性。例如,我有一个公共单例,它挂有一些sqlite3_stmt指针。我把它们移动到一个单独的类中,现在它只是一个公共报头中的前向声明。

顺便说一句,clang_allow_non_modular_incles_in_framework_modules设置不起作用。我试着在框架和相关项目中都设置它。这种变通是必要的,尽管我不确定为什么。

当我在一个项目中包含我自己的框架时,我就遇到了这个问题。修正了将sqlite3.h的所有导入都放在。m文件中,而不是公共的。h文件中。我认为其他库也会在Xcode中标记出类似的问题。

这个答案已经过时了。

导入框架时,必须导入与根头文件共享依赖关系的所有头文件。确保这总是有效的最简单的方法是导入框架的“headers”文件夹中的所有头文件到你的公共头文件路径。

enter image description here

Swift编译器使用这些信息生成一个非破损符号的映射及其相关的类型信息。

导入Parse框架时遇到了这个问题。我能解决这个问题的唯一方法是放弃我上次提交后所做的所有更改(简单地删除框架并清理项目不起作用),并再次添加Parse(在重新下载SDK之后)及其所需的其他框架。

我有Facebook 4.02 sdk和FBSDKCoreKit的具体问题。

我做了所有的步骤,但仍然错误关于非模块化头。我只从框架中拖放特定的头以构建阶段->头节。

然后在顶部的项目导航器上自动创建标题的副本。

我从构建阶段->头文件中删除了它,并删除了新文件,工作正常。

好像它被重置了。

我的解决方案是在框架模块上允许非模块化包含切换到YES!

下面是如何自动应用快速修复,这样你就不必在每次pod install之后手动更改Pods.xcodeproj

将这个片段添加到Podfile的末尾:

post_install do |installer|
installer.pods_project.build_configuration_list.build_configurations.each do |configuration|
configuration.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
end
end

斯威夫特:

1. 修改你的Xcode项目和目标的构建设置如下所示:

允许非模块包含在框架模块中

Enable Bitcode:是

2. 使用当前最新版本的GoogleMaps iOS SDK(使用CocoaPods获取):

GoogleMaps (1.10.4)

3.注释有问题的导入:

//import GoogleMaps

4. 创建或修改桥接头文件,添加有问题的导入:

[你的Xcode项目名称]-Bridging-Header.h

// Use this file to import your target's public headers
// that you would like to expose to Swift.
#import <GoogleMaps/GoogleMaps.h>

5. 清理并重新构建Xcode项目。

大多数情况下,这个错误是由选择的答案引起的,但是当我将框架文件拖到我的新项目文件夹中时,这个错误意外地出现了一次。我点击删除框架,但不小心按下了“删除引用”的框架,而不是完全删除文件。此时,如果我在Finder中打开项目文件夹,我会看到像“CoreLocation”和“AudioToolbox”这样的文件。从项目文件夹中删除这些文件并清理项目可以解决这个问题。

这是编译器预期的行为,有很好的理由。

我认为大多数人遇到这个问题是因为他们从Application Target切换到Framework Target,并开始将C和Objective C头文件添加到框架的伞头中,期望它具有与应用程序的桥接头相同的行为,而后者的行为不同。伞头实际上是为混合swift和obj-c框架指定的,它的目的是将你的框架在objective-c或c中的api暴露给外部世界。这意味着我们放在那里的头应该在公共范围内。

它不应该被用作将不属于框架的Objective-C/C头文件暴露给框架swift代码的地方。因为在这种情况下,这些头文件也将作为框架模块的一部分对外公开,这通常不是我们想要做的,因为它破坏了模块化。(这就是为什么允许在框架模块中包含非模块默认为没有的原因)

为了将Objective-C/C库公开给你的框架swift代码,我们应该为这个库定义一个单独的swift模块。然后可以使用标准swift import YourLegacyLibrary

让我在一些典型的场景中演示一下:将libxml2嵌入到我们的框架中。

你首先需要创建一个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绑定。

然后在你的xcode项目目录中创建一个文件夹SwiftLibXML2并放入这个模块。modulemap那里

建立设置中,将$(SDKROOT)/usr/include/libxml2添加到页眉搜索路径

建立设置中,将$(SRCROOT)/SwiftLibXML2添加到导入路径

在项目的一般选项卡下,将libxml2.tbd添加到链接框架和库

现在你可以在需要的地方导入这个模块:

import SwiftLibXML2

(如果你想看一个更完整的模块。地图的例子,我建议参考达尔文的模块。modulemap位于/usr/include/module.modulemap,你需要安装Xcode命令行工具才能到达那里,参考OS X El Capitan中缺少/usr/include)

我知道这是一个老问题,但我也有同样的问题,上面的任何东西都帮不了我。所以我希望我的回答能对别人有所帮助。 在我的情况下,问题是在ALWAYS_SEARCH_USER_PATHS设置。当它被设置为NO时,项目建立并工作正常。但只要其中一个pod要求将其设置为YES,我就会收到一个错误

包括非模块化的头在框架模块内

经过几杯咖啡和一整天的研究,我发现根据Xcode 7.1 Beta 2发布说明的已知问题:

如果你得到一个错误声明“Include of non-modular header within framework module” 之前编译的框架,确保“Always Search User Paths” 构建设置设置为“No”。仅由于遗留原因,默认为“Yes”。(22784786) < / p >

虽然我使用的是XCode 7.3,但似乎这个bug还没有修复。

在允许导入非模块化include之后,你可以尝试使用Objective-C Bridging头文件导入该模块:

#import <YandexMobileMetrica/YandexMobileMetrica.h>

我也想补充一下我在这个问题上的经验。

总结一下:

  • @ambientlight的回答很棒,它解决了大部分问题。
  • 允许非模块化报头是另一种解决方案(参见上面的一些答案)。
  • 将框架的头标记为公共的(只有那些您想要公开的),并将它们导入到伞形头中。

以下是我对上述答案的2个补充:

  • 仔细检查项目中直接导入框架的头文件(而不是使用前向声明,如果可能的话)——在另一个头文件中包含一个头文件并不是一个好的实践;有时这会导致问题,因为如果处理不当,可能会导致一个头文件被多个包含,并产生链接器问题。
  • UPDATE:确保库的体系结构与要链接到的目标的体系结构相匹配。
  • 最后,在做了上面所有的事情之后,我仍然不断地碰到那个错误。所以我挖掘了更多,发现(在苹果开发者论坛,但我丢失了链接:(),如果你在伞头中包含的头不像这样<framework/headerName.h>,而只是像这样"headerName.h",问题就消失了。

我尝试了最后一个,到目前为止我还没有遇到过这个问题,但是我怀疑这个解决方案只有在你应用了一些顶部的答案时才有效(注意:它们并不都相互兼容,例如,模块方法和允许非模块头包含)。

#import "MyOtherFramework.h"

#import <MyOtherFramework/MyOtherFramework.h>

在我的情况下(Xcode 9 beta 6 - Swift 4 -使用Cocoapods),当我删除Podfile.lock豆荚目录并再次运行pod install时,这个问题得到了解决

我在将一个项目从swift2更新到swift3后遇到了这个问题。我使用XCode 8.3.2更新代码,无法摆脱“框架模块内的非模块化头”的错误。当我在另一个版本的XCode(版本9.0.1)中打开相同的项目时,错误没有出现。

允许框架模块中的非模块化包含是的!为我解决了同样的问题。

我解决了它从框架中删除Modules文件夹。

  • 使用finder浏览到应用程序项目中显示的框架位置

  • 进入Test.framework文件夹(在上面的例子中,它将是SOGraphDB.framework) &删除文件夹Modules

  • 清洁和重新构建应用程序,它将解决问题。

我尝试了所有可能的解决方案,我发现在这个线程设置目标>允许在框架模块中包含非模块化的组件,切换到YES!等等。

但是什么都不管用。

当我通过评论use_frameworks安装pods时,我开始得到这个错误!,因为我想有一个静态库的豆荚。

原因Swift编译器抛出(在Xcode 13上)这个错误,因为我正在导入私有框架头文件#import "TFLTensorFlowLite.h" 在公共.h文件中,所以我在.m文件中导入了它,如下面的截图所示,它停止了Swift编译器抛出这个错误(注意我的框架有Objective c和Swift代码)

enter image description here

enter image description here