Импорт CommonCrypto в Swift

Как вы импортируете CommonCrypto в среду Swift для iOS?

Я понимаю, как использовать CommonCrypto в приложении Swift: вы добавляете #import <CommonCrypto/CommonCrypto.h> в заголовок моста.

Однако структуры Swift не поддерживают перемычки заголовков. В документации говорится:

Вы можете импортировать внешние фреймворки с чистой базой Objective-C, чистой кодовой базой Swift или кодовой базой на смешанном языке. Процесс импорта внешней структуры одинаковый, независимо от того, написана ли среда на одном языке или содержит файлы с обоих языков. Когда вы импортируете внешнюю инфраструктуру, убедитесь, что для параметра «Определить модуль» для импортируемой структуры установлено значение «Да».

Вы можете импортировать фреймворк в любой файл Swift в другой целевой среде, используя следующий синтаксис:

 import FrameworkName 

К сожалению, импорт CommonCrypto не работает. Также не добавляется #import <CommonCrypto/CommonCrypto.h> в заголовок зонтика.

8 Solutions collect form web for “Импорт CommonCrypto в Swift”

Фактически вы можете создать решение, которое «просто работает» (нет необходимости копировать параметры module.modulemap и SWIFT_INCLUDE_PATHS в ваш проект, как это требуется в других решениях здесь), но для этого требуется создать фиктивную структуру / модуль, который вы «Импорт в вашу структуру. Мы также можем обеспечить его работу независимо от платформы ( iphoneos , iphonesimulator или macosx ).

  1. Добавьте новую цель рамки в свой проект и назовите ее после системной библиотеки, например , «CommonCrypto». (Вы можете удалить заголовок зонтика, CommonCrypto.h .)

  2. Добавьте новый файл параметров конфигурации и назовите его, например , «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 
  3. Создайте три указанных выше файла карты модулей выше и заполните их следующим образом:

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

    (Замените «Xcode.app» на «Xcode-beta.app», если вы используете бета-версию. Замените 10.11 на ваш текущий SDK SD, если не используете El Capitan.)

  4. На вкладке « Информация » параметров вашего проекта в разделе « Конфигурации» установите конфигурации « Отладка и выпуск» CommonCrypto в CommonCrypto (ссылка на CommonCrypto.xcconfig ).

  5. На вкладке « Построить фазы » на вашей платформе добавьте среду CommonCrypto в Target Dependencies . Кроме того, добавьте libcommonCrypto.dylib в фазу компоновки ссылок с бинарными связями .

  6. Выберите CommonCrypto.framework в продуктах и убедитесь, что для его целевого членства для вашей обертки установлено значение Необязательный .

Теперь вы сможете создавать, запускать и import CommonCrypto в своей import CommonCrypto .

Например, посмотрите, как SQLite.swift использует фиктивный sqlite3.framework .

Я нашел проект GitHub, который успешно использует CommonCrypto в среде Swift: SHA256-Swift . Кроме того, эта статья о той же проблеме с sqlite3 была полезна.

Исходя из вышесказанного, этапы:

1) Создайте каталог CommonCrypto внутри каталога проекта. Внутри создайте файл module.map . Карта модуля позволит нам использовать библиотеку CommonCrypto в качестве модуля в Swift. Его содержание:

 module CommonCrypto [system] { header "/Applications/Xcode6-Beta5.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) Наконец, импортируйте CommonCrypto внутри ваших файлов Swift как любые другие модули. Например:

 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 Simulator). Я не знаю, как сделать путь заголовка относительно текущей платформы.

Обновления для iOS 8 <= Мы должны удалить строку «CommonCrypto» , чтобы получить успешную компиляцию.

редактировать

Я продолжал получать

ld: библиотека не найдена для -lCommonCrypto для архитектуры x86_64 clang: ошибка: команда компоновщика не удалась с кодом выхода 1 (используйте -v, чтобы увидеть вызов)

Если я не удалил link "CommonCrypto" . Как только я удалил эту строку, она построена нормально.

Что-то более простое и надежное заключается в создании целевой совокупности, называемой «CommonCryptoModuleMap», с этапом сценария запуска для автоматического создания карты модуля и с правильным ходом Xcode / SDK:

введите описание изображения здесь введите описание изображения здесь

Этап запуска сценария должен содержать этот bash:

 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 и т. Д. Вам также не нужно ничего сидеть в исходном каталоге вашего проекта.

Создав эту цель, сделайте свою библиотеку / фреймворк зависимой от нее с помощью элемента Target Dependencies:

введите описание изображения здесь

Это обеспечит создание карты модуля до создания вашей структуры.

