Nhập CommonCrypto trong khung Swift


184

Làm cách nào để bạn nhập CommonCryptotrong khung Swift cho iOS?

Tôi hiểu cách sử dụng CommonCryptotrong ứng dụng Swift: Bạn thêm #import <CommonCrypto/CommonCrypto.h>vào tiêu đề bắc cầu. Tuy nhiên, các khung Swift không hỗ trợ các tiêu đề bắc cầu. Các tài liệu nói:

Bạn có thể nhập các khung bên ngoài có một cơ sở mã Objective-C thuần túy, một cơ sở mã Swift thuần túy hoặc một cơ sở mã ngôn ngữ hỗn hợp. Quá trình nhập một khung bên ngoài là giống nhau cho dù khung được viết bằng một ngôn ngữ hoặc chứa các tệp từ cả hai ngôn ngữ. Khi bạn nhập khung bên ngoài, hãy đảm bảo cài đặt xây dựng Mô-đun xác định cho khung bạn đang nhập được đặt thành Có.

Bạn có thể nhập khung vào bất kỳ tệp Swift nào trong một mục tiêu khác bằng cú pháp sau:

import FrameworkName

Thật không may, nhập khẩu CommonCryptokhông hoạt động. Không thêm #import <CommonCrypto/CommonCrypto.h>vào tiêu đề ô.


CommonCrypto là khung dựa trên C, không phải khung Objective-C.
rmaddy

1
@rmaddy Objective-C là một superset C. Bạn đang nói rằng chúng tôi không thể sử dụng CommonCrypto từ Swift?
hpique

4
@rmaddy Tôi chỉ quản lý để CommonCrypto hoạt động bằng cách sử dụng bản đồ mô-đun. Tôi sẽ đánh bóng các giải pháp và gửi nó sau ngày hôm nay.
hpique

nếu bạn thấy thuận tiện và những gì bạn đang tìm kiếm đã được triển khai, bạn có thể dùng thử CryptoSwift
Marcin

1
Apple chỉ cần mở CommonCrypto. Có lẽ chúng ta có thể làm cho nó chạy nếu chúng ta có các nguồn.
nhãn cầu

Câu trả lời:


137

Một cái gì đó đơn giản và mạnh mẽ hơn một chút là tạo một mục tiêu Tổng hợp có tên là "CommonCryptoModuleMap" với giai đoạn Run Script để tự động tạo bản đồ mô-đun và với đường dẫn Xcode / SDK chính xác:

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Giai đoạn Run Script sẽ chứa bash này:

# 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

Sử dụng mã shell và ${SDKROOT}có nghĩa là bạn không phải mã cứng đường dẫn Xcode.app có thể thay đổi hệ thống này sang hệ thống khác, đặc biệt nếu bạn sử dụng xcode-selectđể chuyển sang phiên bản beta hoặc đang xây dựng trên máy chủ CI có cài đặt nhiều phiên bản ở những vị trí không chuẩn. Bạn cũng không cần mã cứng SDK để nó hoạt động cho iOS, macOS, v.v. Bạn cũng không cần phải có bất cứ thứ gì trong thư mục nguồn của dự án.

Sau khi tạo mục tiêu này, hãy làm cho thư viện / khung của bạn phụ thuộc vào mục đó với mục Phụ thuộc mục tiêu:

nhập mô tả hình ảnh ở đây

Điều này sẽ đảm bảo bản đồ mô-đun được tạo trước khi khung của bạn được xây dựng.

macOS lưu ý : Nếu bạn macOScũng hỗ trợ , bạn sẽ cần thêm macosxvào Supported Platformscài đặt bản dựng trên mục tiêu tổng hợp mới mà bạn vừa tạo, nếu không, nó sẽ không đặt bản đồ mô-đun vào Debugthư mục dữ liệu dẫn xuất chính xác với phần còn lại của khung sản phẩm.

nhập mô tả hình ảnh ở đây

