【发布时间】:2015-06-08 08:21:41
【问题描述】:
当我尝试在 Xcode 6.3 中将 CKCountdownButton 构建为框架时,它会抱怨
警告:找不到目标“CKCountdownButton”的伞头,不会生成模块映射
然后当我在其他项目中导入这个框架时,它失败了 No such module 'CKCountdownButton'
【问题讨论】:
当我尝试在 Xcode 6.3 中将 CKCountdownButton 构建为框架时,它会抱怨
警告:找不到目标“CKCountdownButton”的伞头,不会生成模块映射
然后当我在其他项目中导入这个框架时,它失败了 No such module 'CKCountdownButton'
【问题讨论】:
我找到了另一个解决方案,Xcode提供了一种通过Module Map File配置来指定umbrella header的方法。
module.modulemap的内容应该是:
framework module Foo {
umbrella header "Bar.h"
header "other-header.h"
export *
module * { export * }
}
【讨论】:
在框架中添加CKCountdownButton.h 修复了这个问题。
我认为伞形头是指与Framework同名的头文件
【讨论】:
MyFramework_macOS.h)。然后我将模块名称更改为“MyFramework”,但我没有更改标题。我通过将标题重命名为 MyFramework.h 并更新其中的导出以匹配新模块名称(MyFramework_macOSVersionNumber 到 MyFrameworkVersionNumber 等)来修复伞形标题问题。
该目标需要至少有 1 个 Swift 文件。检查您是否已将 Swift 文件添加到目标中
【讨论】:
自定义框架模块映射(.modulemap)和DEFINES_MODULE
公共文件结构:
header_1
header_1_1
header_2
将所有应向消费者公开的标头标记为公共(标头_1.h、标头_2.h、标头1_1.h)。 Headers public section[About] 否则你会得到下一个错误。
//For example in umbrella.h
Include of non-modular header inside framework module '<module_name>'
//or in upper .h file
'PBURLConnectionStub.h' file not found
modular headers - .h 包含在.modulemap 中的文件:
umbrella 来自umbrella.h 的关键字
header关键字。模块化标头可以仅导入模块化标头
创建一个umbrella file - 任何.h 文件(或为框架目标自动生成<product_name>.h)。我们就叫它Umbrella.h
将根.h 文件添加到umbrella file(Umbrella.h)。从此文件中的所有导入都将自动添加
//Umbrella.h file
#import "header_1.h"
#import "header_2.h"
使用或创建自定义.modulemap 文件。您可以随意调用.modulemap 文件,编译后将调用module.modulemap。另外我不建议您将其称为module.modulemap,因为它可能会导致此文件发生不可预知的变化
默认生成的module.modulemap:
//the same for Objective-C and Swift framework
framework module SomeModule {
//umbrella header "<umbrella_name>.h"
umbrella header "Umbrella.h"
export *
module * { export * }
}
//unique for Swift framework
module SomeModule.Swift {
header "SomeModule-Swift.h"
requires objc
}
umbrella header
以递归方式公开所有 module headers。生成下一个代码
//.modulemap
framework module SomeModule {
//explicitly define all modular header
header "header_1.h"
header "header_2.h"
header "header_1_1.h"
}
//using
import SomeModule
header_1
header_2
header_1_1
多个模块
.modulemap 可以包含多个模块。其中之一必须与PRODUCT_MODULE_NAME同名
//.modulemap
framework module SomeModule
framework module SomeModule2
//using
import SomeModule
import SomeModule2
子模块module
当您导入外部模块时,您可以使用子模块中的标头
//.modulemap
framework module SomeModule {
module Submodule1 {
header "header_1.h"
}
}
//using
import SomeModuleSwift.Submodule1
//or even
import SomeModuleSwift
//availability
header_1
显式子模块explicit module
您不能将模块名称用于子模块标题(如上例所示默认情况下可以这样做)
//.modulemap
framework module SomeModule {
explicit module Submodule1 {
header "header_1.h"
}
}
//using
//import SomeModuleSwift //Error: Cannot find 'header_1' in scope
import SomeModuleSwift.Submodule1
//availability
header_1
显式子模块之间的依赖关系export
//.modulemap
framework module SomeModule {
explicit module Submodule1 {
header "header_1.h"
export Submodule2
}
explicit module Submodule2 {
header "header_2.h"
}
}
//using
import SomeModuleObjC.Submodule1
//availability
header_1
header_2
使用雨伞
module * 仅适用于 umbrella,否则您会得到
Inferred submodules require a module with an umbrella
//.modulemap
framework module SomeModule {
umbrella header "Umbrella.h"
module * { export * }
export *
生成下一个代码
framework module SomeModule {
//module * { export * }
module header_1 {
header "header_1.h"
export header_2
export header_1_1
}
module header_2 {
header "header_2.h"
export header_1
export header_1_1
}
module header_1_1 {
header "header_1_1.h"
export header_1
export header_2
}
//export *
export header_1
export header_2
export header_1_1
}
//using one of them
import SomeModule.header_1
//or
import SomeModule.header_2
//or
import SomeModule.header_1_1
//or
SomeModule
//availability
header_1
header_2
header_1_1
当找不到某个文件时,会发生下一个错误
Error: Cannot find 'header_name' in scope
查看效果使用explicit module
module * - 为umbrella 内的每个modular header 创建子模块
export * - 将所有子模块导出到当前子/模块中
如果我们使用module * { } 而不是module * { export * } 和import SomeModule.header_1 没有任何改变,我们可以在导入单个子模块时使用所有modular headers。这是安全的,因为父模块SomeModule 可以访问所有子模块
import SomeModule.header_1
header_1
header_2
header_1_1
如果我们使用explicit module * { } 而不是explicit module * { export * } 和import SomeModule.header_1 我们会得到错误
import SomeModule.header_1
header_1
//header_2 //Error: Cannot find 'header_2' in scope
制作人:
定义模块(DEFINES_MODULE)
Build Settings -> Defines Module
If YES - Xcode generates .modulemap. If `MODULEMAP_FILE` is not specified Xcode try to generate it automatically
模块映射文件(MODULEMAP_FILE)
Build Settings -> Module Map File
Path to custom `.modulemap` file
The result file `module.modulemap` will be generated and embedded into .framework
消费者:
导入路径(SWIFT_INCLUDE_PATHS)
Build Settings -> Import Paths
Path to custom `.modulemap` file
【讨论】:
我在使用“GoogleToolbox”时遇到了同样的问题。当我尝试更新我的 Pod 存储库并且发生了一些错误时发生了这种情况。刚刚在项目文件夹的终端上进行了“pod install”,一切正常。
【讨论】: