Импорт CommonCrypto в Swift framework

185

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

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

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

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

import FrameworkName

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

hpique
источник
CommonCrypto - это платформа на основе C, а не платформа Objective-C.
rmaddy
2
@rmaddy Objective-C - это надмножество C. Вы хотите сказать, что мы не можем использовать CommonCrypto из Swift?
hpique
4
@rmaddy Мне только что удалось заставить CommonCrypto работать с помощью карт модулей. Я доработаю решение и выложу его позже сегодня.
hpique
если вам это удобно, и то, что вы ищете, уже реализовано, вы можете попробовать CryptoSwift
Марцин
1
Apple только что открыла исходный код CommonCrypto. Возможно, мы сможем запустить его, если у нас будут источники.
eyeballz

Ответы:

137

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

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

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

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

Примечание для macOS : если вы также поддерживаете macOS, вам нужно будет добавить macosxв Supported Platformsнастройку сборки новую совокупную цель, которую вы только что создали, иначе карта модуля не будет помещена в правильную Debugпапку производных данных с остальной частью каркасные изделия.

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

Затем добавьте родительский каталог карты модуля в ${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMapпараметр сборки «Import Paths» в разделе Swift ( SWIFT_INCLUDE_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
Майк Веллер
источник
8
Этот ответ должен быть на высоте. Просто и элегантно
Абдулла Саид
1
Поздно к игре на этом - но это должен быть выбранный ответ. Это просто, и другим разработчикам, работающим над тем же проектом, легче увидеть требования.
fatuous.logic 07
1
Отличный ответ. Благодарность!
Клаус Буссе
1
Если я сделаю это в моем .framework, должен ли я сделать то же самое в проектах, в которые я включаю этот фреймворк?
Рави Киран
2
@IanDundas Я обновил код выше, добавив исправление для проблемы повторной компиляции, а также исправление для использования этого в macOS
iwasrobbed
92

На самом деле вы можете создать решение, которое «просто работает» (нет необходимости копировать 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 ОС, если не работает El Capitan.)

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

  5. На вкладке Build Phases целевой платформы добавьте платформу CommonCrypto в Target Dependencies . Дополнительно добавьте libcommonCrypto.dylib на этап сборки Link Binary With Libraries .

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

Теперь у вас должна быть возможность создавать, запускать и использовать import CommonCryptoсвою оболочку.

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

Stephencelis
источник
4
У меня работает без шага (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
stannie
4
Превосходно! Использовал это для создания github.com/soffes/Crypto,System.framework хотя мне не нужно было связывать . Стоит отметить, что вам необходимо создать отдельный фреймворк для Mac и iOS, если ваш фреймворк кроссплатформенный.
Сэм Соффес
32
Как и где люди находят подобное?
hola
5
Просто примечание проясните, что вам нужно выбрать Objective-C в качестве языка на шаге 1. Это легко упустить из виду. Также, возможно, из-за того, что у меня не было .dylib, мне нужно было добавить .framework на шаге 5.
Тео Сартори,
7
это ужасно. У меня есть зоопарк Xcodes, каждый из которых сломан по-разному, и наличие абсолютных путей к заголовкам повсюду вызывает рвоту. Что-то ужасно не так в купертино, или, по крайней мере, с тем, кто отвечает за этот беспорядок с модульными картами
Антон Тропашко
82

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

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

ОБНОВЛЕНИЕ / РЕДАКТИРОВАНИЕ

Я продолжал получать следующую ошибку сборки:

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

Если только я не удалил строку link "CommonCrypto"из module.mapсозданного мной файла. Как только я удалил эту строку, все заработало нормально.

hpique
источник
30
Ну и дела, Apple наверняка хочет все усложнить. Убьет ли Swifties просто позволить нам импортировать файлы / фреймворки без необходимости проходить через всю эту ерунду?
zaph 05
4
Это бесит, поскольку $SDKROOTпеременная должна позволять вам использовать независимые от платформы пути, но я понятия не имею, как добраться до этого в Swift.
danimal 02
2
Для меня это не сработало, пока я не удалил link "CommonCrypto"из файла module.map.
Тео Сартори
1
Может ли кто-нибудь подтвердить, что это работает на Xcode 7.3? Это решение перестало работать у меня после обновления.
Никита Кукушкин
1
Исправление: он работает нормально, когда я собираю для симулятора, но не удается @ линковать, когда я собираю для устройства iOS 9.3 с «ld: library not found for -lCommonCrypto for architecture arm64»
Никита Кукушкин
52

В этом ответе обсуждается, как заставить его работать внутри фреймворка, а также с 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 с подходом модульной карты

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

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

🐝 Интересные посты по теме

onmyway133
источник
1
Вот это да! К моему удивлению, путь заголовка из верхнего подхода (создание файла module.modulemap) отлично работал, когда ранее файлы modulemap вызывали множество проблем. Я боролся с этим на некоторое время , используя файл module.modulemap абсолютный путь к в /CommonCrypto/CommonCrypto.hпределах Applications/XCode.app/Contents/Developer/Platforms/iPhoneOS...., которые требуют ручной модификации для людей , которые переименовали XCode. Переключение этой строки для просмотра, "/usr/include/CommonCrypto/CommonCrypto.h"похоже, отлично работает для команды с несколькими версиями XCode. Спасибо огромное!
Наталья
3
Я создаю модуль, устанавливаю SWIFT_INCLUDE_PATHS и preserve_paths. Когда я запускаю pod lib lint, но сборка завершилась ошибкой: нет такого модуля CommonCrypto. Как я могу с этим справиться.
Klein Mioke
1
Не имеет отношения к проблеме, но я люблю использовать смайлики в качестве маркеров! 😊
Fomentia 06
2
@ onmyway133 Использование локального модуля разработки работает, если вы замените его $(PODS_ROOT)/CommonCryptoSwift/Sources/CCommonCryptoна $(PODS_TARGET_SRCROOT)/Sources/CCommonCrypto. PODS_TARGET_SRCROOTустановлен правильно для локальных модулей.
Орхан Алиханов
Отличный ответ, спас мне жизнь! Спасибо миллион
Хасан Шахбази
46

Хорошие новости! Swift 4.2 (Xcode 10) наконец-то предоставляет CommonCrypto!

Просто добавьте import CommonCryptoв свой быстрый файл.

mxcl
источник
Отличные новости! Можете добавить ссылку на документацию?
Kryštof Matěj
У меня нет ссылки на документацию, я обнаружил это при попытке скомпилировать проект, в котором у меня был один из обходных путей здесь с Xcode 10. Он пожаловался, что может найти два CommonCryptoмодуля, таким образом подозревая Apple, теперь, если я удалил свой обходной путь и вот! Это правда. Я написал об этом в Твиттере, и инженер Apple ответил, что это было задумано.
mxcl
1
Магазин приложений показывает мне только 9.4.7 как доступное обновление, как вы получили Xcode 10?
Хаммад Тарик
1
Он находится в стадии бета-тестирования, как вам сказал бы простой поиск в Google.
mxcl
1
@SomoyDasGupta да. Просто удалите предыдущий импорт и скомпилируйте его снова. Другими словами, вам не нужно выполнять шаги из ответа Майка Веллера.
COLD ICE
7

ВНИМАНИЕ: iTunesConnect может отклонять приложения, использующие этот метод.


Новый член моей команды случайно сломал решение, данное одним из лучших ответов, поэтому я решил объединить его в небольшом проекте- оболочке под названием CommonCryptoModule . Вы можете установить его вручную или через Cocoapods:

pod 'CommonCryptoModule', '~> 1.0.2'

Затем все, что вам нужно сделать, это импортировать нужный модуль CommonCrypto, например:

import CommonCryptoModule

Надеюсь, кому-то это пригодится.

Никита Кукушкин
источник
Предупреждение: ваша заявка будет отклонена, если вы воспользуетесь этим методом!
Segabond
Да, нам тоже отказали, очень странно, потому что мы несколько месяцев загружали без проблем, используя этот метод.
Никита Кукушкин
5

Я думаю, что у меня есть улучшение по сравнению с превосходной работой Майка Веллера.

Добавьте фазу выполнения сценария перед 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 с папкой заголовков фреймворка, поэтому результат также должен работать для проектов Objective C.

Jjrscott
источник
См . Ответ dvdblk для улучшения, касающегося использования в CocoaPods.
jjrscott
5

Для тех, кто использует swift 4.2 с Xcode 10 :

Модуль CommonCrypto теперь предоставляется системой, поэтому вы можете напрямую импортировать его, как и любую другую системную структуру.

import CommonCrypto

Кубрик Г
источник
1
Дубликат ответа @mxcl: stackoverflow.com/a/50690346/9988514
Райнер Шварц
4

@mogstad любезно обернул раствор @stephencelis в Cocoapod:

под "libCommonCrypto"

Другие доступные модули мне не подошли.

Джейкоб Дженнингс
источник
4

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

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

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

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

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

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

Роб Напье
источник
Я обнаружил, что это надежно компилируется, и это очень просто. Нужно ли приложению, использующему фреймворк, ссылаться на что-нибудь особенное, или CommonCrypto всегда доступен?
codingFriend1
1
Я думаю, что Security.frameworkавтоматически связывается (прошло немного времени с тех пор, как я начал новый проект). Если вы получаете ошибки, это фреймворк для ссылки.
Роб Напье
Это действительно кажется самым простым решением, и оно отлично работает на одной машине, но всякий раз, когда я использую фреймворк в другом фреймворке или приложении, на другом компьютере я получаю ошибку «отсутствует модуль».
richever
2

Я знаю, что это старый вопрос. Но я выясняю альтернативный способ использования библиотеки в проекте 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
}

А затем в заголовке моста 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не обязательно публично).
Рафаэль
Но с какой платформой ОС я должен ссылаться, чтобы использовать эту штуку? В отличие от других - мне приходится работать с CommonCrypto в проекте Obj-C, и только это ломается в Xcode 9 с MacOS-10.13 SDK
Мотти Шнеор 08
@MottiShneor Свяжите любую ОС от 10.9 или выше. Я работаю в той же среде, и она отлично работает.
Теренс
2

Я добавил немного магии cocoapods в ответ jjrscott на случай, если вам нужно использовать CommonCrypto в своей библиотеке cocoapods.


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"

Работает как шарм :)

