CommonCrypto in ein Swift-Framework importieren


184

Wie importiere ich CommonCryptoin ein Swift-Framework für iOS?

Ich verstehe, wie man CommonCryptoin einer Swift-App verwendet: Sie fügen #import <CommonCrypto/CommonCrypto.h>dem Bridging-Header hinzu. Swift-Frameworks unterstützen jedoch keine Bridging-Header. Die Dokumentation sagt:

Sie können externe Frameworks importieren, die eine reine Objective-C-Codebasis, eine reine Swift-Codebasis oder eine gemischtsprachige Codebasis haben. Der Vorgang zum Importieren eines externen Frameworks ist der gleiche, unabhängig davon, ob das Framework in einer einzigen Sprache geschrieben ist oder Dateien aus beiden Sprachen enthält. Stellen Sie beim Importieren eines externen Frameworks sicher, dass die Build-Einstellung Defines Module für das zu importierende Framework auf Yes festgelegt ist.

Sie können ein Framework mit der folgenden Syntax in eine beliebige Swift-Datei innerhalb eines anderen Ziels importieren:

import FrameworkName

Leider CommonCryptofunktioniert der Import nicht. Das Hinzufügen #import <CommonCrypto/CommonCrypto.h>zum Umbrella-Header erfolgt ebenfalls nicht.


CommonCrypto ist ein C-basiertes Framework, kein Objective-C-Framework.
rmaddy

1
@rmaddy Objective-C ist eine C-Obermenge. Wollen Sie damit sagen, dass wir CommonCrypto von Swift nicht verwenden können?
Hpique

4
@rmaddy Ich habe es gerade geschafft, CommonCrypto mithilfe von Modulzuordnungen zum Laufen zu bringen. Ich werde die Lösung polieren und später heute veröffentlichen.
hpique

Wenn Sie es bequem finden und das, wonach Sie suchen, bereits implementiert ist, können Sie CryptoSwift
Marcin

1
Apple hat gerade CommonCrypto mit offenen Quellen. Vielleicht können wir es zum Laufen bringen, wenn wir die Quellen haben.
Augapfel

Antworten:


137

Etwas einfacher und robuster ist es, ein Aggregatziel namens "CommonCryptoModuleMap" mit einer Run Script-Phase zu erstellen, um die Modulzuordnung automatisch und mit dem richtigen Xcode / SDK-Pfad zu generieren:

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Die Run Script-Phase sollte diesen Bash enthalten:

# 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

Wenn Sie Shell-Code verwenden ${SDKROOT}, müssen Sie den Pfad Xcode.app nicht hart codieren, was von System zu System variieren kann, insbesondere wenn Sie xcode-selectzu einer Beta-Version wechseln oder auf einem CI-Server aufbauen, auf dem mehrere Versionen installiert sind an nicht standardmäßigen Standorten. Sie müssen das SDK auch nicht hart codieren, damit dies für iOS, macOS usw. funktioniert. Außerdem muss sich nichts im Quellverzeichnis Ihres Projekts befinden.

Stellen Sie nach dem Erstellen dieses Ziels Ihre Bibliothek / Ihr Framework mit einem Element "Zielabhängigkeiten" davon abhängig:

Geben Sie hier die Bildbeschreibung ein

Dadurch wird sichergestellt, dass die Modulzuordnung generiert wird, bevor Ihr Framework erstellt wird.

macOS-Hinweis : Wenn Sie ebenfalls unterstützen macOS, müssen Sie macosxdie Supported PlatformsBuild-Einstellung für das neue Aggregatziel, das Sie gerade erstellt haben, erweitern, da sonst die Modulzuordnung nicht Debugmit dem Rest des Ordners im richtigen abgeleiteten Datenordner abgelegt wird Rahmenprodukte.

Geben Sie hier die Bildbeschreibung ein

