在 Swift 框架中导入 CommonCrypto

Posted

技术标签:

【中文标题】在 Swift 框架中导入 CommonCrypto【英文标题】:Importing CommonCrypto in a Swift framework 【发布时间】:2014-10-04 14:17:38 【问题描述】:

如何在 ios 的 Swift 框架中导入 CommonCrypto

我了解如何在 Swift 应用程序中使用 CommonCrypto: 您将#import <CommonCrypto/CommonCrypto.h> 添加到桥接头。 但是,Swift 框架不支持桥接头。 documentation 说:

您可以导入具有纯 Objective-C 代码库、纯 Swift 代码库或混合语言代码库的外部框架。这 导入外部框架的过程是否相同 框架是用一种语言编写的或包含来自这两种语言的文件 语言。导入外部框架时,请确保 为您要导入的框架定义模块构建设置 是的。

你可以将一个框架导入到不同的 Swift 文件中 使用以下语法定位目标:

import FrameworkName

很遗憾,导入 CommonCrypto 不起作用。也不会将#import <CommonCrypto/CommonCrypto.h> 添加到伞形标题中。

【问题讨论】:

CommonCrypto 是基于 C 的框架,而不是 Objective-C 框架。 @rmaddy Objective-C 是 C 的超集。你是说我们不能使用 Swift 的 CommonCrypto 吗? @rmaddy 我刚刚设法通过使用模块映射让 CommonCrypto 工作。我将完善解决方案并在今天晚些时候发布。 如果你觉得方便,而且你要的已经实现了,你可以试试CryptoSwift Apple 刚刚开源了 CommonCrypto。如果我们有资源,也许我们可以让它运行。 【参考方案1】:

更新 Xcode 后,我也遇到了同样的情况。 我尝试了我能做的所有事情,例如重新安装 cocoapods 和清理项目,但没有奏效。 现在重启系统后解决了。

【讨论】:

【参考方案2】:

如果您遇到以下问题:

ld: 找不到 -lapple_crypto 的库 clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)

在 Xcode 10 中,Swift 4.0。 CommonCrypto 是框架的一部分。

添加

 import CommonCrypto

删除

来自链接二进制文件的 CommonCrpto lib 文件与来自 Build 的库 阶段 import CommonCrypto 来自桥接头

这对我有用!

【讨论】:

【参考方案3】:

好消息! Swift 4.2 (Xcode 10) 终于提供了 CommonCrypto!

只需在您的 swift 文件中添加 import CommonCrypto

【讨论】:

好消息!您可以添加文档链接吗? 我没有文档链接,我在尝试编译一个项目时发现了这一点,在该项目中我使用 Xcode 10 有一种解决方法。它抱怨说它可以找到两个 CommonCrypto 模块,因此怀疑苹果现在提供了我删除了我的解决方法并且'lo!这是真的。我在推特上发了推文,一位 Apple 工程师回复确认这是有意的。 App Store 只显示 9.4.7 作为可用更新,你是如何获得 Xcode 10 的? 它处于测试阶段,就像一个简单的 Google 搜索会告诉你的那样。 @SomoyDasGupta 是的。只需删除以前的导入,然后重新编译即可。换句话说,您不必执行 MikeWeller 回答中的步骤【参考方案4】:

对于使用 swift 4.2Xcode 10 的任何人:

CommonCrypto 模块现在由系统提供,因此您可以像任何其他系统框架一样直接导入它。

import CommonCrypto

【讨论】:

@mxcl 的答案重复:***.com/a/50690346/9988514【参考方案5】:

我不确定 Xcode 9.2 是否有所改变,但现在实现这一点要简单得多。我唯一要做的就是在我的框架项目目录中创建一个名为“CommonCrypto”的文件夹,并在其中创建两个文件,一个名为“cc.h”,如下所示:

#include <CommonCrypto/CommonCrypto.h>
#include <CommonCrypto/CommonRandom.h>

