¿Cómo se importa CommonCrypto
en un marco Swift para iOS?
Entiendo cómo usar CommonCrypto
en una aplicación Swift: se agrega #import <CommonCrypto/CommonCrypto.h>
al encabezado de puente. Sin embargo, los marcos Swift no admiten encabezados de puente. La documentación dice:
Puede importar marcos externos que tengan una base de código pura de Objective-C, una base de código de Swift pura o una base de código de lenguaje mixto. El proceso para importar un marco externo es el mismo si el marco está escrito en un solo idioma o contiene archivos de ambos idiomas. Cuando importe un marco externo, asegúrese de que la configuración de compilación del módulo Defines para el marco que está importando esté establecida en Sí.
Puede importar un marco en cualquier archivo Swift dentro de un destino diferente utilizando la siguiente sintaxis:
import FrameworkName
Desafortunadamente, la importación CommonCrypto
no funciona. Tampoco agrega #import <CommonCrypto/CommonCrypto.h>
al encabezado paraguas.
fuente
Respuestas:
Algo un poco más simple y robusto es crear un objetivo agregado llamado "CommonCryptoModuleMap" con una fase Ejecutar script para generar el mapa del módulo automáticamente y con la ruta correcta de Xcode / SDK:
La fase Ejecutar script debe contener este bash:
Usar el código de shell y
${SDKROOT}
significa que no tiene que codificar la ruta Xcode.app que puede variar de un sistema a otro, especialmente si usaxcode-select
para cambiar a una versión beta, o está construyendo en un servidor CI donde se instalan múltiples versiones en ubicaciones no estándar. Tampoco necesita codificar el SDK, por lo que debería funcionar para iOS, macOS, etc. Tampoco necesita tener nada en el directorio de origen de su proyecto.Después de crear este objetivo, haga que su biblioteca / marco dependa de él con un elemento de Dependencias de destino:
Esto asegurará que el mapa del módulo se genere antes de construir su marco.
nota de macOS : si también es compatible
macOS
, deberá agregarmacosx
a laSupported Platforms
configuración de compilación en el nuevo destino agregado que acaba de crear, de lo contrario no colocará el mapa del módulo en laDebug
carpeta de datos derivados correcta con el resto del productos marco.A continuación, agregue el directorio principal del mapa del módulo
${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap
, a la configuración de compilación "Importar rutas" en la sección Swift (SWIFT_INCLUDE_PATHS
):Recuerde agregar una
$(inherited)
línea si tiene rutas de búsqueda definidas en el proyecto o en el nivel xcconfig.Eso es todo, ahora deberías poder
import CommonCrypto
Actualización para Xcode 10
Xcode 10 ahora viene con un mapa del módulo CommonCrypto que hace innecesaria esta solución alternativa. Si desea admitir Xcode 9 y 10, puede hacer una comprobación en la fase Ejecutar script para ver si el mapa del módulo existe o no, por ejemplo
fuente
En realidad, puede crear una solución que "simplemente funcione" (no es necesario copiar un módulo.modulemap y
SWIFT_INCLUDE_PATHS
configuraciones a su proyecto, como lo requieren otras soluciones aquí), pero sí requiere que cree un marco / módulo ficticio que usted ' Importaremos en su marco propiamente dicho. También podemos asegurar que funcione independientemente de la plataforma (iphoneos
,iphonesimulator
omacosx
).Agregue un nuevo objetivo de marco a su proyecto y asígnele el nombre de la biblioteca del sistema, por ejemplo , "CommonCrypto". (Puede eliminar el encabezado general, CommonCrypto.h .)
Agregue un nuevo archivo de ajustes de configuración y asígnele un nombre, por ejemplo , "CommonCrypto.xcconfig". (No marque ninguno de sus objetivos para su inclusión). Rellene con lo siguiente:
Cree los tres archivos de mapa del módulo referenciados, arriba, y complételos con lo siguiente:
iphoneos.modulemap
iphonesimulator.modulemap
macosx.modulemap
(Reemplace "Xcode.app" con "Xcode-beta.app" si está ejecutando una versión beta. Reemplácelo
10.11
con su SDK de sistema operativo actual si no está ejecutando El Capitan).En la pestaña Información de la configuración de su proyecto, en Configuraciones , configure las configuraciones Debug and Release de CommonCrypto en CommonCrypto ( haciendo referencia a CommonCrypto.xcconfig ).
En la pestaña Fases de compilación del objetivo del marco , agregue el marco CommonCrypto a las dependencias de destino . Además, agregue libcommonCrypto.dylib a la fase de compilación Enlace binario con bibliotecas .
Seleccione CommonCrypto.framework en Productos y asegúrese de que la Membresía de destino para su contenedor esté configurada como Opcional .
Ahora debería poder compilar, ejecutar y
import CommonCrypto
en su marco de envoltura.Para ver un ejemplo, vea cómo SQLite.swift usa un sqlite3.framework ficticio .
fuente
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
System.framework
. Vale la pena señalar, debe hacer un marco de envoltorio separado para Mac e iOS si su marco es multiplataforma.Encontré un proyecto de GitHub que utiliza con éxito CommonCrypto en un marco Swift: SHA256-Swift . Además, este artículo sobre el mismo problema con sqlite3 fue útil.
En base a lo anterior, los pasos son:
1) Cree un
CommonCrypto
directorio dentro del directorio del proyecto. Dentro, crea unmodule.map
archivo. El mapa del módulo nos permitirá usar la biblioteca CommonCrypto como módulo dentro de Swift. Sus contenidos son:2) En Configuración de compilación, dentro del compilador Swift - Buscar rutas , agregue el
CommonCrypto
directorio a Importar rutas (SWIFT_INCLUDE_PATHS
).3) Finalmente, importe CommonCrypto dentro de sus archivos Swift como cualquier otro módulo. Por ejemplo:
Limitaciones
El uso del marco personalizado en otro proyecto falla en el momento de la compilación con el error
missing required module 'CommonCrypto'
. Esto se debe a que el módulo CommonCrypto no parece estar incluido con el marco personalizado. Una solución alternativa es repetir el paso 2 (configuraciónImport Paths
) en el proyecto que usa el marco.El mapa del módulo no es independiente de la plataforma (actualmente apunta a una plataforma específica, el simulador de iOS 8). No sé cómo hacer la ruta del encabezado en relación con la plataforma actual.
Actualizaciones para iOS 8 <= Debemos eliminar el enlace de línea "CommonCrypto" , para obtener una compilación exitosa.
ACTUALIZAR / EDITAR
Seguí recibiendo el siguiente error de compilación:
A menos que elimine la línea
link "CommonCrypto"
delmodule.map
archivo que creé. Una vez que eliminé esta línea, se construyó bien.fuente
$SDKROOT
que se supone que la variable le permite caminos agnósticos de plataforma, pero no tengo idea de cómo llegar a eso en Swift.link "CommonCrypto"
eliminé el archivo module.map.Esta respuesta discute cómo hacer que funcione dentro de un marco, y con Cocoapods y Carthage
Approach enfoque de mapa de módulo
Lo uso
modulemap
en mi contenedor alrededor de CommonCrypto https://github.com/onmyway133/arcane , https://github.com/onmyway133/ReindeerPara aquellos que están obteniendo
header not found
, eche un vistazo https://github.com/onmyway133/Arcane/issues/4 o ejecutexcode-select --install
Hacer una carpeta que
CCommonCrypto
contengamodule.modulemap
Vaya a Configuración integrada -> Importar rutas
🌳 Cocoapods con enfoque de mapa de módulo
Aquí está el podspec https://github.com/onmyway133/Arcane/blob/master/Arcane.podspec
El uso
module_map
no funciona, consulte https://github.com/CocoaPods/CocoaPods/issues/5271El uso de Local Development Pod con
path
no funciona, consulte https://github.com/CocoaPods/CocoaPods/issues/809Es por eso que ves que mi ejemplo Podfile https://github.com/onmyway133/CommonCrypto.swift/blob/master/Example/CommonCryptoSwiftDemo/Podfile apunta al repositorio git
Approach enfoque de encabezado público
Ji es un contenedor alrededor de libxml2, y utiliza un enfoque de encabezado público
Tiene un archivo de encabezado https://github.com/honghaoz/Ji/blob/master/Source/Ji.h con
Target Membership
set toPublic
Tiene una lista de archivos de encabezado para libxml2 https://github.com/honghaoz/Ji/tree/master/Source/Ji-libxml
Tiene Configuración de compilación -> Rutas de búsqueda de encabezado
Tiene Configuración de compilación -> Otras banderas de enlazador
🐏 Cocoapods con enfoque de encabezado público
Echa un vistazo al podspec https://github.com/honghaoz/Ji/blob/master/Ji.podspec
🐝 Publicaciones relacionadas interesantes
fuente
/CommonCrypto/CommonCrypto.h
dentroApplications/XCode.app/Contents/Developer/Platforms/iPhoneOS....
, lo que requería una modificación manual para las personas que cambiaron el nombre de XCode. Cambiar esa línea para mirar"/usr/include/CommonCrypto/CommonCrypto.h"
parece funcionar bien para un equipo con varias versiones de XCode. Muchas gracias!pod lib lint
, pero la compilación falló con un error: no existe tal módulo 'CommonCrypto'. ¿Cómo puedo lidiar con eso?$(PODS_ROOT)/CommonCryptoSwift/Sources/CCommonCrypto
con$(PODS_TARGET_SRCROOT)/Sources/CCommonCrypto
.PODS_TARGET_SRCROOT
está configurado correctamente para los pods locales.¡Buenas noticias! ¡Swift 4.2 (Xcode 10) finalmente proporciona CommonCrypto!
Simplemente agregue
import CommonCrypto
su archivo rápido.fuente
CommonCrypto
módulos, por lo que sospechaba que Apple ahora proporcionaba que eliminé mi solución y 'lo! Eso era cierto. Tuiteé al respecto y un ingeniero de Apple respondió confirmando que estaba destinado.ADVERTENCIA: iTunesConnect puede rechazar aplicaciones que utilizan este método.
El nuevo miembro de mi equipo accidentalmente rompió la solución dada por una de las principales respuestas, por lo que decidí consolidarla en un pequeño proyecto de envoltura llamado CommonCryptoModule . Puede instalarlo manualmente o mediante Cocoapods:
Luego, todo lo que tiene que hacer es importar el módulo donde lo necesite
CommonCrypto
, así:Espero que alguien más encuentre esto útil.
fuente
Creo que tengo una mejora en el excelente trabajo de Mike Weller.
Agregue una fase Run Script antes de la
Compile Sources
fase que contiene este bash:Este script construye un marco básico con el module.map en el lugar correcto y luego se basa en la búsqueda automática de
BUILT_PRODUCTS_DIR
marcos de Xcode .Vinculaba la carpeta de inclusión CommonCrypto original como la carpeta de encabezados del marco, por lo que el resultado también debería funcionar para proyectos de Objective C.
fuente
Para cualquiera que use swift 4.2 con Xcode 10 :
El sistema proporciona ahora el módulo CommonCrypto, por lo que puede importarlo directamente como cualquier otro marco del sistema.
fuente
@mogstad ha tenido la amabilidad de envolver la solución @stephencelis en un Cocoapod:
pod 'libCommonCrypto'
Las otras cápsulas disponibles no me funcionaron.
fuente
Las soluciones de mapa de módulo pueden ser buenas y son robustas frente a los cambios del SDK, pero las encontré incómodas de usar en la práctica y no tan confiables como me gustaría al entregar cosas a otros. Para tratar de hacerlo todo más infalible, tomé un camino diferente:
Solo copia los encabezados.
Lo sé, frágil. Pero Apple casi nunca hace cambios significativos en CommonCrypto y estoy viviendo el sueño de que no lo cambiarán de manera significativa sin finalmente hacer de CommonCrypto un encabezado modular.
Por "copiar los encabezados" quiero decir "cortar y pegar todos los encabezados que necesita en un encabezado masivo en su proyecto al igual que lo haría el preprocesador". Como ejemplo de esto que puede copiar o adaptar, vea RNCryptor.h .
Tenga en cuenta que todos estos archivos tienen licencia bajo APSL 2.0, y este enfoque mantiene intencionalmente los avisos de derechos de autor y licencia. Mi paso de concatenación tiene licencia bajo MIT, y eso solo se aplica hasta el próximo aviso de licencia).
No digo que esta sea una solución hermosa, pero hasta ahora parece haber sido una solución increíblemente simple tanto para implementar como para soporte.
fuente
Security.framework
se vincula automáticamente (ha pasado un tiempo desde que comencé un nuevo proyecto). Si obtiene errores, ese es el marco para vincular.Sé que esta es una vieja pregunta. Pero descubro una forma alternativa de usar la biblioteca en el proyecto Swift, que podría ser útil para aquellos que no desean importar el marco presentado en estas respuestas.
En el proyecto Swift, cree un encabezado de puente Objective-C, cree una categoría NSData (o una clase personalizada que use la biblioteca) en Objective-C. El único inconveniente sería que tiene que escribir todo el código de implementación en Objective-C. Por ejemplo:
Y luego, en su encabezado de puente de Objective-C, agregue esto
Y luego, en la clase Swift, haz algo similar:
Funciona como se esperaba.
fuente
NSData+NSDataEncryptionExtension.h
no tiene que ser público).He agregado algo de magia de cocoapods a la respuesta de jjrscott en caso de que necesite usar CommonCrypto en su biblioteca de cocoapods.
1) Agregue esta línea a su podspec:
2) Guarde esto en la carpeta de su biblioteca o donde quiera (sin embargo, no olvide cambiar el script_phase en consecuencia ...)
Funciona de maravilla :)
fuente
No estoy seguro de si algo ha cambiado con Xcode 9.2, pero ahora es mucho más simple lograrlo. Lo único que tuve que hacer es crear una carpeta llamada "CommonCrypto" en mi directorio de proyecto de marco y crear dos archivos dentro de él, uno llamado "cc.h" de la siguiente manera:
Y otro llamado module.modulemap:
(No sé por qué no puede hacer referencia a archivos de encabezado del área SDKROOT directamente en un archivo de mapa de módulo, pero no pude hacer que funcione)
Lo tercero es encontrar la configuración "Importar rutas" y establecerla en $ (SRCROOT). De hecho, puede configurarlo en cualquier carpeta en la que desee que esté la carpeta CommonCrypto, si no lo desea en el nivel raíz.
Después de esto deberías poder usar
En cualquier archivo rápido y todos los tipos / funciones / etc. están disponibles.
Sin embargo, una advertencia: si su aplicación usa libCommonCrypto (o libcoreCrypto) es excepcionalmente fácil para un hacker no demasiado sofisticado adjuntar un depurador a su aplicación y descubrir qué claves se pasan a estas funciones.
fuente
En caso de que tenga el siguiente problema:
En Xcode 10, Swift 4.0. CommonCrypto es parte del marco.
Añadir
Eliminar
import CommonCrypto
desde el encabezado de puente¡Esto funcionó para mí!
fuente
Me pasó lo mismo después de actualizar Xcode. Intenté todo lo que puedo hacer, como reinstalar cocoapods y limpiar el proyecto, pero no funcionó. Ahora se ha resuelto después de reiniciar el sistema.
fuente
Es muy simple. Añadir
a un archivo .h (el archivo de encabezado de puente de su proyecto). Como convención, puede llamarlo YourProjectName-Bridging-Header.h.
Luego vaya a la configuración de compilación de su proyecto y busque Swift Compiler - Generación de código. Debajo de él, agregue el nombre de su encabezado de puente a la entrada "Encabezado de puente de Objetivo-C".
Ya terminaste No se requieren importaciones en su código Swift. Swift podrá ver los encabezados públicos de Objective-C que figuran en este archivo de encabezado de puente.
fuente