Fügen Sie als Nächstes das übergeordnete Verzeichnis ${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMapder Modulzuordnung zur Build-Einstellung "Pfade importieren" im Abschnitt "Swift" ( SWIFT_INCLUDE_PATHS) hinzu:

Geben Sie hier die Bildbeschreibung ein

Denken Sie daran, eine $(inherited)Zeile hinzuzufügen , wenn Sie Suchpfade auf Projekt- oder xcconfig-Ebene definiert haben.

Das war's, du solltest es jetzt können import CommonCrypto

Update für Xcode 10

Xcode 10 wird jetzt mit einer CommonCrypto-Modulzuordnung geliefert, sodass diese Problemumgehung nicht mehr erforderlich ist. Wenn Sie sowohl Xcode 9 als auch Xcode 10 unterstützen möchten, können Sie in der Phase "Skript ausführen" überprüfen, ob die Modulzuordnung vorhanden ist oder nicht, z

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
Diese Antwort sollte oben sein. Einfach und elegant
Abdullah Saeed

1
Spät zum Spiel - aber dies sollte die gewählte Antwort sein. Es ist einfach und für andere Entwickler, die an demselben Projekt arbeiten, einfacher, die Anforderungen zu erkennen.
fatuous.logic

1
Gute Antwort. Vielen Dank!
Klaus Busse

1
Wenn ich dies in meinem .framework mache, muss ich dasselbe in den Projekten tun, in denen ich dieses Framework einbinde?
Ravi Kiran

2
@ IanDundas Ich habe den obigen Code mit einem Fix für das Problem der Neukompilierung sowie einem Fix für die Verwendung unter macOS
aktualisiert

91

Sie können tatsächlich eine Lösung erstellen, die "einfach funktioniert" (Sie müssen keine module.modulemap und SWIFT_INCLUDE_PATHSEinstellungen in Ihr Projekt kopieren , wie dies für andere Lösungen hier erforderlich ist), aber Sie müssen ein Dummy-Framework / Modul erstellen, das Sie ' Ich importiere in Ihr Framework. Wir können auch dafür sorgen , es funktioniert unabhängig von der Plattform ( iphoneos, iphonesimulatoroder macosx).

  1. Fügen Sie Ihrem Projekt ein neues Framework-Ziel hinzu und benennen Sie es nach der Systembibliothek, z. B. "CommonCrypto". (Sie können den Umbrella-Header CommonCrypto.h löschen .)

  2. Fügen Sie eine neue Datei - Konfigurationseinstellungen und nennt es, zum Beispiel , „CommonCrypto.xcconfig“. (Überprüfen Sie keines Ihrer Ziele auf Aufnahme.) Füllen Sie Folgendes aus:

    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. Erstellen Sie die drei oben genannten Modulzuordnungsdateien oben und füllen Sie sie mit den folgenden Angaben:

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

    (Ersetzen Sie "Xcode.app" durch "Xcode-beta.app", wenn Sie eine Beta-Version ausführen. Ersetzen Sie sie 10.11durch Ihr aktuelles OS SDK, wenn Sie El Capitan nicht ausführen.)

  4. Setzen Sie auf der Registerkarte Info Ihrer Projekteinstellungen unter Konfigurationen die Debug- und Release- Konfigurationen von CommonCrypto auf CommonCrypto (unter Bezugnahme auf CommonCrypto.xcconfig ).

  5. Auf dem Framework - Ziel Build - Phasen Registerkarte, fügen Sie den CommonCrypto Rahmen Ziel Abhängigkeiten . Fügen Sie außerdem libcommonCrypto.dylib zur Erstellungsphase von Link Binary With Libraries hinzu .

  6. Wählen Sie CommonCrypto.framework in Produkten und stellen Sie sicher , dass sein Ziel Mitgliedschaft für Ihren Wrapper gesetzt ist Optional .

Sie sollten nun in der Lage sein, import CommonCryptoIhr Wrapper-Framework zu erstellen, auszuführen und zu verwenden .

Ein Beispiel finden Sie unter Verwendung von Dummy sqlite3.framework durch SQLite.swift .


4
Funktioniert bei mir ohne Schritt (5). Damit bekomme ich einen Build-Fehler: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
Ausgezeichnet! Ich habe dies verwendet, um github.com/soffes/Crypto zu erstellen. Ich musste jedoch keinen Link System.frameworkerstellen. Es ist erwähnenswert, dass Sie ein separates Wrapper-Framework für Mac und iOS erstellen müssen, wenn Ihr Framework plattformübergreifend ist.
Sam Soffes

32
Wie oder wo finden die Leute so etwas heraus?
Hola

5
Nur ein Hinweis macht deutlich, dass Sie in Schritt 1 Objective-C als Sprache auswählen müssen. Dies wird leicht übersehen. Vielleicht, weil ich keine .dylib hatte, musste ich das .framework in Schritt 5 hinzufügen.
Teo Sartori

7
das ist schrecklich Ich habe einen Zoo von Xcodes, die jeweils auf unterschiedliche Weise kaputt sind, und die absoluten Pfade zu den Headern überall zu haben, ist kotzenaufrufend. In Cupertino läuft etwas furchtbar schief, oder zumindest mit demjenigen, der für dieses Modulkarten-Chaos verantwortlich ist
Anton Tropashko,

82

Ich habe ein GitHub-Projekt gefunden, das CommonCrypto erfolgreich in einem Swift-Framework verwendet: SHA256-Swift . Auch dieser Artikel über das gleiche Problem mit sqlite3 war nützlich.

Basierend auf dem oben Gesagten sind die Schritte:

1) Erstellen Sie ein CommonCryptoVerzeichnis innerhalb des Projektverzeichnisses. Erstellen Sie innerhalb eine module.mapDatei. Die Modulzuordnung ermöglicht es uns, die CommonCrypto-Bibliothek als Modul in Swift zu verwenden. Sein Inhalt ist:

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) Fügen Sie in den Build-Einstellungen in Swift Compiler - Suchpfade das CommonCryptoVerzeichnis zu Import Paths ( SWIFT_INCLUDE_PATHS) hinzu.