Затем добавьте родительский каталог карты модуля, ${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap , в настройку сборки «Header Search Paths»:

введите описание изображения здесь

Не забудьте добавить $(inherited) строку, если у вас есть пути поиска, определенные на уровне проекта или xcconfig.

Вот и все, теперь вы должны иметь возможность import CommonCrypto

В этом ответе обсуждается, как заставить его работать внутри рамки, а также с Cocoapods и Carthage

🐟 Подход модуля

Я использую modulemap в своей обертке вокруг CommonCrypto https://github.com/onmyway133/arcane , https://github.com/onmyway133/Reindeer

Для тех, кто не получил header not found , посмотрите https://github.com/onmyway133/Arcane/issues/4

  • Создайте папку CCommonCrypto содержащую module.modulemap

      module CCommonCrypto { header "/usr/include/CommonCrypto/CommonCrypto.h" export * } 
  • Перейдите в «Встроенные параметры» -> «Импорт путей»

      ${SRCROOT}/Sources/CCommonCrypto 

🌳 Cocoapods с модульным подходом

🐘 подход с открытым заголовком

  • 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 с подходом общего заголовка

🐝 Интересные связанные должности

Модульные решения могут быть хорошими и надежными в отношении изменений SDK, но я нашел их неудобными для использования на практике, и не настолько надежными, как хотелось бы, когда передавали вещи другим. Чтобы попытаться сделать все более надежным, я пошел по-другому:

Просто скопируйте заголовки.

Я знаю, хрупкий. Но Apple почти никогда не вносит существенных изменений в CommonCrypto, и я живу мечтой, что они не изменят ее каким-либо существенным образом, не превратив CommonCrypto в модульный заголовок.

«Скопируйте заголовки», я имею в виду «вырезать и вставить все заголовки, которые вам нужны, в один массивный заголовок в вашем проекте, как это сделал бы препроцессор». В качестве примера этого можно скопировать или адаптироваться, см. RNCryptor.h .

Обратите внимание, что все эти файлы лицензированы в APSL 2.0, и этот подход намеренно поддерживает уведомления об авторских правах и лицензиях. Мой этап конкатенации лицензируется в рамках MIT и распространяется только на следующее уведомление о лицензии).

Я не говорю, что это прекрасное решение, но до сих пор это было невероятно простое решение как для реализации, так и для поддержки.

@mogstad был достаточно любезен, чтобы обернуть решение @stephencelis в Cocoapod:

pod 'libCommonCrypto'

Другие доступные мне стручки не работали для меня.

Я знаю, что это старый вопрос. Но я выясню альтернативный способ использования библиотеки в проекте Swift, что может быть полезно для тех, кто не хочет импортировать фреймворк, введенный в эти ответы.

В проекте Swift создайте заголовок моста Objective-C, создайте категорию NSData (или пользовательский класс, который будет использовать библиотеку) в Objective-C. Единственным недостатком будет то, что вы должны написать весь код реализации в 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 } 

А затем в своем заголовочном заголовке цели-c добавьте это

 #import "NSData+NSDataEncryptionExtension.h" 

И тогда в классе Свифт делайте похожие вещи:

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

Он работает так, как ожидалось.

Это очень просто. Добавить

 #import <CommonCrypto/CommonCrypto.h> 

в файл .h (заголовок заголовочного файла вашего проекта). В качестве конвенции вы можете назвать это YourProjectName-Bridging-Header.h.

Затем перейдите в свой проект Build Settings и найдите Swift Compiler – Code Generation. Под ним добавьте имя вашего заголовка моста к записи «Objetive-C Bridging Header».

Все готово. Импорт не требуется в вашем коде Swift. Любые общедоступные заголовки Objective-C, перечисленные в этом файле заголовка моста, будут видны для Swift.

  • Использование Facebook Messenger SDK в Swift
  • Как использовать идентификаторы ограничений в автозапуске и как сменить ограничение с помощью идентификаторов?
  • Передача основных данных из выбранной ячейки таблицы в новый контроллер представления
  • Facebook Framework уже добавлен в проект, но по-прежнему показывает такие ошибки, как «Нет такого модуля FBSDKCoreKit»
  • Не удается получить данные пикселей через CGDataProviderCopyData, используя AVCaptureVideoDataOutput в swift 2
  • UITableView - прокрутите вниз до viewDidAppear
  • В чем разница между переменной swift и функцией при использовании закрытия в переменной?
  • Как получить доступное имя Wi-Fi сети в iOS, используя быстрый
  • AVAudioEngine для NSData - wav-файл не воспроизводится на сервере
  • Удаленные записи CloudKit Reappear
  • Ошибка Xcode swift с кодом выхода 254
  • Interesting Posts

    Завершение приложения из-за неперехваченного исключения «NSRangeException», причина: «Не удается удалить наблюдателя – ios

    Есть ли хорошие инструменты для сбора показателей Objective-C?

    Ошибка AVAssetReader после того, как приложение помещено в фоновом режиме, почему?

    Изображение UIImageView на основе маски UIView

    NSPredicate нечувствительный к строковой строке поиск с CloudKit

    динамическая высота ячейки uitableview

    Пользовательский формат IOS Push Notification

    Изображения, отображаемые в разных размерах – Swift

    Как сделать простой EQ AudioUnit (бас, середина, тройной) с iOS?

    Игровая площадка Xcode застревает на «Running playground» или «Запуск симулятора» и не будет запускать код, что делать?

    Пользовательские иконки UITabBar iOS

    kCGImageAlphaNone неразрешенный идентификатор в быстром

    Как преобразовать NSDictionary в пользовательский объект

    В чем разница между выполнением NSURLRequest и ответом на делегатов, а не с помощью dispatch_async?

    Черное и белое наложение для MKMapView

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.