Comment importer CommonCrypto
dans un framework Swift pour iOS?
Je comprends comment utiliser CommonCrypto
dans une application Swift: vous ajoutez #import <CommonCrypto/CommonCrypto.h>
à l'en-tête de pontage. Cependant, les frameworks Swift ne prennent pas en charge les en-têtes de pontage. La documentation dit:
Vous pouvez importer des frameworks externes qui ont une base de code Objective-C pure, une base de code Swift pure ou une base de code en langage mixte. Le processus d'importation d'un framework externe est le même que le framework soit écrit dans une seule langue ou contienne des fichiers des deux langues. Lorsque vous importez une infrastructure externe, assurez-vous que le paramètre de construction Définit le module pour l'infrastructure que vous importez est défini sur Oui.
Vous pouvez importer un framework dans n'importe quel fichier Swift au sein d'une cible différente en utilisant la syntaxe suivante:
import FrameworkName
Malheureusement, l'importation CommonCrypto
ne fonctionne pas. Ni l'ajout #import <CommonCrypto/CommonCrypto.h>
à l'en-tête du parapluie.
la source
Réponses:
Quelque chose d'un peu plus simple et plus robuste consiste à créer une cible d'agrégation appelée "CommonCryptoModuleMap" avec une phase d'exécution de script pour générer automatiquement la carte du module et avec le chemin Xcode / SDK correct:
La phase d'exécution du script doit contenir cette bash:
L'utilisation du code shell et
${SDKROOT}
signifie que vous n'avez pas à coder en dur le chemin Xcode.app qui peut varier d'un système à l'autre, en particulier si vous utilisezxcode-select
pour passer à une version bêta, ou si vous construisez sur un serveur CI où plusieurs versions sont installées dans des endroits non standard. Vous n'avez pas non plus besoin de coder en dur le SDK, cela devrait donc fonctionner pour iOS, macOS, etc. Vous n'avez pas non plus besoin d'avoir quoi que ce soit dans le répertoire source de votre projet.Après avoir créé cette cible, faites en sorte que votre bibliothèque / structure en dépende avec un élément Target Dependencies:
Cela garantira que la carte du module est générée avant la création de votre framework.
Remarque macOS : si vous prenez également en charge
macOS
, vous devrez ajoutermacosx
auSupported Platforms
paramètre de construction sur la nouvelle cible d'agrégation que vous venez de créer, sinon il ne placera pas la carte de module dans le bonDebug
dossier de données dérivées avec le reste du produits de cadre.Ensuite, ajoutez le répertoire parent de la mappe de module,, au
${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap
paramètre de construction "Import Paths" sous la section Swift (SWIFT_INCLUDE_PATHS
):N'oubliez pas d'ajouter une
$(inherited)
ligne si vous avez des chemins de recherche définis au niveau du projet ou de xcconfig.Ça y est, vous devriez maintenant pouvoir
import CommonCrypto
Mise à jour pour Xcode 10
Xcode 10 est maintenant livré avec une carte de module CommonCrypto rendant cette solution de contournement inutile. Si vous souhaitez prendre en charge à la fois Xcode 9 et 10, vous pouvez effectuer une vérification dans la phase Exécuter le script pour voir si la carte du module existe ou non, par exemple
la source
Vous pouvez en fait créer une solution qui "fonctionne juste" (pas besoin de copier un module.modulemap et des
SWIFT_INCLUDE_PATHS
paramètres dans votre projet, comme requis par d'autres solutions ici), mais cela vous oblige à créer un framework / module factice que vous ' ll importer dans votre cadre proprement dit. Nous pouvons également assurer qu'il fonctionne quelle que soit la plate - forme (iphoneos
,iphonesimulator
oumacosx
).Ajoutez une nouvelle cible de framework à votre projet et nommez-la après la bibliothèque système, par exemple , "CommonCrypto". (Vous pouvez supprimer l'en-tête parapluie, CommonCrypto.h .)
Ajoutez un nouveau fichier de paramètres de configuration et nommez-le, par exemple "CommonCrypto.xcconfig". (Ne cochez aucune de vos cibles pour l'inclusion.) Remplissez-le avec les éléments suivants:
Créez les trois fichiers de mappage de modules référencés ci-dessus et remplissez-les avec les éléments suivants:
iphoneos.modulemap
iphonesimulator.modulemap
macosx.modulemap
(Remplacez "Xcode.app" par "Xcode-beta.app" si vous exécutez une version bêta. Remplacez
10.11
par votre SDK OS actuel si vous n'exécutez pas El Capitan.)Dans l' onglet Info des paramètres de votre projet, sous Configurations , définissez les configurations de débogage et de publication de CommonCrypto sur CommonCrypto (faisant référence à CommonCrypto.xcconfig ).
Dans l' onglet Phases de construction de votre cible de framework , ajoutez le framework CommonCrypto aux dépendances cibles . Ajoutez également libcommonCrypto.dylib à la phase de création de lien binaire avec bibliothèques .
Sélectionnez CommonCrypto.framework dans Produits et assurez-vous que son adhésion cible pour votre wrapper est définie sur Facultatif .
Vous devriez maintenant pouvoir construire, exécuter et
import CommonCrypto
dans votre framework wrapper.Pour un exemple, voyez comment SQLite.swift utilise un factice sqlite3.framework .
la source
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
cependant. Il est à noter que vous devez créer un framework de wrapper séparé pour Mac et iOS si votre framework est multiplateforme.J'ai trouvé un projet GitHub qui utilise avec succès CommonCrypto dans un framework Swift: SHA256-Swift . En outre, cet article sur le même problème avec sqlite3 était utile.
Sur la base de ce qui précède, les étapes sont les suivantes:
1) Créez un
CommonCrypto
répertoire dans le répertoire du projet. À l'intérieur, créez unmodule.map
fichier. La carte des modules nous permettra d'utiliser la bibliothèque CommonCrypto en tant que module dans Swift. Son contenu est:2) Dans Paramètres de construction, dans Swift Compiler - Search Paths , ajoutez le
CommonCrypto
répertoire à Import Paths (SWIFT_INCLUDE_PATHS
).3) Enfin, importez CommonCrypto dans vos fichiers Swift comme tout autre module. Par exemple:
Limites
L'utilisation du framework personnalisé dans un autre projet échoue au moment de la compilation avec l'erreur
missing required module 'CommonCrypto'
. Cela est dû au fait que le module CommonCrypto ne semble pas être inclus dans le cadre personnalisé. Une solution de contournement consiste à répéter l'étape 2 (paramètreImport Paths
) dans le projet qui utilise l'infrastructure.La carte du module n'est pas indépendante de la plate-forme (elle pointe actuellement vers une plate-forme spécifique, le simulateur iOS 8). Je ne sais pas comment rendre le chemin de l'en-tête par rapport à la plate-forme actuelle.
Mises à jour pour iOS 8 <= Nous devrions supprimer le lien de ligne "CommonCrypto" , pour obtenir la compilation réussie.
METTRE À JOUR / MODIFIER
J'ai continué à recevoir l'erreur de construction suivante:
Sauf si j'ai supprimé la ligne
link "CommonCrypto"
dumodule.map
fichier que j'ai créé. Une fois que j'ai supprimé cette ligne, elle s'est bien construite.la source
$SDKROOT
variable est censée vous permettre des chemins indépendants de la plate-forme, mais je ne sais pas comment y arriver dans Swift.link "CommonCrypto"
fichier module.map.Cette réponse explique comment le faire fonctionner dans un cadre, et avec Cocoapods et Carthage
🐟 approche modulemap
J'utilise
modulemap
dans mon wrapper autour de CommonCrypto https://github.com/onmyway133/arcane , https://github.com/onmyway133/ReindeerPour ceux qui obtiennent
header not found
, veuillez jeter un coup d'œil sur https://github.com/onmyway133/Arcane/issues/4 ou exécutezxcode-select --install
Créer un dossier
CCommonCrypto
contenantmodule.modulemap
Allez dans Paramètres construits -> Chemins d'importation
🌳 Cocoapods avec approche modulemap
Voici le podspec https://github.com/onmyway133/Arcane/blob/master/Arcane.podspec
L'utilisation
module_map
ne fonctionne pas, voir https://github.com/CocoaPods/CocoaPods/issues/5271L'utilisation du module de développement local avec
path
ne fonctionne pas, voir https://github.com/CocoaPods/CocoaPods/issues/809C'est pourquoi vous voyez que mon exemple de podfile https://github.com/onmyway133/CommonCrypto.swift/blob/master/Example/CommonCryptoSwiftDemo/Podfile pointe vers le dépôt git
🐘 approche d'en-tête publique
Ji est un wrapper autour de libxml2, et il utilise une approche d'en-tête public
Il a un fichier d'en-tête https://github.com/honghaoz/Ji/blob/master/Source/Ji.h avec
Target Membership
la valeurPublic
Il a une liste de fichiers d'en-tête pour libxml2 https://github.com/honghaoz/Ji/tree/master/Source/Ji-libxml
Il a des paramètres de construction -> Chemins de recherche d'en-tête
Il a des paramètres de construction -> Autres indicateurs de l'éditeur de liens
🐏 Cocoapods avec approche d'en-tête public
Jetez un œil au podspec https://github.com/honghaoz/Ji/blob/master/Ji.podspec
🐝 Articles connexes intéressants
la source
/CommonCrypto/CommonCrypto.h
intérieurApplications/XCode.app/Contents/Developer/Platforms/iPhoneOS....
, ce qui nécessitait une modification manuelle pour les personnes qui ont renommé XCode. Changer cette ligne pour regarder"/usr/include/CommonCrypto/CommonCrypto.h"
semble fonctionner correctement pour une équipe avec plusieurs versions de XCode. Merci beaucoup!pod lib lint
, mais que la construction a échoué avec une erreur: aucun module de ce type «CommonCrypto». Comment puis-je y faire face.$(PODS_ROOT)/CommonCryptoSwift/Sources/CCommonCrypto
par$(PODS_TARGET_SRCROOT)/Sources/CCommonCrypto
.PODS_TARGET_SRCROOT
est correctement défini pour les pods locaux.Bonnes nouvelles! Swift 4.2 (Xcode 10) fournit enfin CommonCrypto!
Ajoutez simplement
import CommonCrypto
votre fichier Swift.la source
CommonCrypto
modules, soupçonnant ainsi Apple maintenant à condition que j'ai supprimé ma solution de contournement et «voilà! C'était vrai. J'ai tweeté à ce sujet et un ingénieur Apple a répondu en confirmant que c'était prévu.AVERTISSEMENT: iTunesConnect peut rejeter les applications qui utilisent cette méthode.
Un nouveau membre de mon équipe a accidentellement cassé la solution donnée par l'une des principales réponses, j'ai donc décidé de la consolider dans un petit projet de wrapper appelé CommonCryptoModule . Vous pouvez l'installer manuellement ou via Cocoapods:
Ensuite, il ne vous reste plus qu'à importer le module là où vous en avez besoin
CommonCrypto
, comme ceci:J'espère que quelqu'un d'autre trouvera cela utile.
la source
Je pense que j'ai une amélioration par rapport à l'excellent travail de Mike Weller.
Ajoutez une phase Run Script avant la
Compile Sources
phase contenant cette bash:Ce script construit un framework simple avec le module.map au bon endroit, puis s'appuie sur la recherche automatique de Xcode
BUILT_PRODUCTS_DIR
pour les frameworks.J'ai lié le dossier d'inclusion CommonCrypto d'origine en tant que dossier Headers du framework afin que le résultat fonctionne également pour les projets Objective C.
la source
Pour tous ceux qui utilisent swift 4.2 avec Xcode 10 :
Le module CommonCrypto est maintenant fourni par le système, vous pouvez donc l'importer directement comme n'importe quel autre framework système.
la source
@mogstad a eu la gentillesse d'envelopper la solution @stephencelis dans un Cocoapod:
pod 'libCommonCrypto'
Les autres pods disponibles ne fonctionnaient pas pour moi.
la source
Les solutions modulemap peuvent être bonnes et résistantes aux modifications du SDK, mais je les ai trouvées difficiles à utiliser dans la pratique, et pas aussi fiables que je le souhaiterais lorsque je les distribue à d'autres. Pour essayer de rendre tout cela plus infaillible, je suis allé d'une manière différente:
Copiez simplement les en-têtes.
Je sais, fragile. Mais Apple n'apporte presque jamais de changements significatifs à CommonCrypto et je vis le rêve qu'ils ne le changeront pas de manière significative sans finalement faire de CommonCrypto un en-tête modulaire.
Par «copier les en-têtes», je veux dire «couper et coller tous les en-têtes dont vous avez besoin dans un en-tête massif de votre projet, comme le ferait le préprocesseur». À titre d'exemple que vous pouvez copier ou adapter, consultez RNCryptor.h .
Notez que tous ces fichiers sont sous licence APSL 2.0, et cette approche maintient intentionnellement les avis de copyright et de licence. Mon étape de concaténation est sous licence MIT, et cela ne s'applique que jusqu'au prochain avis de licence).
Je ne dis pas que c'est une belle solution, mais jusqu'à présent, cela semble avoir été une solution incroyablement simple à mettre en œuvre et à soutenir.
la source
Security.framework
c'est automatiquement lié (ça fait un petit moment depuis qu'un nouveau projet a commencé). Si vous obtenez des erreurs, c'est le cadre à lier.Je sais que c'est une vieille question. Mais je trouve une autre façon d'utiliser la bibliothèque dans le projet Swift, ce qui pourrait être utile pour ceux qui ne veulent pas importer le cadre introduit dans ces réponses.
Dans le projet Swift, créez un en-tête de pontage Objective-C, créez une catégorie NSData (ou une classe personnalisée pour utiliser la bibliothèque) dans Objective-C. Le seul inconvénient serait que vous deviez écrire tout le code d'implémentation en Objective-C. Par exemple:
Et puis dans votre en-tête de pont objective-c, ajoutez ceci
Et puis en classe Swift, faites la même chose:
Cela fonctionne comme prévu.
la source
NSData+NSDataEncryptionExtension.h
ne doit pas nécessairement être public).J'ai ajouté de la magie des cocoapodes à la réponse de jjrscott au cas où vous auriez besoin d'utiliser CommonCrypto dans votre bibliothèque de cocoapodes.
1) Ajoutez cette ligne à votre podspec:
2) Enregistrez-le dans le dossier de votre bibliothèque ou où vous le souhaitez (mais n'oubliez pas de modifier le script_phase en conséquence ...)
Fonctionne comme un charme :)
la source
Je ne sais pas si quelque chose a changé avec Xcode 9.2 mais c'est maintenant beaucoup plus simple d'y parvenir. Les seules choses que j'avais à faire étaient de créer un dossier appelé "CommonCrypto" dans le répertoire de mon projet de cadre et de créer deux fichiers à l'intérieur, l'un appelé "cc.h" comme suit:
Et un autre appelé module.modulemap:
(Je ne sais pas pourquoi vous ne pouvez pas référencer les fichiers d'en-tête de la zone SDKROOT directement dans un fichier modulemap mais je n'ai pas pu le faire fonctionner)
La troisième chose est de trouver le paramètre "Import Paths" et de le définir sur $ (SRCROOT). En fait, vous pouvez le définir dans le dossier dans lequel vous souhaitez placer le dossier CommonCrypto, si vous ne le souhaitez pas au niveau racine.
Après cela, vous devriez pouvoir utiliser
Dans n'importe quel fichier swift et tous les types / fonctions / etc. sont disponibles.
Un mot d'avertissement cependant - si votre application utilise libCommonCrypto (ou libcoreCrypto), il est exceptionnellement facile pour un pirate pas trop sophistiqué d'attacher un débogueur à votre application et de découvrir quelles clés sont passées à ces fonctions.
la source
Dans le cas où vous rencontrez le problème ci-dessous:
Dans Xcode 10, Swift 4.0. CommonCrypto fait partie du framework.
Ajouter
Retirer
import CommonCrypto
de l'en-tête de pontCela a fonctionné pour moi!
la source
Cela m'est arrivé après la mise à jour de Xcode. J'ai essayé tout ce que je pouvais faire, comme réinstaller les cocoapodes et nettoyer le projet, mais cela n'a pas fonctionné. Maintenant, il a été résolu après le redémarrage du système.
la source
C'est très simple. Ajouter
dans un fichier .h (le fichier d'en-tête de pontage de votre projet). Par convention, vous pouvez l'appeler YourProjectName-Bridging-Header.h.
Accédez ensuite aux paramètres de construction de votre projet et recherchez Swift Compiler - Génération de code. En dessous, ajoutez le nom de votre en-tête de pont à l'entrée "Objetive-C Bridging Header".
Vous avez terminé. Aucune importation requise dans votre code Swift. Tous les en-têtes Objective-C publics répertoriés dans ce fichier d'en-tête de pontage seront visibles par Swift.
la source