Build-Einstellungen

3) Importieren Sie abschließend CommonCrypto wie alle anderen Module in Ihre Swift-Dateien. Beispielsweise:

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

Einschränkungen

Die Verwendung des benutzerdefinierten Frameworks in einem anderen Projekt schlägt beim Kompilieren mit dem Fehler fehl missing required module 'CommonCrypto'. Dies liegt daran, dass das CommonCrypto-Modul anscheinend nicht im benutzerdefinierten Framework enthalten ist. Eine Problemumgehung besteht darin, Schritt 2 (Einstellung Import Paths) in dem Projekt zu wiederholen , das das Framework verwendet.

Die Modulzuordnung ist nicht plattformunabhängig (sie verweist derzeit auf eine bestimmte Plattform, den iOS 8 Simulator). Ich weiß nicht, wie ich den Header-Pfad relativ zur aktuellen Plattform erstellen soll.

Updates für iOS 8 <= Wir sollten den Zeilenlink "CommonCrypto" entfernen , um die erfolgreiche Kompilierung zu erhalten.

UPDATE / EDIT

Ich habe immer wieder den folgenden Build-Fehler erhalten:

ld: Bibliothek für -lCommonCrypto für Architektur nicht gefunden x86_64 clang: Fehler: Linker-Befehl mit Exit-Code 1 fehlgeschlagen (verwenden Sie -v, um den Aufruf anzuzeigen)

Es sei denn, ich habe die Zeile link "CommonCrypto"aus der von module.mapmir erstellten Datei entfernt. Sobald ich diese Linie entfernt habe, ist sie in Ordnung.


30
Gee, Apple will es sicher schwierig machen. Würde es die Swifties töten, wenn wir nur Dateien / Frameworks importieren würden, ohne all diese BS durchlaufen zu müssen?
Zaph