Tiếp theo, thêm thư mục mẹ của sơ đồ mô-đun ${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap, vào cài đặt xây dựng "Nhập đường dẫn" trong phần Swift ( SWIFT_INCLUDE_PATHS):

nhập mô tả hình ảnh ở đây

Hãy nhớ thêm một $(inherited)dòng nếu bạn có các đường dẫn tìm kiếm được xác định ở cấp độ dự án hoặc xcconfig.

Đó là nó, bây giờ bạn có thể import CommonCrypto

Cập nhật cho Xcode 10

Xcode 10 hiện có một bản đồ mô-đun CommonCrypto khiến cho cách giải quyết này không cần thiết. Nếu bạn muốn hỗ trợ cả Xcode 9 và 10, bạn có thể thực hiện kiểm tra trong giai đoạn Run Script để xem bản đồ mô-đun có tồn tại hay không, ví dụ:

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

8
Câu trả lời này nên được đặt lên hàng đầu. Đơn giản và thanh lịch
Abdullah Saeed

1
Cuối trò chơi này - nhưng đây sẽ là câu trả lời được chọn. Thật đơn giản và dễ dàng hơn cho các nhà phát triển khác làm việc trong cùng một dự án để xem yêu cầu.
mệt mỏi.logic

1
Câu trả lời chính xác. Cảm ơn!
Klaus Busse

1
Nếu tôi làm điều này trong .framework của tôi, tôi có nên làm tương tự trong các dự án mà tôi bao gồm khung này không?
Ravi Kiran

2
@IanDundas Tôi đã cập nhật mã ở trên với bản sửa lỗi cho sự cố biên dịch lại cũng như cách khắc phục để sử dụng mã này trên macOS
iwasrobbed

91

Bạn thực sự có thể xây dựng một giải pháp "chỉ hoạt động" (không cần sao chép mô- đun.modulemapSWIFT_INCLUDE_PATHScài đặt vào dự án của bạn, theo yêu cầu của các giải pháp khác ở đây), nhưng nó yêu cầu bạn phải tạo một khung / mô-đun giả mà bạn ' sẽ nhập vào khuôn khổ của bạn thích hợp. Chúng tôi cũng có thể đảm bảo nó hoạt động không phụ thuộc nền tảng ( iphoneos, iphonesimulatorhoặc macosx).

  1. Thêm một mục tiêu khung mới cho dự án của bạn và đặt tên nó theo thư viện hệ thống, ví dụ: "CommonCrypto". (Bạn có thể xóa tiêu đề ô, CommonCrypto.h .)

  2. Thêm một tệp cài đặt cấu hình mới và đặt tên cho nó, ví dụ: "CommonCrypto.xcconfig". (Đừng kiểm tra bất kỳ mục tiêu nào của bạn để đưa vào.) Hãy điền vào mục sau:

    MODULEMAP_FILE[sdk=iphoneos*]        = \
        $(SRCROOT)/CommonCrypto/iphoneos.modulemap
    MODULEMAP_FILE[sdk=iphonesimulator*] = \
        $(SRCROOT)/CommonCrypto/iphonesimulator.modulemap
    MODULEMAP_FILE[sdk=macosx*]          = \
        $(SRCROOT)/CommonCrypto/macosx.modulemap
  3. Tạo ba tệp bản đồ mô-đun được tham chiếu ở trên và điền chúng với các mục sau:

    • 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.modulemap

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

    (Thay thế "Xcode.app" bằng "Xcode-beta.app" nếu bạn đang chạy phiên bản beta. Thay thế 10.11bằng SDK hệ điều hành hiện tại của bạn nếu không chạy El Capitan.)

  4. Trên tab Thông tin của cài đặt dự án của bạn, bên dưới Cấu hình , đặt cấu hình Gỡ lỗiPhát hành của CommonCrypto thành CommonCrypto (tham chiếu CommonCrypto.xcconfig ).

  5. Về mục tiêu khuôn khổ của bạn giai đoạn xây dựng tab, thêm CommonCrypto khuôn khổ để Target Dependencies . Ngoài ra, thêm libcommonCrypto.dylib vào giai đoạn xây dựng Liên kết nhị phân với thư viện .

  6. Chọn CommonCrypto.framework trong Sản phẩm và đảm bảo Tư cách thành viên mục tiêu của nó cho trình bao bọc của bạn được đặt thành Tùy chọn .

Bây giờ bạn có thể xây dựng, chạy và import CommonCrypto trong khung trình bao bọc của bạn.

Để biết ví dụ, hãy xem cách SQLite.swift sử dụng một sqlite3.framework giả .


4
Làm việc cho tôi mà không cần bước (5). Với nó, tôi gặp lỗi xây dựng: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
stannie

4
Thông minh! Đã sử dụng điều này để tạo github.com/soffes/Crypto Tôi không phải liên kết System.framework. Điều đáng chú ý, bạn phải tạo một khung bao bọc riêng cho Mac và iOS nếu khung của bạn là đa nền tảng.
Sam Soffes

32
Làm thế nào hoặc ở đâu mọi người tìm ra những thứ như thế này?
hola

5
Chỉ cần một lưu ý cho thấy rõ rằng bạn cần chọn Objective-C làm ngôn ngữ trong bước 1. Điều này dễ bị bỏ qua. Ngoài ra, có lẽ vì tôi không có .dylib, tôi cần thêm .framework ở bước 5.
Teo Sartori

7
điều này thật kinh khủng Tôi có một sở thú Xcodes mỗi cái bị phá vỡ theo một cách khác nhau và có những con đường tuyệt đối đến các tiêu đề ở khắp mọi nơi đang kêu gọi. Một cái gì đó đang hết sức sai lầm ở cupertino, hoặc ít nhất là với bất kỳ ai chịu trách nhiệm về mớ hỗn độn này
Anton Tropashko

82

Tôi đã tìm thấy một dự án GitHub sử dụng thành công CommonCrypto trong khung Swift: SHA256-Swift . Ngoài ra, bài viết này về cùng một vấn đề với sqlite3 là hữu ích.

Dựa trên các bước trên, các bước là:

1) Tạo một CommonCryptothư mục bên trong thư mục dự án. Trong, tạo một module.maptập tin. Bản đồ mô-đun sẽ cho phép chúng tôi sử dụng thư viện CommonCrypto làm mô-đun trong Swift. Nội dung của nó là:

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) Trong Cài đặt bản dựng, trong Trình biên dịch Swift - Đường dẫn tìm kiếm , thêm CommonCryptothư mục vào Nhập đường dẫn ( SWIFT_INCLUDE_PATHS).

