Swift Cocoapods 中的子模块

Swift sub-modules in Cocoapods

我正在尝试设置私有 Cocoapods 的以下排列:

PodA 取决于 PodB 取决于 CommonCrypto.

CommonCryptodylib 随 iOS 一起提供但没有 Swift 头模块。在 PodB 中,我创建了一个包含以下内容的自定义 module.modulemap

module CommonCrypto [system] {
    header "/usr/include/CommonCrypto/CommonCrypto.h"
}

PodB 添加以下行后通过 lint 测试 (pod spec lint PodB.podspec):

# Ensure module isn't deleted by CocoaPods
s.preserve_paths = 'path_to/PodB/CommonCrypto'
s.pod_target_xcconfig = { 'HEADER_SEARCH_PATHS' => '$(PODS_ROOT)/path_to/CommonCrypto' }

PodA内,我依赖PodBs.dependency = 'PodB'。使用 pod spec lint --sources=myrepo PodA.podspecPodA 进行 linting 时,使用 import PodB:

编译任何 Swift 文件时出现错误
missing required module 'CommonCrypto'

我该如何解决这个问题? CommonCrypto 是私有的还是 public 到 PodB.

对我来说并不重要

我尝试将 export * 添加到 module.modulemap,但没有任何区别。

您是否将框架添加到 podB 的规范文件中?

s.frameworks = 'CommonCrypto'

我用(稍微)丑陋的解决方法解决了这个问题;我将包含路径导出到父项目。

由于包含路径是多值的,列表而不是单个设置,Cocoapods 可以合并任何父项目 (PodA) 设置与任何子项目 (PodB) 要求。

我以前尝试过这个解决方案,但失败了,因为我使用的是 HEADER_SEARCH_PATHS 而不是 SWIFT_INCLUDE_PATHS。固定 podspec 的相关位如下所示:

# Ensure module isn't deleted by CocoaPods
s.preserve_paths = 'path_to/PodB/CommonCrypto'
s.pod_target_xcconfig = { 'SWIFT_INCLUDE_PATHS' => '$(PODS_ROOT)/path_to/CommonCrypto' }
s.user_target_xcconfig = { 'SWIFT_INCLUDE_PATHS' => '$(PODS_ROOT)/path_to/CommonCrypto' }

user_target_xcconfig 允许 PodB 将构建设置注入 PodA。这通常不是一个好主意,可以用来搞砸各种事情,所以我欢迎更好的解决方案,但在将父 pods 指向模块的特殊情况下,我认为这是可以接受的。

也就是说,如果 PodA 依赖于 PodBPodC,我 认为 这个解决方案会失败,其中 B C 需要 CommonCrypto...

到目前为止,我很幸运,只是将所有需要的 CommonCrypto header 复制到一个桥接 header 中,并将其包含到 pod 中。 CommonCrypto 很少更改,在发生任何重要更改之前,它很可能是模块化的 header。有关示例 header 文件,请参阅 RNCryptor.h。请注意,所有 #ifdef 条件都包括在内,并且每个完整的 header 都包括在内(不仅仅是这个项目所需要的)。这应该可以防止多个包导入同一个文件(只要 header 没有改变)。

resultant podspec 仅包含 .h 作为来源:

s.source_files = 'RNCryptor.swift', 'RNCryptor.h'

使用 $(PODS_TARGET_SRCROOT) 而不是 $(PODS_ROOT)/podname/ 对我有用

s.source_files = 'Classes/**/*.swift', 'modules/**/*.map'
s.preserve_paths = 'modules/**/*.map'

s.pod_target_xcconfig = {
   'SWIFT_INCLUDE_PATHS[sdk=iphoneos*]'         => '$(PODS_TARGET_SRCROOT)/modules/iphoneos/CommonCrypto',
   'SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*]'  => '$(PODS_TARGET_SRCROOT)/modules/iphonesimulator/CommonCrypto',
}

module.map 个文件: modules/iphoneos/CommonCrypto/module.地图:

module CommonCrypto [system] {
    header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
    export *
}

modules/iphonesimulator/CommonCrypto/module.地图:

module CommonCrypto [system] {
    header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h"
    export *
}