4
Dies ist ärgerlich, da die $SDKROOTVariable Ihnen plattformunabhängige Pfade ermöglichen soll, aber ich habe keine Ahnung, wie Sie in Swift dazu gelangen können.
Danimal

2
Bei mir hat es nicht funktioniert, bis ich die link "CommonCrypto"aus der module.map-Datei entfernt habe.
Teo Sartori

1
Kann jemand bestätigen, dass dies mit Xcode 7.3 funktioniert? Diese Lösung funktioniert nach dem Update nicht mehr für mich.
Nikita Kukushkin

1
Korrektur: Es funktioniert einwandfrei, wenn ich für einen Simulator baue, aber die @ Verknüpfung schlägt fehl, wenn ich für ein iOS 9.3-Gerät mit "ld: Bibliothek nicht gefunden für -lCommonCrypto für Architektur arm64"
Nikita

50

In dieser Antwort wird erläutert, wie es in einem Framework sowie mit Cocoapods und Carthage funktioniert

🐟 Modulemap-Ansatz

Ich verwende modulemapin meinem Wrapper CommonCrypto https://github.com/onmyway133/arcane , https://github.com/onmyway133/Reindeer

Für diejenigen, die dies erhalten header not found, schauen Sie bitte unter https://github.com/onmyway133/Arcane/issues/4 nach oder führen Sie es ausxcode-select --install

  • Erstellen Sie einen Ordner CCommonCryptomitmodule.modulemap

      module CCommonCrypto {
        header "/usr/include/CommonCrypto/CommonCrypto.h"
        export *
      }
  • Gehen Sie zu Erstellungseinstellungen -> Pfade importieren

      ${SRCROOT}/Sources/CCommonCrypto

🌳 Cocoapods mit Modulemap-Ansatz

🐘 Ansatz für öffentliche Header

🐏 Cocoapods mit öffentlichem Header-Ansatz

🐝 Interessante verwandte Beiträge


1
Beeindruckend! Zu meiner Überraschung funktionierte der Header-Pfad vom obersten Ansatz (Erstellen der Datei module.modulemap) hervorragend, wenn zuvor Modulemap-Dateien viele Probleme verursacht hatten. Ich hatte eine Weile damit zu kämpfen, indem ich eine module.modulemap-Datei mit einem absoluten Pfad nach /CommonCrypto/CommonCrypto.hinnen verwendete Applications/XCode.app/Contents/Developer/Platforms/iPhoneOS...., die für Personen, die XCode umbenannten, manuelle Änderungen erforderte. Das Umschalten dieser Zeile "/usr/include/CommonCrypto/CommonCrypto.h"scheint für ein Team mit mehreren XCode-Versionen gut zu funktionieren. Ich danke dir sehr!
Natalia

3
Beim Erstellen eines Pods setze ich die SWIFT_INCLUDE_PATHS- und bewahren_Pfade. Wenn ich laufe pod lib lint, aber die Erstellung mit Fehler fehlgeschlagen ist: Kein solches Modul 'CommonCrypto'. Wie kann ich damit umgehen?
Klein Mioke

1
Nicht im Zusammenhang mit dem Problem, aber ich liebe die Verwendung von Emoji als Kugeln! 😊
Fomentia

2
@ onmyway133 lokale Entwicklung pod Arbeiten verwenden , wenn Sie ersetzen $(PODS_ROOT)/CommonCryptoSwift/Sources/CCommonCryptomit $(PODS_TARGET_SRCROOT)/Sources/CCommonCrypto. PODS_TARGET_SRCROOTist für lokale Pods richtig eingestellt.
Orkhan Alikhanov

Tolle Antwort, hat mir das Leben gerettet! Vielen Dank
Hassan Shahbazi

45

Gute Nachrichten! Swift 4.2 (Xcode 10) bietet endlich CommonCrypto!