Xây dựng cài đặt

3) Cuối cùng, nhập CommonCrypto bên trong các tệp Swift của bạn như bất kỳ mô-đun nào khác. Ví dụ:

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 ""
    }
}

Hạn chế

Sử dụng khung tùy chỉnh trong dự án khác không thành công khi biên dịch lỗi missing required module 'CommonCrypto'. Điều này là do mô-đun CommonCrypto dường như không được bao gồm trong khung tùy chỉnh. Cách giải quyết là lặp lại bước 2 (cài đặtImport Paths ) trong dự án sử dụng khung.

Bản đồ mô-đun không độc lập với nền tảng (hiện tại nó trỏ đến một nền tảng cụ thể, Trình mô phỏng iOS 8). Tôi không biết cách tạo đường dẫn tiêu đề liên quan đến nền tảng hiện tại.

Cập nhật cho iOS 8 <= Chúng ta nên xóa liên kết dòng "CommonCrypto" , để có được quá trình biên dịch thành công.

CẬP NHẬT / EDIT

Tôi tiếp tục nhận được lỗi xây dựng sau:

ld: không tìm thấy thư viện cho -lCommonCrypto cho kiến ​​trúc x86_64 clang: error: lệnh linker không thành công với mã thoát 1 (sử dụng -v để xem lời mời)

Trừ khi tôi xóa dòng link "CommonCrypto"khỏi module.maptệp tôi đã tạo. Khi tôi gỡ bỏ dòng này, nó được xây dựng ok.


30
Gee, Apple chắc chắn muốn làm khó mọi thứ. Nó sẽ giết Swifties chỉ để chúng tôi nhập tệp / khung mà không phải thông qua tất cả BS này?
zaph