还有一个叫module.modulemap:

module CommonCrypto 
    export *
    header "cc.h"

(我不知道为什么不能直接在modulemap文件中引用SDKROOT区域的头文件,但我无法让它工作)

第三件事是找到“导入路径”设置并设置为$(SRCROOT)。 事实上,如果您不希望它位于根级别,您可以将其设置为您希望 CommonCrypto 文件夹所在的任何文件夹。

之后你应该可以使用了

import CommonCrypto

在任何 swift 文件和所有类型/功能/等中。可用。

但请注意 - 如果您的应用使用 libCommonCrypto(或 libcoreCrypto),不太老练的黑客非常容易将调试器附加到您的应用并找出传递给这些函数的密钥。

【讨论】:

【参考方案6】:

更简单和更健壮的方法是创建一个名为“CommonCryptoModuleMap”的聚合目标,其中包含运行脚本阶段,以自动生成模块映射并使用正确的 Xcode/SDK 路径:

运行脚本阶段应该包含这个 bash:

# This if-statement means we'll only run the main script if the CommonCryptoModuleMap directory doesn't exist
# Because otherwise the rest of the script causes a full recompile for anything where CommonCrypto is a dependency
# Do a "Clean Build Folder" to remove this directory and trigger the rest of the script to run
if [ -d "$BUILT_PRODUCTS_DIR/CommonCryptoModuleMap" ]; then
    echo "$BUILT_PRODUCTS_DIR/CommonCryptoModuleMap directory already exists, so skipping the rest of the script."
    exit 0
fi

mkdir -p "$BUILT_PRODUCTS_DIR/CommonCryptoModuleMap"
cat <<EOF > "$BUILT_PRODUCTS_DIR/CommonCryptoModuleMap/module.modulemap"
module CommonCrypto [system] 
    header "$SDKROOT/usr/include/CommonCrypto/CommonCrypto.h"
    export *

EOF

使用 shell 代码和 $SDKROOT 意味着您不必对 Xcode.app 路径进行硬编码,这可能会因系统而异,尤其是当您使用 xcode-select 切换到测试版或正在构建时在非标准位置安装多个版本的 CI 服务器上。您也不需要对 SDK 进行硬编码,因此这应该适用于 iOS、macOS 等。您也不需要在项目的源目录中放置任何内容。

创建此目标后,使用 Target Dependencies 项使您的库/框架依赖它:

这将确保在构建框架之前生成模块映射。

ma​​cOS 注意:如果您也支持macOS,则需要将macosx 添加到您刚刚创建的新聚合目标的Supported Platforms 构建设置中,否则它不会将模块映射与其他框架产品一起放入正确的Debug 派生数据文件夹中。

接下来,将模块映射的父目录 $BUILT_PRODUCTS_DIR/CommonCryptoModuleMap 添加到 Swift 部分 (SWIFT_INCLUDE_PATHS) 下的“导入路径”构建设置:

如果您在项目或 xcconfig 级别定义了搜索路径,请记住添加 $(inherited) 行。

就是这样,你现在应该可以import CommonCrypto

Xcode 10 更新

Xcode 10 现在附带了一个 CommonCrypto 模块映射,因此不需要这种解决方法。如果您想同时支持 Xcode 9 和 10,您可以在运行脚本阶段检查模块映射是否存在,例如

COMMON_CRYPTO_DIR="$SDKROOT/usr/include/CommonCrypto"
if [ -f "$COMMON_CRYPTO_DIR/module.modulemap" ]
then
   echo "CommonCrypto already exists, skipping"
else
    # generate the module map, using the original code above
fi

【讨论】:

这个答案应该是最重要的。简洁大方 这个游戏迟到了 - 但这应该是选择的答案。这很简单,也更容易让从事同一项目的其他开发人员看到需求。 如果我在 .framework 中执行此操作,我是否必须在包含此框架的项目中执行相同操作? @MikeWeller 你好,我确实按照上述步骤操作,但没有得到这样的模块“CommonCrypto”。我现在使用 xCode 9。新版本的 xCode 是否还有其他功能可以使其正常工作?或者我错过了什么。 @IanDundas 我更新了上面的代码,修复了重新编译问题以及在 macOS 上使用它的修复【参考方案7】:

我在 jjrscott 的回答中添加了一些 cocoapods 魔法,以防您需要在 cocoapods 库中使用 CommonCrypto。


1) 将此行添加到您的 podspec:

s.script_phase =  :name => 'CommonCrypto', :script => 'sh $PROJECT_DIR/../../install_common_crypto.sh', :execution_position => :before_compile 

2) 将其保存在您的库文件夹或您喜欢的任何位置(但不要忘记相应地更改 script_phase ...)

# This if-statement means we'll only run the main script if the
# CommonCrypto.framework directory doesn't exist because otherwise
# the rest of the script causes a full recompile for anything
# where CommonCrypto is a dependency
# Do a "Clean Build Folder" to remove this directory and trigger
# the rest of the script to run
FRAMEWORK_DIR="$BUILT_PRODUCTS_DIR/CommonCrypto.framework"

if [ -d "$FRAMEWORK_DIR" ]; then
echo "$FRAMEWORK_DIR already exists, so skipping the rest of the script."
exit 0
fi

mkdir -p "$FRAMEWORK_DIR/Modules"
echo "module CommonCrypto [system] 
    header "$SDKROOT/usr/include/CommonCrypto/CommonCrypto.h"
    export *
" >> "$FRAMEWORK_DIR/Modules/module.modulemap"

ln -sf "$SDKROOT/usr/include/CommonCrypto" "$FRAMEWORK_DIR/Headers"

像魅力一样工作:)

【讨论】:

您能否提供相同的演示或示例框架项目以及 pod 规范文件? @dvdblk 在我的情况下,我有一个自己的 pod,它使用了使用 CommonCrypto 的第三方 pod。我应该修复我的 pod 还是应该在第三方 pod 中修复它?【参考方案8】:

我认为我对 Mike Weller 的出色工作有所改进。

在包含此 bash 的 Compile Sources 阶段之前添加一个运行脚本阶段:

# This if-statement means we'll only run the main script if the
# CommonCrypto.framework directory doesn't exist because otherwise
# the rest of the script causes a full recompile for anything
# where CommonCrypto is a dependency
# Do a "Clean Build Folder" to remove this directory and trigger
# the rest of the script to run

FRAMEWORK_DIR="$BUILT_PRODUCTS_DIR/CommonCrypto.framework"

if [ -d "$FRAMEWORK_DIR" ]; then
echo "$FRAMEWORK_DIR already exists, so skipping the rest of the script."
exit 0
fi

mkdir -p "$FRAMEWORK_DIR/Modules"
cat <<EOF > "$FRAMEWORK_DIR/Modules/module.modulemap"
module CommonCrypto [system] 
    header "$SDKROOT/usr/include/CommonCrypto/CommonCrypto.h"
    export *

EOF

ln -sf "$SDKROOT/usr/include/CommonCrypto" "$FRAMEWORK_DIR/Headers"

此脚本在正确的位置使用 module.map 构建一个简单的框架,然后依赖于 Xcode 自动搜索 BUILT_PRODUCTS_DIR 的框架。

我将原始 CommonCrypto 包含文件夹链接为框架的 Headers 文件夹,因此结果也应该适用于 Objective C 项目。

【讨论】:

请参阅 dvdblk's answer 以了解涵盖 CocoaPods 使用的改进。【参考方案9】:

我发现了一个在 Swift 框架中成功使用 CommonCrypto 的 GitHub 项目:SHA256-Swift。另外,这篇关于the same problem with sqlite3 的文章很有用。

基于以上,步骤为:

1) 在项目目录中创建一个CommonCrypto 目录。在其中创建一个module.map 文件。模块映射将允许我们将 CommonCrypto 库用作 Swift 中的模块。它的内容是:

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

