CommonCrypto
iOS 용 Swift 프레임 워크에서 어떻게 가져 옵니까?
CommonCrypto
Swift 앱에서 사용하는 방법을 이해합니다 #import <CommonCrypto/CommonCrypto.h>
. 브리징 헤더에 추가 합니다. 그러나 Swift 프레임 워크는 브리징 헤더를 지원하지 않습니다. 문서는 말합니다 :
순수한 Objective-C 코드베이스, 순수한 Swift 코드베이스 또는 혼합 언어 코드베이스가있는 외부 프레임 워크를 가져올 수 있습니다. 외부 프레임 워크를 가져 오는 프로세스는 프레임 워크가 단일 언어로 작성되었는지 또는 두 언어의 파일을 포함하는지에 관계없이 동일합니다. 외부 프레임 워크를 가져올 때 가져 오려는 프레임 워크에 대한 모듈 빌드 정의 설정이 예로 설정되어 있는지 확인하십시오.
다음 구문을 사용하여 다른 대상 내의 Swift 파일로 프레임 워크를 가져올 수 있습니다.
import FrameworkName
불행히도 가져 오기 CommonCrypto
가 작동하지 않습니다. #import <CommonCrypto/CommonCrypto.h>
우산 헤더에 추가하지 않습니다 .
답변
조금 더 간단하고 강력한 것은 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
쉘 코드를 사용 ${SDKROOT}
하면 Xcode.app 경로를 하드 코딩 할 필요가 없으며 특히 시스템을 사용하는 경우 시스템마다 다를 수 있습니다xcode-select
베타 버전으로 전환하거나 여러 버전이 설치된 CI 서버에 구축하는 경우 비표준 위치. 또한 SDK를 하드 코딩 할 필요가 없으므로 iOS, macOS 등에서 작동합니다. 또한 프로젝트의 소스 디렉토리에 아무것도 없어도됩니다.
이 대상을 만든 후 대상 종속성 항목을 사용하여 라이브러리 / 프레임 워크에 종속되도록하십시오.
이를 통해 프레임 워크가 빌드되기 전에 모듈 맵이 생성됩니다.
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을 모두 지원하려면 스크립트 실행 단계에서 모듈 맵의 존재 여부를 확인하십시오.
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
답변
실제로 “작동하는”솔루션을 만들 수 있습니다 ( 여기에서 다른 솔루션에 필요한대로 module.modulemap 및 SWIFT_INCLUDE_PATHS
설정을 프로젝트 에 복사 할 필요는 없음 ).하지만 더미 프레임 워크 / 모듈을 만들어야합니다. 프레임 워크로 가져옵니다. 우리는 또한이 플랫폼에 관계없이 작동하는지 확인 할 수 있습니다 ( 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
-
위의 세 가지 참조 모듈 맵 파일을 작성하고 다음으로 채우십시오.
-
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 * }
-
macosx. 모듈 맵
module CommonCrypto [system] { header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/CommonCrypto/CommonCrypto.h" export * }
베타 버전을 실행중인 경우 “Xcode.app”를 “Xcode-beta.app”로 바꾸
10.11
십시오. El Capitan을 실행하지 않는 경우 현재 OS SDK로 교체하십시오 . -
-
프로젝트 설정 의 정보 탭에서 구성 아래 의 디버그 및 릴리스 구성을 설정하십시오. CommonCrypto을 에 CommonCrypto (참조 CommonCrypto.xcconfig ).
-
프레임 워크 대상의 빌드 단계 탭에서 CommonCrypto 프레임 워크를 대상 종속성에 추가하십시오. . 또한 라이브러리와 바이너리 연결 빌드 단계 에 libcommonCrypto.dylib 를 추가하십시오 .
-
제품 에서 CommonCrypto.framework 를 선택 하고 랩퍼 대상 멤버쉽 이 선택 사항 으로 설정되어 .
이제 import CommonCrypto
래퍼 프레임 워크에서 빌드, 실행 및 실행할 수 있어야합니다 .
예를 들어, SQLite.swift 가 더미 sqlite3.framework를 사용하는 방법을 보십시오 .
답변
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 *
}
2) 빌드 설정의 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 모듈이 사용자 지정 프레임 워크에 포함되어 있지 않기 때문입니다. 해결 방법은 Import Paths
프레임 워크를 사용하는 프로젝트에서 2 단계 (설정 ) 를 반복 하는 것입니다.
모듈 맵은 플랫폼 독립적이지 않습니다 (현재는 특정 플랫폼, iOS 8 시뮬레이터를 가리킴). 현재 플랫폼을 기준으로 헤더 경로를 만드는 방법을 모르겠습니다.
iOS 8 업데이트 <= 줄을 제거해야합니다 성공적인 컴파일을 위해 “CommonCrypto” 링크를 .
업데이트 / 편집
다음과 같은 빌드 오류가 계속 발생했습니다.
ld : x86_64 아키텍처의 -lCommonCrypto 라이브러리를 찾을 수 없음 : 오류 : 종료 코드 1에서 링커 명령이 실패했습니다 (호출을 보려면 -v 사용).
내가 만든 파일 에서 줄 link "CommonCrypto"
을 제거하지 않으면 module.map
이 줄을 제거하면 정상적으로 빌드되었습니다.
답변
이 답변에서는 프레임 워크 내에서 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 * }
-
기본 설정으로 이동-> 경로 가져 오기
${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
수없는 경우 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
? 공개 헤더 접근
-
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
공개 헤더 접근 방식의 Cocoapod
-
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' }
? 재미있는 관련 게시물
답변
좋은 소식! 스위프트 4.2 (Xcode 10)는 마침내 CommonCrypto를 제공합니다!
import CommonCrypto
신속한 파일을 추가 하십시오.
답변
경고 : iTunesConnect는 이 방법을 사용하는 응용 프로그램을 거부 할 수 있습니다 .
우리 팀의 새 멤버가 실수로 최고의 답변 중 하나가 제공 한 솔루션을 중단했기 때문에 CommonCryptoModule 이라는 작은 래퍼 프로젝트로 솔루션을 통합하기로 결정했습니다 . 수동으로 또는 Cocoapods를 통해 설치할 수 있습니다.
pod 'CommonCryptoModule', '~> 1.0.2'
그런 다음 필요한 부분을 다음 CommonCrypto
과 같이 가져 오면됩니다 .
import CommonCryptoModule
다른 사람이 이것을 유용하게 사용하기를 바랍니다.
답변
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"
이 스크립트는 올바른 위치에 module.map을 사용하여 베어 본 프레임 워크를 구성한 다음 Xcode의 자동 검색을 사용합니다. BUILT_PRODUCTS_DIR
프레임 워크 합니다.
원래 CommonCrypto include 폴더를 프레임 워크의 Headers 폴더로 연결 했으므로 Objective C 프로젝트에서도 결과가 작동해야합니다.