4
Điều này gây phẫn nộ vì $SDKROOTbiến được cho là cho phép bạn tạo nền tảng cho các đường dẫn bất khả tri, nhưng tôi không biết làm thế nào để đến đó trong Swift.
danimal

2
Đối với tôi nó không hoạt động cho đến khi tôi gỡ bỏ link "CommonCrypto"tệp module.map.
Teo Sartori

1
Bất cứ ai cũng có thể xác nhận điều này làm việc trên Xcode 7.3? Giải pháp này đã ngừng hoạt động cho tôi sau khi cập nhật.
Nikita Kukushkin

1
Correnction: nó hoạt động tốt khi tôi xây dựng cho trình giả lập, nhưng không liên kết @ khi tôi xây dựng cho thiết bị iOS 9.3 với "ld: library không tìm thấy cho -lCommonCrypto cho kiến ​​trúc arm64"
Nikita Kukushkin

50

Câu trả lời này thảo luận về cách làm cho nó hoạt động trong một khung, và với Cocoapods và Carthage

Approach phương pháp modulemap

Tôi sử dụng modulemaptrong trình bao bọc của mình xung quanh CommonCrypto https://github.com/onmyway133/arcane , https://github.com/onmyway133/Reindeer

Đối với những người nhận được header not found, xin vui lòng xem https://github.com/onmyway133/Arcane/issues/4 hoặc chạyxcode-select --install

  • Tạo một thư mục CCommonCryptochứamodule.modulemap

      module CCommonCrypto {
        header "/usr/include/CommonCrypto/CommonCrypto.h"
        export *
      }
  • Chuyển đến Cài đặt được xây dựng -> Nhập đường dẫn

      ${SRCROOT}/Sources/CCommonCrypto

Cocoapods với phương pháp modulemap

Approach phương pháp tiếp cận tiêu đề công cộng

Cocoapods với cách tiếp cận tiêu đề công khai

Bài viết liên quan thú vị


1
Ồ Thật ngạc nhiên, đường dẫn tiêu đề từ cách tiếp cận hàng đầu (tạo tệp module.modulemap) hoạt động rất tốt khi các tệp modulemap trước đây đã gây ra nhiều vấn đề. Tôi đã phải vật lộn với điều này trong một thời gian bằng cách sử dụng tệp module.modulemap với đường dẫn tuyệt đối đến /CommonCrypto/CommonCrypto.hbên trong Applications/XCode.app/Contents/Developer/Platforms/iPhoneOS...., yêu cầu sửa đổi thủ công cho những người đã đổi tên XCode. Chuyển dòng đó để xem xét "/usr/include/CommonCrypto/CommonCrypto.h"có vẻ hoạt động tốt cho một nhóm với một số phiên bản XCode. Cảm ơn bạn rất nhiều!
Natalia

3
Tôi đang tạo một nhóm, tôi đặt SWIFT_INCLUDE_PATHS và reserved_paths. Khi tôi chạy pod lib lint, nhưng quá trình xây dựng không thành công do lỗi: không có mô-đun 'CommonCrypto' như vậy. Làm thế nào tôi có thể đối phó với nó.
Klein Mioke

1
Không liên quan đến vấn đề nhưng tôi thích sử dụng biểu tượng cảm xúc như viên đạn! 😊
Fomentia

2
@ onmyway133 Sử dụng pod phát triển cục bộ hoạt động nếu bạn thay thế $(PODS_ROOT)/CommonCryptoSwift/Sources/CCommonCryptobằng $(PODS_TARGET_SRCROOT)/Sources/CCommonCrypto. PODS_TARGET_SRCROOTđược đặt chính xác cho các nhóm cục bộ.
Orkhan Alikhanov

Câu trả lời tuyệt vời, đã cứu mạng tôi! Cảm ơn một triệu
Hassan Shahbazi

45

Tin tốt! Swift 4.2 (Xcode 10) cuối cùng cũng cung cấp CommonCrypto!

Chỉ cần thêm import CommonCryptovào tập tin nhanh chóng của bạn.