2) 在 Build Settings 中,在 Swift Compiler - Search Paths 中,将 CommonCrypto 目录添加到 Import Paths (SWIFT_INCLUDE_PATHS)。

3) 最后,在您的 Swift 文件中导入 CommonCrypto,作为任何其他模块。例如:

import CommonCrypto

extension String 

    func hnk_MD5String() -> String 
        if let data = self.dataUsingEncoding(NSUTF8StringEncoding)
        
            let result = NSMutableData(length: Int(CC_MD5_DIGEST_LENGTH))
            let resultBytes = UnsafeMutablePointer<CUnsignedChar>(result.mutableBytes)
            CC_MD5(data.bytes, CC_LONG(data.length), resultBytes)
            let resultEnumerator = UnsafeBufferPointer<CUnsignedChar>(start: resultBytes, length: result.length)
            let MD5 = NSMutableString()
            for c in resultEnumerator 
                MD5.appendFormat("%02x", c)
            
            return MD5
        
        return ""
    

限制

在另一个项目中使用自定义框架在编译时失败,错误为missing required module 'CommonCrypto'。这是因为 CommonCrypto 模块似乎没有包含在自定义框架中。一种解决方法是在使用该框架的项目中重复第 2 步(设置 Import Paths)。

模块映射不是独立于平台的(它当前指向一个特定的平台,iOS 8 模拟器)。我不知道如何使标题路径相对于当前平台。

iOS 8 的更新link "CommonCrypto" 行,以获得成功的编译。

更新/编辑

我不断收到以下构建错误:

ld:未找到用于架构 x86_64 的 -lCommonCrypto 的库 clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)

除非我从我创建的module.map 文件中删除了link "CommonCrypto" 行。一旦我删除了这条线,它就可以正常运行了。

【讨论】:

天啊,Apple 确实想让事情变得困难。让我们导入文件/框架而不必经历所有这些废话,会杀死 Swifties 吗? 这很令人恼火,因为$SDKROOT 变量应该允许您与平台无关的路径,但我不知道如何在 Swift 中实现这一点。 对我来说,直到我从 module.map 文件中删除 link "CommonCrypto" 后它才起作用。 任何人都可以确认这适用于 Xcode 7.3 吗?此解决方案在更新后停止为我工作。 更正:当我为模拟器构建时它工作正常,但当我为 iOS 9.3 设备构建“ld: library not found for -lCommonCrypto for architecture arm64”时@链接失败【参考方案10】:

警告:iTunesConnect 可能会reject 使用此方法的应用程序。


我团队的新成员不小心破坏了其中一个最佳答案给出的解决方案,因此我决定将其整合到一个名为 CommonCryptoModule 的小型包装项目中。您可以手动或通过 Cocoapods 安装它:

pod 'CommonCryptoModule', '~> 1.0.2'

然后,你所要做的就是在你需要CommonCrypto的地方导入模块,像这样:

import CommonCryptoModule

希望其他人觉得这很有用。

【讨论】:

警告:如果您使用此方法,您的申请将被拒绝! 是的,我们也被拒绝了,很奇怪,因为我们使用这种方法上传了几个月都没有问题。【参考方案11】:

这个答案讨论了如何使其在框架内以及 Cocoapods 和 Carthage 中工作

? modulemap 方法

我在 CommonCrypto https://github.com/onmyway133/arcane、https://github.com/onmyway133/Reindeer 的包装器中使用 modulemap

对于那些获得header not found的人,请查看https://github.com/onmyway133/Arcane/issues/4或运行xcode-select --install

创建一个文件夹CCommonCrypto,其中包含module.modulemap

  module CCommonCrypto 
    header "/usr/include/CommonCrypto/CommonCrypto.h"
    export *
  

转到内置设置 -> 导入路径

  $SRCROOT/Sources/CCommonCrypto