Fügen import CommonCryptoSie einfach Ihre schnelle Datei hinzu.


Großartige Neuigkeiten! Können Sie den Link zur Dokumentation hinzufügen?
Kryštof Matěj

Ich habe keinen Link zur Dokumentation. Ich habe dies entdeckt, als ich versucht habe, ein Projekt zu kompilieren, bei dem ich eine der Problemumgehungen hier mit Xcode 10 hatte. Es wurde beanstandet, dass zwei CommonCryptoModule gefunden werden konnten, und Apple vermutet, dass ich meine Problemumgehung und entfernt habe 'lo! Es war wahr. Ich habe darüber getwittert und ein Apple-Ingenieur hat geantwortet, dass dies beabsichtigt ist.
mxcl

1
Der App Store zeigt mir nur 9.4.7 als verfügbares Update. Wie haben Sie Xcode 10 erhalten?
Hammad Tariq

1
Es ist in der Beta, wie eine triviale Google-Suche Ihnen gesagt hätte.
mxcl

1
@ SomoyDasGupta ja. Entfernen Sie einfach den vorherigen Import und kompilieren Sie ihn erneut. Mit anderen Worten, Sie müssen nicht die Schritte von MikeWeller Antwort
COLD ICE

7

WARNUNG: iTunesConnect lehnt möglicherweise Apps ab, die diese Methode verwenden.


Ein neues Mitglied in meinem Team hat versehentlich die Lösung einer der wichtigsten Antworten gebrochen, und ich habe beschlossen, sie in einem kleinen Wrapper-Projekt namens CommonCryptoModule zu konsolidieren . Sie können es manuell oder über Cocoapods installieren:

pod 'CommonCryptoModule', '~> 1.0.2'

Dann müssen Sie nur noch das Modul an die gewünschte Stelle importieren CommonCrypto:

import CommonCryptoModule

Hoffe, jemand anderes findet das nützlich.


Warnung: Ihre Bewerbung wird abgelehnt, wenn Sie diese Methode anwenden!
Segabond

Ja, wir wurden ebenfalls abgelehnt, sehr seltsam, weil wir mit dieser Methode mehrere Monate lang ohne Probleme hochgeladen haben.
Nikita Kukushkin

5

Ich glaube, ich habe eine Verbesserung von Mike Wellers hervorragender Arbeit.

Fügen Sie vor der Compile SourcesPhase, die diese Bash enthält, eine Run Script-Phase hinzu :

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

Dieses Skript erstellt ein Bare-Bones-Framework mit der module.map an der richtigen Stelle und stützt sich dann auf die automatische Suche von Xcode nach BUILT_PRODUCTS_DIR nach Frameworks.

Ich habe den ursprünglichen CommonCrypto-Include-Ordner als Header-Ordner des Frameworks verknüpft, sodass das Ergebnis auch für Objective C-Projekte funktionieren sollte.


Siehe dvdblk Antwort für eine Verbesserung , dass Abdeckungen Verwendung in CocoaPods.
jjrscott


4

@mogstad war so freundlich, @stephencelis-Lösung in einen Cocoapod zu wickeln:

pod 'libCommonCrypto'

Die anderen verfügbaren Pods haben bei mir nicht funktioniert.


4

Die Modulemap-Lösungen können gut sein und sind robust gegen SDK-Änderungen, aber ich fand sie in der Praxis umständlich und nicht so zuverlässig, wie ich es gerne hätte, wenn ich Dinge an andere verteile. Um alles narrensicherer zu machen, bin ich einen anderen Weg gegangen:

Kopieren Sie einfach die Header.

Ich weiß, zerbrechlich. Aber Apple nimmt fast nie wesentliche Änderungen an CommonCrypto vor und ich lebe den Traum, dass sie es nicht wesentlich ändern werden, ohne CommonCrypto schließlich auch zu einem modularen Header zu machen.