Tin tốt! Bạn có thể thêm liên kết đến tài liệu?
Kryštof Matěj

Tôi không có liên kết đến tài liệu, tôi đã phát hiện ra điều này trong khi cố gắng biên dịch một dự án nơi tôi có một trong những cách giải quyết ở đây với Xcode 10. Nó phàn nàn rằng nó có thể tìm thấy hai CommonCryptomô-đun, do đó nghi ngờ Apple đã cung cấp cho tôi cách gỡ bỏ và 'lo! Đó là sự thật. Tôi đã tweet về nó và một kỹ sư của Apple đã trả lời xác nhận rằng nó đã được dự định.
mxcl

1
Cửa hàng ứng dụng chỉ hiển thị cho tôi 9.4.7 dưới dạng bản cập nhật khả dụng, làm thế nào bạn có Xcode 10?
Hammad Tariq

1
Đây là phiên bản beta như một tìm kiếm tầm thường của Google sẽ cho bạn biết.
mxcl

1
@SomoyDasGupta có. Chỉ cần loại bỏ nhập trước đó, và biên dịch lại. Nói cách khác, bạn không phải thực hiện các bước từ câu trả lời của MikeWeller
ICE

7

CẢNH BÁO: iTunesConnect có thể từ chối các ứng dụng đang sử dụng phương pháp này.


Thành viên mới trong nhóm của tôi đã vô tình phá vỡ giải pháp được đưa ra bởi một trong những câu trả lời hàng đầu, vì vậy tôi quyết định hợp nhất nó trong một dự án trình bao bọc nhỏ có tên CommonCryptoModule . Bạn có thể cài đặt thủ công hoặc qua Cocoapods:

pod 'CommonCryptoModule', '~> 1.0.2'

Sau đó, tất cả những gì bạn phải làm là nhập mô-đun nơi bạn cần CommonCrypto, như vậy:

import CommonCryptoModule

Hy vọng người khác tìm thấy điều này hữu ích.


Cảnh báo: Ứng dụng của bạn sẽ bị từ chối nếu bạn sử dụng phương pháp này!
Segabond

Đúng, chúng tôi cũng bị từ chối, rất kỳ lạ, vì chúng tôi đã tải lên mà không gặp vấn đề gì trong vài tháng bằng phương pháp này.
Nikita Kukushkin

5

Tôi nghĩ rằng tôi đã có một sự cải tiến cho công việc tuyệt vời của Mike Weller.

Thêm một giai đoạn Run Script trước Compile Sourcesgiai đoạn chứa bash này:

# 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"

Kịch bản lệnh này xây dựng một khung xương trần với module.map ở đúng vị trí và sau đó dựa vào tìm kiếm tự động của Xcode BUILT_PRODUCTS_DIR cho các khung .

Tôi đã liên kết thư mục bao gồm CommonCrypto ban đầu dưới dạng thư mục Headers của khung để kết quả cũng hoạt động cho các dự án Objective C.


Xem câu trả lời của dvdblk để biết sự cải thiện bao gồm việc sử dụng trong Cốc Cốc.
jjrscott

5

Đối với bất cứ ai sử dụng swift 4.2 với Xcode 10 :

Mô-đun CommonCrypto hiện được cung cấp bởi hệ thống, vì vậy bạn có thể nhập trực tiếp nó như bất kỳ khung hệ thống nào khác.

import CommonCrypto

Bản sao câu trả lời của @ mxcl: stackoverflow.com/a/50690346/9988514
Rainer Schwarz

4

@mogstad đã đủ tử tế để bọc giải pháp @stephencelis trong Cocoapod:

nhóm 'libCommonCrypto'

Các nhóm khác có sẵn không làm việc cho tôi.


4

Các giải pháp modulemap có thể tốt và mạnh mẽ chống lại các thay đổi SDK, nhưng tôi thấy chúng khó sử dụng trong thực tế và không đáng tin cậy như tôi muốn khi giao mọi thứ cho người khác. Để cố gắng làm cho nó trở nên hoàn hảo hơn, tôi đã đi một cách khác:

Chỉ cần sao chép các tiêu đề.