? 带有模块映射方法的 Cocoapods

这是 podspec https://github.com/onmyway133/Arcane/blob/master/Arcane.podspec

  s.source_files = 'Sources/**/*.swift'
  s.xcconfig =  'SWIFT_INCLUDE_PATHS' =>
  '$(PODS_ROOT)/CommonCryptoSwift/Sources/CCommonCrypto' 
  s.preserve_paths = 'Sources/CCommonCrypto/module.modulemap'

使用module_map 不起作用,请参阅https://github.com/CocoaPods/CocoaPods/issues/5271

通过 path 使用本地开发 Pod 不起作用,请参阅 https://github.com/CocoaPods/CocoaPods/issues/809

这就是为什么你看到我的示例 Podfile https://github.com/onmyway133/CommonCrypto.swift/blob/master/Example/CommonCryptoSwiftDemo/Podfile 指向 git 存储库

  target 'CommonCryptoSwiftDemo' do
    pod 'CommonCryptoSwift', :git => 'https://github.com/onmyway133/CommonCrypto.swift'
  end

?公共标头方法

Ji 是 libxml2 的包装器,它使用公共标头方法

它有一个头文件https://github.com/honghaoz/Ji/blob/master/Source/Ji.h,其中Target Membership 设置为Public

它有一个libxml2的头文件列表https://github.com/honghaoz/Ji/tree/master/Source/Ji-libxml

它有构建设置 -> 标题搜索路径

  $(SDKROOT)/usr/include/libxml2

它有构建设置 -> 其他链接器标志

  -lxml2

? 带有公共标头方法的 Cocoapods

看看 podspec https://github.com/honghaoz/Ji/blob/master/Ji.podspec

  s.libraries        = "xml2"
  s.xcconfig         =  'HEADER_SEARCH_PATHS' =>           '$(SDKROOT)/usr/include/libxml2', 'OTHER_LDFLAGS' => '-lxml2' 

? 有趣的相关帖子

How to call C from Swift? https://spin.atomicobject.com/2015/02/23/c-libraries-swift/

【讨论】:

哇!令我惊讶的是,当以前的模块映射文件引起很多问题时,***方法(创建 module.modulemap 文件)的标头路径效果很好。一段时间以来,我一直在为此苦苦挣扎,在 Applications/XCode.app/Contents/Developer/Platforms/iPhoneOS.... 中使用具有到 /CommonCrypto/CommonCrypto.h 的绝对路径的 module.modulemap 文件,这需要对重命名 XCode 的人进行手动修改。切换该行以查看 "/usr/include/CommonCrypto/CommonCrypto.h" 对于具有多个 XCode 版本的团队来说似乎工作正常。非常感谢! 我正在创建一个 pod,我设置了 SWIFT_INCLUDE_PATHS 和 preserve_paths。当我运行pod lib lint,但构建失败并出现错误:没有这样的模块'CommonCrypto'。我该如何处理。 与问题无关,但我喜欢将表情符号用作子弹! ? @onmyway133 如果将 $(PODS_ROOT)/CommonCryptoSwift/Sources/CCommonCrypto 替换为 $(PODS_TARGET_SRCROOT)/Sources/CCommonCrypto,则使用本地开发 pod 有效。 PODS_TARGET_SRCROOT 已为本地 pod 正确设置。 很好的答案,救了我的命!谢谢一百万【参考方案12】:

modulemap 解决方案可以很好,并且对 SDK 更改具有鲁棒性,但我发现它们在实践中使用起来很尴尬,并且在将东西分发给其他人时并不像我希望的那样可靠。为了让这一切变得更加万无一失,我采取了不同的方式:

只需复制标题即可。

我知道,脆弱。但 Apple 几乎从未对 CommonCrypto 做出重大改变,我梦想着他们不会在没有最终使 CommonCrypto 成为模块化标头的情况下以任何重大方式改变它。