Mit "Kopieren der Header" meine ich "Ausschneiden und Einfügen aller benötigten Header in einen massiven Header in Ihrem Projekt, genau wie es der Präprozessor tun würde." Ein Beispiel dafür, das Sie kopieren oder anpassen können, finden Sie unter RNCryptor.h .

Beachten Sie, dass alle diese Dateien unter APSL 2.0 lizenziert sind und bei diesem Ansatz die Urheberrechts- und Lizenzhinweise absichtlich beibehalten werden. Mein Verkettungsschritt ist unter MIT lizenziert und dies gilt nur bis zur nächsten Lizenzbenachrichtigung.

Ich sage nicht, dass dies eine schöne Lösung ist, aber bisher scheint es eine unglaublich einfache Lösung für die Implementierung und den Support gewesen zu sein.


Ich fand das zuverlässig kompilieren und es ist ganz einfach. Muss die Anwendung, die das Framework verwendet, eine Verknüpfung zu etwas Besonderem herstellen, oder ist CommonCrypto immer verfügbar?
CodingFriend1

1
Ich denke, es Security.frameworkwird automatisch verlinkt (es ist eine Weile her, seit ein neues Projekt gestartet wurde). Wenn Sie Fehler erhalten, ist dies das zu verknüpfende Framework.
Rob Napier

Dies scheint die einfachste Lösung zu sein und funktioniert auf einem Computer hervorragend. Wenn ich das Framework jedoch in einem anderen Framework oder einer anderen App auf einem anderen Computer verwende, wird der Fehler "Fehlendes Modul" angezeigt.
Richever

2

Ich weiß, dass dies eine alte Frage ist. Ich finde jedoch eine alternative Möglichkeit, die Bibliothek im Swift-Projekt zu verwenden, die für diejenigen hilfreich sein kann, die das in diesen Antworten eingeführte Framework nicht importieren möchten.

Erstellen Sie im Swift-Projekt einen Objective-C-Bridging-Header, erstellen Sie in Objective-C eine NSData-Kategorie (oder eine benutzerdefinierte Klasse, die die Bibliothek verwenden soll). Der einzige Nachteil wäre, dass Sie den gesamten Implementierungscode in Objective-C schreiben müssen. Beispielsweise:

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

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

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

Fügen Sie dies dann in Ihrem Ziel-C-Überbrückungsheader hinzu

#import "NSData+NSDataEncryptionExtension.h"

Und dann in der Swift-Klasse machen Sie etwas Ähnliches:

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

Es funktioniert wie erwartet.


Dies funktioniert sehr reibungslos und ermöglicht es Ihnen sogar, Interna intern zu halten ( NSData+NSDataEncryptionExtension.hmuss nicht öffentlich sein).
Raphael

Aber gegen welches Betriebssystem-Framework sollte ich verlinken, um dieses Ding zu verwenden? Im Gegensatz zu anderen - ich muss mit CommonCrypto in einem Obj-C-Projekt arbeiten, und das allein bricht auf Xcode 9 mit MacOS-10.13 SDK
Motti Shneor

@MottiShneor Verknüpfen Sie ein beliebiges Betriebssystem ab 10.9. Ich arbeite an der gleichen Umgebung und es funktioniert gut.
Terence

2

Ich habe jjrscotts Antwort etwas Cocoapods-Magie hinzugefügt, falls Sie CommonCrypto in Ihrer Cocoapods-Bibliothek verwenden müssen.


1) Fügen Sie diese Zeile Ihrer Podspec hinzu:

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

2) Speichern Sie dies in Ihrem Bibliotheksordner oder wo immer Sie möchten (vergessen Sie jedoch nicht, die script_phase entsprechend zu ändern ...)

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

Klappt wunderbar :)


Können Sie ein Demo oder ein Beispiel-Framework-Projekt für dasselbe zusammen mit der Pod-Spezifikationsdatei bereitstellen?
Gowtham

0