dvdblk
источник
Можете ли вы предоставить демонстрационный или образец фреймворка для него вместе со спецификационным файлом модуля?
Gowtham
@dvdblk В моем случае у меня есть собственный модуль, который использует модуль стороннего производителя, который использует CommonCrypto. Следует ли мне исправить свой модуль или его следует исправить в этом модуле стороннего производителя?
Вячеслав Герчиков
0

Я не уверен, что в Xcode 9.2 что-то изменилось, но теперь добиться этого стало намного проще. Единственное, что мне нужно было сделать, это создать папку с именем «CommonCrypto» в каталоге моего фреймворка и создать в ней два файла, один из которых называется «cc.h», как показано ниже:

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

И еще один под названием module.modulemap:

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

(Я не знаю, почему вы не можете ссылаться на файлы заголовков из области SDKROOT непосредственно в файле modulemap, но мне не удалось заставить его работать)

В-третьих, найдите параметр «Импорт путей» и установите значение $ (SRCROOT). Фактически, вы можете установить его в любую папку, в которой должна находиться папка CommonCrypto, если вы не хотите, чтобы она находилась на корневом уровне.

После этого вы сможете использовать

import CommonCrypto

В любом swift файле и во всех типах / функциях / и т.д. доступны.

Небольшое предупреждение: если ваше приложение использует libCommonCrypto (или libcoreCrypto), не слишком опытному хакеру будет очень легко присоединить отладчик к вашему приложению и узнать, какие ключи передаются этим функциям.

