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

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

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

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

似乎与模块function有关,但目前尚不清楚如何解决,您是否知道解决scheme?

更新:

这是一个Swift编译器错误。

更新2:

快速修复(但不解决根本原因)是将以下设置设置为yes:CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES

你的标题是公开的吗?

在项目浏览器中select头文件。 然后在xcode右侧的部分中,您会注意到目标旁边有一个下拉菜单。 将其从“项目”更改为“公开”。 这对我有效。

公共标题

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

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

它不应该被用作公开的Objective-C / C头文件,而不是框架的一部分到你的框架的swift代码。 因为在这种情况下,这些头文件也将作为我们框架模块的一部分暴露给外部世界,这往往不是我们想要做的,因为它打破了模块化。 (这正是为什么在框架模块中允许非模块化包含默认为NO

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

让我来演示一下这个典型场景:将libxml2embedded到我们的框架中。

1.您首先需要创build一个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项目目录下创build一个文件夹SwiftLibXML2并把这个module.modulemap放在那里

3.Build Settings中 ,将$(SDKROOT)/usr/include/libxml2Headersearchpath

4.生成设置中 ,添加$(SRCROOT)/SwiftLibXML2导入path

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

现在,您可以根据需要导入此模块:

 import SwiftLibXML2 

(如果你想看一个更完整的module.map例子,我会build议在/usr/include/module.modulemap引用Darwin的module.modulemap,你需要安装Xcode命令行工具去参考,参考Missing / usr / include在OS X El Capitan中 )

下面介绍如何自动应用快速修复,以便在每次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 

我的解决scheme是去目标 – >build立设置 – >允许非模块包括在框架模块切换到YES!

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

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

顺便说一句,CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES设置不起作用。 我试图在框架和依赖项目中设置它。 这个解决方法是必要的,但我不知道为什么。

Swift中

1.修改你的Xcode项目,并按照如下所述的目标“构build设置”:

允许非模块化包含在框架模块中:否

启用位码:是的

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

GoogleMaps(1.10.4)

3.评论有问题的导入:

 //import GoogleMaps 

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

[您的Xcode项目名称] – Bridge-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.清理并重新构build您的Xcode项目。

这个答案已经过时了。

导入框架时,必须导入与根标题共享依赖关系的所有头文件 。 确保始终有效的最简单方法是将框架“Headers”文件夹中的所有标题导入公共标题path。

在这里输入图像描述

Swift编译器使用这些信息来生成一个非损坏符号的地图及其关联的types信息。

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

 #import "MyOtherFramework.h" 

 #import <MyOtherFramework/MyOtherFramework.h> 

将自己的框架包含在一个项目中时,我有这个确切的问题。 通过将.m文件中的所有sqlite3.h导入不在公共.h文件中。 我假设其他库可能会标记与Xcode类似的问题。

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

我做了所有的步骤,但仍然错误的非模块化标题。 我拖放只从框架中的特定标题构build阶段 – >标题部分。

然后在顶部的项目导航器中自动创build一个标题副本。

我从构build阶段 – >标题删除它,并删除新文件,工作正常。

喜欢它复位或什么的。

我知道这是一个古老的问题,但我有同样的问题,上面没有任何帮助。 所以我希望我的回答对某人有帮助。 在我的情况下,问题是在ALWAYS_SEARCH_USER_PATHS设置。 当它被设置为没有项目build立和工作正常。 但只要其中一个吊舱要求将其设置为YES,我正在收到一个错误

在框架模块中包含非模块化头文件

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

•如果您之前编译的框架出现错误,指出“在框架模块中包含非模块化标题”,请确保“始终search用户path”编译设置设置为“否”。 仅出于传统原因,默认值为“是”。 (22784786)

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

大多数情况下,这个错误是由select的答案引起的,但是当我将框架文件拖到我的新项目文件夹中时,偶然出现这个错误。 我点击删除框架,但意外地只按“删除参考”的框架,而不是实际上完全删除文件。 在这一点上,如果我在Finder中打开我的项目文件夹,我在那里看到像“CoreLocation”和“AudioToolbox”这样的文件。 从项目文件夹中删除这些文件并清理项目解决了问题。

在允许导入非模块化包含之后,您可以尝试使用Objective-C桥接头来导入该模块:

 #import <YandexMobileMetrica/YandexMobileMetrica.h> 

我想补充我的经验,以及这个问题。

只是要总结一下:

  • @ ambientlight的答案是伟大的,它修复了大部分的问题。
  • 允许非模块化标题是另一种解决scheme(请参阅上面的一些答案)
  • 将框架的标头标记为公共(只是您想要公开的),并将其导入到伞头中
  • 这里是我的两个补充答案
  • 仔细检查你的项目中的导入是否直接在你的项目中导入你的框架(如果可能的话使用forward声明),把头文件包含到另一个头文件中是不好的,有时这会导致一个问题,因为如果没有做好这可能会导致多个包括一个头和链接器的问题
  • 最后在做了以上所有的事情之后,我仍然不断碰到这个错误,所以我挖了一点点,发现(在苹果开发者论坛上,但失去了链接:(),如果你包括标题在伞头没有像这个<framework/headerName.h> ,但只有像这个"headerName.h" ,问题消失了,我试过这个,现在我没有经历过这个问题了,但我认为这个解决scheme是有效的只有你已经应用了一些最好的答案(它们并不都是相互兼容的,例如模块方法和允许非模块化的头文件)

附加:检查库的体系结构以及要链接到的目标的体系结构

在我的情况下(Xcode 9testing版6 – Swift 4 – 使用Cocoapods),当我删除Podfile.lockPods目录并再次运行pod install

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

我有这个问题导入Parse框架。 我可以修复它的唯一方法是放弃自从我上次提交以来所做的所有更改(简单地删除框架并清理项目不起作用),并使用其他所需的框架再次添加Parse(重新下载SDK之后)。