Ich bin mir nicht sicher, ob sich mit Xcode 9.2 etwas geändert hat, aber es ist jetzt viel einfacher, dies zu erreichen. Das einzige, was ich tun musste, war, einen Ordner mit dem Namen "CommonCrypto" in meinem Framework-Projektverzeichnis zu erstellen und zwei Dateien darin zu erstellen, eine mit dem Namen "cc.h" wie folgt:

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

Und eine andere namens module.modulemap:

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

(Ich weiß nicht, warum Sie Header-Dateien aus dem SDKROOT-Bereich nicht direkt in einer Modulemap-Datei referenzieren können, aber ich konnte sie nicht zum Laufen bringen.)

Die dritte Sache ist, die Einstellung "Pfade importieren" zu finden und auf $ (SRCROOT) zu setzen. Tatsächlich können Sie es auf einen beliebigen Ordner festlegen, unter dem sich der CommonCrypto-Ordner befinden soll, wenn Sie ihn nicht auf Stammebene möchten.

Danach sollten Sie in der Lage sein, zu verwenden

import CommonCrypto

In jeder schnellen Datei und allen Typen / Funktionen / etc. stehen zur Verfügung.

Ein Wort der Warnung: Wenn Ihre App libCommonCrypto (oder libcoreCrypto) verwendet, ist es für einen nicht allzu hoch entwickelten Hacker außerordentlich einfach, einen Debugger an Ihre App anzuhängen und herauszufinden, welche Schlüssel an diese Funktionen übergeben werden.


0

Falls Sie das folgende Problem haben:

ld: Bibliothek für -lapple_crypto nicht gefunden clang: Fehler: Linker-Befehl mit Exit-Code 1 fehlgeschlagen (verwenden Sie -v, um den Aufruf anzuzeigen)

In Xcode 10 Swift 4.0. CommonCrypto ist Teil des Frameworks.

Hinzufügen

 import CommonCrypto

Entfernen

  • CommonCrpto lib-Datei aus Link-Binärdatei mit Bibliotheken aus Build-Phasen
  • import CommonCrypto vom Bridging-Header

Das hat bei mir funktioniert!


-1

Das ist mir auch nach dem Update von Xcode passiert. Ich habe alles versucht, was ich tun kann, z. B. Cocoapods neu installieren und das Projekt reinigen, aber es hat nicht funktioniert. Jetzt ist es nach dem Neustart des Systems behoben .


-13

Es ist sehr einfach. Hinzufügen

#import <CommonCrypto/CommonCrypto.h>

in eine .h-Datei (die Bridging-Header-Datei Ihres Projekts). Als Konvention können Sie es YourProjectName-Bridging-Header.h nennen.

Gehen Sie dann zu Ihrem Projekt Build Settings und suchen Sie nach Swift Compiler - Code Generation. Fügen Sie darunter den Namen Ihres Bridging-Headers zum Eintrag "Objetive-C Bridging Header" hinzu.

Du bist fertig. In Ihrem Swift-Code sind keine Importe erforderlich. Alle öffentlichen Objective-C-Header, die in dieser Bridging-Header-Datei aufgeführt sind, sind für Swift sichtbar.


Ihre Methode gibt einen Fehler zurück: Die Verwendung von Bridging-Headern mit Framework-Zielen wird nicht unterstützt
gorgi93

5
@ gorgi93 Sie können keinen Bridging-Header in einem Framework-Ziel verwenden, wie der Fehler nahelegt. Die einzige Möglichkeit besteht darin, es leider in die Haupt-Framework-Header-Datei einzufügen.
Charles A.

1
Wenn Sie den Titel dieses Threads tatsächlich rot angezeigt hätten, hätten Sie gesehen, dass der Typ die CommonCrypto-Bibliothek in ein Swift-Framework importieren möchte. Sie können keine Bridging-Header in Frameworks verwenden und das CommonCrypto-Framework nicht in den Umbrella-Header importieren.
miken.mkndev
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.