Дилан Николсон
источник
0

Если у вас возникла следующая проблема:

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

В Xcode 10 Swift 4.0. CommonCrypto является частью фреймворка.

Добавить

 import CommonCrypto

удалять

  • Файл библиотеки CommonCrpto из двоичного файла компоновки с библиотеками из этапов сборки
  • import CommonCrypto из заголовка моста

Это сработало для меня!

СКСН
источник
-1

То же произошло и со мной после обновления Xcode. Я пробовал все, что мог, например, переустанавливать cocoapods и очищать проект, но это не сработало. Теперь это решено после перезагрузки системы.

Джоуи
источник
-13

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

#import <CommonCrypto/CommonCrypto.h>

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

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

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

Хуанхо Конти
источник
ваш метод возвращает ошибку: использование заголовков моста с целями фреймворка не поддерживается
gorgi93
5
@ gorgi93 Вы не можете использовать заголовок моста в целевой платформе, как подсказывает ошибка. К сожалению, единственный вариант - поместить его в заголовочный файл основного фреймворка.
Чарльз А.
1
Если бы вы на самом деле красили заголовок этой ветки, вы бы увидели, что этот парень хочет импортировать библиотеку CommonCrypto в структуру Swift. Вы не можете использовать мостовые заголовки в фреймворках, и вы не можете импортировать фреймворк CommonCrypto в зонтичный заголовок.
miken.mkndev