hpi*_*que 181 ios commoncrypto swift
如何CommonCrypto
在iOS的Swift框架中导入?
我理解如何CommonCrypto
在Swift应用程序中使用:您添加#import <CommonCrypto/CommonCrypto.h>
到桥接标头.但是,Swift框架不支持桥接头.该文件说:
您可以导入具有纯Objective-C代码库,纯Swift代码库或混合语言代码库的外部框架.无论框架是用单一语言编写还是包含来自两种语言的文件,导入外部框架的过程都是相同的.导入外部框架时,请确保将要导入的框架的"定义模块"构建设置设置为"是".
您可以使用以下语法将框架导入到不同目标中的任何Swift文件中:
import FrameworkName
Run Code Online (Sandbox Code Playgroud)
不幸的是,导入CommonCrypto
不起作用.也没有添加#import <CommonCrypto/CommonCrypto.h>
到伞头.
Mik*_*ler 133
更简单,更健壮的东西是使用Run Script阶段创建一个名为"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
Run Code Online (Sandbox Code Playgroud)
使用shell代码并且${SDKROOT}
意味着您不必对Xcode.app路径进行硬编码,这可能会改变系统到系统,特别是如果您使用xcode-select
切换到测试版,或者是在安装了多个版本的CI服务器上构建在非标准的位置.您也不需要对SDK进行硬编码,因此这适用于iOS,macOS等.您也不需要在项目的源目录中放置任何内容.
创建此目标后,使用Target Dependencies项使您的库/框架依赖它:
这将确保在构建框架之前生成模块映射.
MACOS注:如果你支持macOS
的话,你会需要添加macosx
到Supported Platforms
构建你刚刚创建的新的总目标设定,否则将不把模块映射在正确的Debug
导出数据文件夹的其余部分框架产品.
接下来,将模块映射的父目录添加到${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap
Swift部分(SWIFT_INCLUDE_PATHS
)下的"Import Paths"构建设置:
$(inherited)
如果在项目或xcconfig级别定义了搜索路径,请记住添加一行.
就是这样,你现在应该可以 import CommonCrypto
更新Xcode 10
Xcode 10现在附带了一个CommonCrypto模块映射,因此不需要这种解决方法.如果您想同时支持Xcode 9和10,您可以在Run Script阶段检查模块映射是否存在,例如
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
Run Code Online (Sandbox Code Playgroud)
ste*_*lis 90
您实际上可以构建一个"正常工作"的解决方案(无需将module.modulemap和SWIFT_INCLUDE_PATHS
设置复制到您的项目中,这是其他解决方案所要求的),但它确实需要您创建一个虚拟框架/模块,您可以将ll导入到您的框架中.我们也可以保证它工作平台无论是(iphoneos
,iphonesimulator
,或macosx
).
向项目添加新的框架目标,并在系统库之后命名,例如 "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
Run Code Online (Sandbox Code Playgroud)在上面创建三个引用的模块映射文件,并使用以下内容填充它们:
iphoneos.modulemap
module CommonCrypto [system] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
export *
}
Run Code Online (Sandbox Code Playgroud)iphonesimulator.modulemap
module CommonCrypto [system] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h"
export *
}
Run Code Online (Sandbox Code Playgroud)macosx.modulemap
module CommonCrypto [system] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/CommonCrypto/CommonCrypto.h"
export *
}
Run Code Online (Sandbox Code Playgroud)(如果您正在运行测试版,请将"Xcode.app"替换为"Xcode-beta.app".10.11
如果没有运行El Capitan,请替换为您当前的OS SDK.)
在项目设置的" 信息"选项卡上的" 配置"下,将CommonCrypto的" 调试"和" 发布"配置设置为" CommonCrypto"(引用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.
hpi*_*que 82
我找到了一个在Swift框架中成功使用CommonCrypto的GitHub项目:SHA256-Swift.此外,这篇关于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 *
}
Run Code Online (Sandbox Code Playgroud)
2)在构建设置中,在Swift编译器 - 搜索路径中,将CommonCrypto
目录添加到导入路径(SWIFT_INCLUDE_PATHS
).
3)最后,将Swice文件中的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 ""
}
}
Run Code Online (Sandbox Code Playgroud)
在另一个项目中使用自定义框架在编译时失败并出现错误missing required module 'CommonCrypto'
.这是因为CommonCrypto模块似乎不包含在自定义框架中.解决方法是Import Paths
在使用框架的项目中重复步骤2(设置).
模块映射不是平台独立的(它当前指向特定平台,iOS 8模拟器).我不知道如何制作相对于当前平台的标题路径.
iOS 8的更新<=我们应该删除行链接"CommonCrypto",以获得成功的编译.
更新/编辑
我一直收到以下构建错误:
ld:找不到-lCommonCrypto用于体系结构x86_64 clang的库:错误:链接器命令失败,退出代码为1(使用-v查看调用)
除非我link "CommonCrypto"
从module.map
我创建的文件中删除了该行.一旦我删除了这一行,它就构建好了.
onm*_*133 50
这个答案讨论了如何使它在框架内工作,以及Cocoapods和Carthage
模块图方法
我用modulemap
我的包装器CommonCrypto https://github.com/onmyway133/arcane,https://github.com/onmyway133/Reindeer
对于那些获取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 *
}
Run Code Online (Sandbox Code Playgroud)转到"已建设置" - >"导入路径"
${SRCROOT}/Sources/CCommonCrypto
Run Code Online (Sandbox Code Playgroud)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'
Run Code Online (Sandbox Code Playgroud)使用module_map
不起作用,请参阅https://github.com/CocoaPods/CocoaPods/issues/5271
使用Local Development Pod path
不起作用,请参阅https://github.com/CocoaPods/CocoaPods/issues/809
这就是为什么你看到我的示例Podfile https://github.com/onmyway133/CommonCrypto.swift/blob/master/Example/CommonCryptoSwiftDemo/Podfile指向git repo
target 'CommonCryptoSwiftDemo' do
pod 'CommonCryptoSwift', :git => 'https://github.com/onmyway133/CommonCrypto.swift'
end
Run Code Online (Sandbox Code Playgroud)公共标题方法
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
它有Build Settings - > Header Search Paths
$(SDKROOT)/usr/include/libxml2
Run Code Online (Sandbox Code Playgroud)它有Build Settings - > Other Linker Flags
-lxml2
Run Code Online (Sandbox Code Playgroud)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' }
Run Code Online (Sandbox Code Playgroud)有趣的相关帖子
警告:iTunesConnect可能会拒绝使用此方法的应用.
我的团队中的新成员不小心打破了其中一个最佳答案给出的解决方案,因此我决定将其整合到一个名为CommonCryptoModule的小包装项目中.您可以手动安装或通过Cocoapods安装:
pod 'CommonCryptoModule', '~> 1.0.2'
Run Code Online (Sandbox Code Playgroud)
然后,您所要做的就是在需要的地方导入模块CommonCrypto
,如下所示:
import CommonCryptoModule
Run Code Online (Sandbox Code Playgroud)
希望别人觉得这很有用.
我想我对Mike Weller的出色工作有所改进.
在Compile Sources
包含此bash的阶段之前添加运行脚本阶段:
# 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"
Run Code Online (Sandbox Code Playgroud)
这个脚本在正确的位置构建了一个带有module.map的裸骨架,然后依赖于Xcode自动搜索BUILT_PRODUCTS_DIR
框架.
我将原始的CommonCrypto include文件夹链接为框架的Headers文件夹,因此结果也应该用于Objective C项目.
For anyone using swift 4.2 with Xcode 10:
CommonCrypto module is now provided by the system, so you can directly import it like any other system framework.
import CommonCrypto
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
95083 次 |
最近记录: |