Tôi biết, mong manh. Nhưng Apple gần như không bao giờ thực hiện các thay đổi đáng kể đối với CommonCrypto và tôi đang sống trong giấc mơ rằng họ sẽ không thay đổi nó theo bất kỳ cách quan trọng nào mà cuối cùng cũng biến CommonCrypto thành một tiêu đề mô-đun.

Bằng cách "sao chép các tiêu đề", ý tôi là "cắt và dán tất cả các tiêu đề bạn cần vào một tiêu đề lớn trong dự án của bạn giống như bộ tiền xử lý sẽ làm." Để làm ví dụ về điều này mà bạn có thể sao chép hoặc điều chỉnh, hãy xem RNCryptor.h .

Lưu ý rằng tất cả các tệp này được cấp phép theo APSL 2.0 và phương pháp này cố ý duy trì các thông báo bản quyền và giấy phép. Bước nối của tôi được cấp phép theo MIT và điều đó chỉ áp dụng cho thông báo giấy phép tiếp theo).

Tôi không nói rằng đây là một giải pháp đẹp, nhưng cho đến nay nó dường như là một giải pháp cực kỳ đơn giản để vừa thực hiện vừa hỗ trợ.


Tôi tìm thấy điều này để biên dịch đáng tin cậy và nó đơn giản. Ứng dụng sử dụng khung cần phải liên kết với bất kỳ điều gì đặc biệt hay CommonCrypto luôn khả dụng?
mã hóaFriend1

1
Tôi nghĩ rằng Security.frameworknó được liên kết tự động (sẽ mất một chút thời gian kể từ khi bắt đầu một dự án mới). Nếu bạn gặp lỗi, đó là khung để liên kết.
Rob Napier

Đây có vẻ là giải pháp đơn giản nhất và nó hoạt động tốt trên một máy, nhưng bất cứ khi nào tôi sử dụng khung trong khung hoặc ứng dụng khác, trên máy khác, tôi gặp lỗi 'thiếu mô-đun'.
giàu

2

Tôi biết đây là một câu hỏi cũ. Nhưng tôi tìm ra một cách khác để sử dụng thư viện trong dự án Swift, có thể hữu ích cho những người không muốn nhập khung được giới thiệu trong các câu trả lời này.

Trong dự án Swift, tạo tiêu đề bắc cầu Objective-C, tạo thể loại NSData (hoặc lớp tùy chỉnh sử dụng thư viện) trong Objective-C. Hạn chế duy nhất là bạn phải viết tất cả mã thực thi trong Objective-C. Ví dụ:

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

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

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

Và sau đó trong tiêu đề cầu nối mục tiêu-c của bạn, thêm điều này

#import "NSData+NSDataEncryptionExtension.h"

Và sau đó trong lớp Swift làm điều tương tự:

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
}
}

Nó hoạt động như mong đợi.


Điều này hoạt động rất trơn tru và thậm chí cho phép bạn giữ nội bộ bên trong ( NSData+NSDataEncryptionExtension.hkhông phải công khai).
Raphael

Nhưng tôi nên liên kết với khung hệ điều hành nào để sử dụng thứ này? Không giống như những người khác - Tôi phải làm việc với CommonCrypto trong một dự án Obj-C và điều đó một mình phá vỡ Xcode 9 với MacOS-10.13 SDK
Motti Shneor

@MottiShneor Liên kết bất kỳ HĐH nào từ 10.9 trở lên. Tôi đang làm việc trên cùng một môi trường và nó hoạt động tốt.
Terence

2

Tôi đã thêm một số phép thuật cocoapods vào câu trả lời của jjrscott trong trường hợp bạn cần sử dụng CommonCrypto trong thư viện cocoapods của mình.


1) Thêm dòng này vào podspec của bạn:

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

2) Lưu cái này trong thư mục thư viện của bạn hoặc bất cứ nơi nào bạn thích (tuy nhiên đừng quên thay đổi script_phase cho phù hợp ...)

# 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"

Hoạt động như một bùa mê :)


Bạn có thể cung cấp bản demo hoặc dự án khung mẫu cho cùng với tệp pod spec không?
Gowtham