“复制标头”是指“将您需要的所有标头剪切并粘贴到项目中的一个大型标头中,就像预处理器所做的那样。”作为您可以复制或改编的示例,请参阅RNCryptor.h。

请注意,所有这些文件均在 APSL 2.0 下获得许可,并且这种方法有意维护版权和许可声明。我的连接步骤已获得 MIT 许可,并且仅适用于下一个许可通知)。

我并不是说这是一个漂亮的解决方案,但到目前为止,它似乎是一个非常简单的实施和支持解决方案。

【讨论】:

我发现它可以可靠地编译,而且很简单。使用该框架的应用程序是否需要链接到任何特殊的东西,或者 CommonCrypto 是否始终可用? 我认为Security.framework 是自动链接的(自从开始一个新项目以来已经有一段时间了)。如果出现错误,那就是要链接的框架。 这似乎是最简单的解决方案,它在一台机器上运行良好,但每当我在另一台机器上使用另一个框架或应用程序中的框架时,我都会收到“缺少模块”错误。 【参考方案13】:

@mogstad 非常友好地将 @stephencelis 解决方案包装在 Cocoapod 中:

pod 'libCommonCrypto'

其他可用的 pod 对我不起作用。

【讨论】:

【参考方案14】:

我知道这是一个老问题。但我想出了一种在 Swift 项目中使用该库的替代方法,这可能对那些不想导入这些答案中介绍的框架的人有所帮助。

在 Swift 项目中,创建一个 Objective-C 桥接头,在 Objective-C 中创建 NSData 类别(或使用该库的自定义类)。唯一的缺点是您必须在 Objective-C 中编写所有实现代码。 例如:

#import "NSData+NSDataEncryptionExtension.h"
#import <CommonCrypto/CommonCryptor.h>

@implementation NSData (NSDataEncryptionExtension)
- (NSData *)AES256EncryptWithKey:(NSString *)key 
    //do something


- (NSData *)AES256DecryptWithKey:(NSString *)key 
//do something

然后在你的objective-c桥接头中,添加这个

#import "NSData+NSDataEncryptionExtension.h"

然后在 Swift 类中做类似的事情:

public extension String 
func encryp(withKey key:String) -> String? 
    if let data = self.data(using: .utf8), let encrypedData = NSData(data: data).aes256Encrypt(withKey: key) 
        return encrypedData.base64EncodedString()
    
    return nil

func decryp(withKey key:String) -> String? 
    if let data = NSData(base64Encoded: self, options: []), let decrypedData = data.aes256Decrypt(withKey: key) 
        return decrypedData.UTF8String
    
    return nil


它按预期工作。

【讨论】:

这工作非常顺利,甚至允许您将内部信息保留在内部(NSData+NSDataEncryptionExtension.h 不必公开)。 但是我应该链接什么操作系统框架才能使用这个东西?与其他人不同 - 我必须在 Obj-C 项目中使用 CommonCrypto,仅此一项就在带有 MacOS-10.13 SDK 的 Xcode 9 上中断 @MottiShneor 链接 10.9 或更高版本的任何操作系统。我在相同的环境下工作,它工作正常。【参考方案15】:

您实际上可以构建一个“正常工作”的解决方案(无需将 module.modulemapSWIFT_INCLUDE_PATHS 设置复制到您的项目中,正如此处其他解决方案所要求的那样),但它确实需要您创建一个虚拟框架/模块,您将正确地导入您的框架。我们还可以确保它不受平台限制(iphoneosiphonesimulatormacosx)。

    向您的项目添加一个新的框架目标,并以系统库命名,例如,“CommonCrypto”。 (您可以删除伞形标题 CommonCrypto.h。)

    添加一个新的配置设置文件并将其命名,例如,“CommonCrypto.xcconfig”。 (不要检查您的任何目标是否包含在内。)用以下内容填充它:

    MODULEMAP_FILE[sdk=iphoneos*]        = \
        $(SRCROOT)/CommonCrypto/iphoneos.modulemap
    MODULEMAP_FILE[sdk=iphonesimulator*] = \
        $(SRCROOT)/CommonCrypto/iphonesimulator.modulemap
    MODULEMAP_FILE[sdk=macosx*]          = \
        $(SRCROOT)/CommonCrypto/macosx.modulemap
    

    创建上面三个引用的模块映射文件,并用以下内容填充它们:

    iphoneos.modulemap

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

    iphonesimulator.modulemap

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

    ma​​cosx.modulemap

    module CommonCrypto [system] 
        header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/CommonCrypto/CommonCrypto.h"
        export *
    
    

    (如果您运行的是 beta 版本,请将“Xcode.app”替换为“Xcode-beta.app”。如果未运行 El Capitan,请将 10.11 替换为您当前的 OS SDK。)

    在项目设置的 Info 选项卡上的 Configurations 下,设置 DebugRelease > CommonCryptoCommonCrypto 的配置(参考 CommonCrypto.xcconfig)。

    在框架目标的 Build Phases 选项卡上,将 CommonCrypto 框架添加到 Target Dependencies。此外,将 libcommonCrypto.dylib 添加到 Link Binary With Libraries 构建阶段。

    Products 中选择 CommonCrypto.framework 并确保您的包装器的 Target Membership 设置为 Optional。

您现在应该能够在您的包装器框架中构建、运行和import CommonCrypto

例如,查看SQLite.swift 如何使用虚拟 sqlite3.framework

【讨论】:

无需步骤 (5) 即可为我工作。有了它,我得到一个构建错误:ld: cannot link directly with /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.2.sdk/usr/lib/system/libcommonCrypto.dylib. Link against the umbrella framework 'System.framework' instead. for architecture x86_64 太棒了!用它来制作github.com/soffes/Crypto 虽然我不必链接System.framework。值得注意的是,如果你的框架是跨平台的,你必须为 Mac 和 iOS 制作一个单独的包装框架。 人们如何或在哪里找到这样的东西? 只是一个注释清楚地表明您需要在步骤 1 中选择 Objective-C 作为语言。这很容易被忽略。另外,可能是因为我没有 .dylib,所以需要在第 5 步中添加 .framework。 这太可怕了。我有一个 Xcode 动物园,每个 Xcode 都以不同的方式被破坏,并且到处都有到标题的绝对路径是呕吐调用。库比蒂诺出现了严重的问题,或者至少是负责这个模块映射混乱的人【参考方案16】:

这很简单。添加

#import <CommonCrypto/CommonCrypto.h>

到 .h 文件(项目的桥接头文件)。作为约定,您可以将其称为 YourProjectName-Bridging-Header.h。

然后转到您的项目 Build Settings 并查找 Swift Compiler - Code Generation。在它下面,将您的桥接头名称添加到条目“Objetive-C Bridging Header”中。

你已经完成了。您的 Swift 代码中不需要导入。此桥接头文件中列出的任何公共 Objective-C 标头对 Swift 都是可见的。

【讨论】:

您的方法返回错误:不支持使用带有框架目标的桥接头 @gorgi93 如错误所示,您不能在框架目标中使用桥接头。不幸的是,唯一的选择是将它放在主框架头文件中。 如果你真的把这个帖子的标题写成红色,你会看到这个人想要将 CommonCrypto 库导入到 Swift 框架中。不能在框架中使用桥接头,也不能将 CommonCrypto 框架导入伞头。

以上是关于在 Swift 框架中导入 CommonCrypto的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 项目中导入 Zbar 框架

如何在 Swift 项目中导入 Zbar 框架

在 Objective-C(测试)代码中导入框架的 Swift 类

在 Swift Playground 中导入使用 Firebase 的框架(“缺少必需的模块 'Firebase'”)

Xcode Swift 在“应用程序目标”与“框架目标”中导入代码——有啥区别?

使用 Swift 4.0 编译的模块无法在 Swift 3.1 中导入框架二进制文件