0

Tôi không chắc có gì đó thay đổi với Xcode 9.2 hay không nhưng giờ đây việc này đạt được điều này đơn giản hơn nhiều. Điều duy nhất tôi phải làm là tạo một thư mục có tên "CommonCrypto" trong thư mục dự án khung của tôi và tạo hai tệp bên trong nó, một tệp có tên là "cc.h" như sau:

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

Và một cái khác được gọi là module.modulemap:

module CommonCrypto {
    export *
    header "cc.h"
}

(Tôi không biết tại sao bạn không thể tham chiếu các tệp tiêu đề từ khu vực SDKROOT trực tiếp trong tệp modulemap nhưng tôi không thể làm cho nó hoạt động được)

Điều thứ ba là tìm cài đặt "Nhập đường dẫn" và đặt thành $ (SRCROOT). Trong thực tế, bạn có thể đặt nó vào bất kỳ thư mục nào bạn muốn thư mục CommonCrypto ở dưới, nếu bạn không muốn nó ở cấp gốc.

Sau này, bạn sẽ có thể sử dụng

import CommonCrypto

Trong bất kỳ tập tin nhanh chóng và tất cả các loại / chức năng / vv. có sẵn.

Mặc dù vậy, một lời cảnh báo - nếu ứng dụng của bạn sử dụng libCommonCrypto (hoặc libcoreCrypto), một hacker không quá phức tạp sẽ gắn trình gỡ lỗi vào ứng dụng của bạn và tìm ra khóa nào được truyền cho các chức năng này.


0

Trong trường hợp bạn có vấn đề dưới đây:

ld: không tìm thấy thư viện cho -lapple_crypto clang: error: lệnh linker không thành công với mã thoát 1 (sử dụng -v để xem lời mời)

Trong Xcode 10, Swift 4.0. CommonCrypto là một phần của khung.

Thêm vào

 import CommonCrypto

Tẩy

  • Tệp lib CommonCrpto từ liên kết nhị phân với các thư viện từ các giai đoạn Xây dựng
  • import CommonCrypto từ tiêu đề Bridging

Điều này làm việc cho tôi!


-1

Nó cũng xảy ra với tôi sau khi cập nhật Xcode. Tôi đã thử mọi cách tôi có thể làm như cài đặt lại cocoapods và làm sạch dự án, nhưng nó không hoạt động. Bây giờ nó đã được giải quyết sau khi khởi động lại hệ thống.


-13

Nó rất đơn giản. Thêm vào

#import <CommonCrypto/CommonCrypto.h>

đến một tệp .h (tệp tiêu đề bắc cầu của dự án của bạn). Theo quy ước, bạn có thể gọi nó là YourProjectName-Bridging-Header.h.

Sau đó đi đến Cài đặt bản dựng dự án của bạn và tìm kiếm Trình biên dịch Swift - Tạo mã. Trong đó, thêm tên của tiêu đề bắc cầu của bạn vào mục "Tiêu đề cầu nối Objetive-C".

Bạn đã hoàn tất. Không yêu cầu nhập trong mã Swift của bạn. Bất kỳ tiêu đề Objective-C công khai nào được liệt kê trong tệp tiêu đề bắc cầu này sẽ hiển thị với Swift.


phương thức của bạn trả về lỗi: sử dụng các tiêu đề bắc cầu với các mục tiêu khung không được hỗ trợ
gorgi93

5
@ gorgi93 Bạn không thể sử dụng tiêu đề bắc cầu trong mục tiêu khung, như lỗi cho thấy. Thật không may, tùy chọn duy nhất là đặt nó trong tệp tiêu đề khung chính.
Charles A.

1
Nếu bạn thực sự đã đỏ tiêu đề của chủ đề này, bạn sẽ thấy rằng anh chàng đó muốn nhập thư viện CommonCrypto vào một khung Swift. Bạn không thể sử dụng các tiêu đề bắc cầu trong các khung và bạn không thể nhập khung CommonCrypto vào tiêu đề ô.
miken.mkndev 11/03/2016
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.