Importowanie CommonCrypto w ramach Swift


184

Jak importować CommonCryptow środowisku Swift na iOS?

Rozumiem, jak używać CommonCryptow aplikacji Swift: dodajesz #import <CommonCrypto/CommonCrypto.h>do nagłówka pomostowego. Jednak frameworki Swift nie obsługują mostkowania nagłówków. Dokumentacja mówi:

Możesz importować zewnętrzne frameworki, które mają czystą bazę kodową Objective-C, czystą bazę kodową Swift lub bazę kodową w języku mieszanym. Proces importowania zewnętrznego frameworka jest taki sam, niezależnie od tego, czy frameworku jest napisany w jednym języku, czy zawiera pliki z obu języków. Podczas importowania frameworka zewnętrznego upewnij się, że ustawienie kompilacji modułu Definiuje dla importowanej frameworku jest ustawione na Tak.

Możesz zaimportować strukturę do dowolnego pliku Swift w innym celu za pomocą następującej składni:

import FrameworkName

Niestety import CommonCryptonie działa. Nie dodaje się również #import <CommonCrypto/CommonCrypto.h>do nagłówka parasola.


CommonCrypto jest strukturą opartą na języku C, a nie strukturą Objective-C.
— rmaddy

1
@rmaddy Objective-C jest nadzbiorem C. Mówisz, że nie możemy używać CommonCrypto od Swift?
— hpique

4
@rmaddy Właśnie udało mi się uruchomić CommonCrypto za pomocą map modułów. Ulepszę rozwiązanie i opublikuję je później dzisiaj.
— hpique

jeśli uznasz to za wygodne, a to, czego szukasz, jest już zaimplementowane, możesz spróbować CryptoSwift
— Marcin

1
Apple właśnie otworzyło źródło CommonCrypto. Może możemy uruchomić go, jeśli mamy źródła.
— eyeballz

Odpowiedzi:


137

Coś nieco prostszego i bardziej niezawodnego polega na utworzeniu celu agregującego o nazwie „CommonCryptoModuleMap” z fazą Run Script w celu automatycznego wygenerowania mapy modułów i prawidłowej ścieżki Xcode / SDK:

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

Faza Uruchom skrypt powinna zawierać ten 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

Używanie kodu powłoki i ${SDKROOT}oznacza, że ​​nie musisz kodować na stałe ścieżki Xcode.app, która może różnić się w zależności od systemu, szczególnie jeśli używasz xcode-selectdo przejścia do wersji beta lub budujesz na serwerze CI, na którym zainstalowanych jest wiele wersji w niestandardowych lokalizacjach. Nie musisz też kodować na stałe SDK, więc powinno to działać na iOS, macOS itp. Nie musisz też mieć niczego, co mogłoby znajdować się w katalogu źródłowym twojego projektu.

Po utworzeniu tego celu uzależnij swoją bibliotekę / strukturę za pomocą elementu Zależności docelowe:

wprowadź opis zdjęcia tutaj

Zapewni to wygenerowanie mapy modułów przed zbudowaniem frameworka.

Uwaga dotycząca systemu macOS : jeśli również wspierasz macOS, musisz dodać macosxdo Supported Platformsustawienia kompilacji nowego właśnie utworzonego celu zagregowanego, inaczej nie umieści on mapy modułów w odpowiednim Debugfolderze danych pochodnych wraz z resztą produkty ramowe.

wprowadź opis zdjęcia tutaj

Następnie dodaj katalog nadrzędny mapy modułów ${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMapdo ustawienia kompilacji „Importuj ścieżki” w sekcji Swift ( SWIFT_INCLUDE_PATHS):

wprowadź opis zdjęcia tutaj

Pamiętaj, aby dodać $(inherited)wiersz, jeśli masz ścieżki wyszukiwania zdefiniowane na poziomie projektu lub xcconfig.

To wszystko, powinieneś teraz być w stanie import CommonCrypto

Zaktualizuj Xcode 10

Xcode 10 jest teraz dostarczany z mapą modułów CommonCrypto, dzięki czemu to obejście nie jest konieczne. Jeśli chcesz obsługiwać zarówno Xcode 9, jak i 10, możesz sprawdzić w fazie Run Script, czy mapa modułu istnieje, czy nie, np.

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
Ta odpowiedź powinna być na górze. Prosty i elegancki
— Abdullah Saeed

1
Późno do gry w tej sprawie - ale to powinna być wybrana odpowiedź. To proste i łatwiejsze dla innych programistów pracujących nad tym samym projektem, aby zobaczyć wymaganie.
— fatuous.logic

1
Świetna odpowiedź. Dzięki!
— Klaus Busse

1
Jeśli robię to w moim .framework, czy powinienem robić to samo w projektach, w których włączam ten framework?
— Ravi Kiran

2
@IanDundas Zaktualizowałem powyższy kod poprawką dotyczącą problemu ponownej kompilacji, a także poprawką dotyczącą używania tego w systemie macOS
— iwasrobbed

91

Możesz faktycznie zbudować rozwiązanie, które „po prostu działa” (nie musisz kopiować modułu.modulemap i SWIFT_INCLUDE_PATHSustawień do projektu, jak wymagają tego inne rozwiązania tutaj), ale wymaga to stworzenia fałszywego frameworka / modułu, który „ Zaimportuję do twojego frameworka. Możemy również zapewnić, że działa niezależnie od platformy ( iphoneos, iphonesimulatorlub macosx).

  1. Dodaj nowy cel struktury do projektu i nazwij go po bibliotece systemowej, np. „CommonCrypto”. (Możesz usunąć nagłówek parasola CommonCrypto.h .)

  2. Dodaj nowy plik ustawień konfiguracji i nazwij go, np. „CommonCrypto.xcconfig”. (Nie zaznaczaj żadnego z celów pod kątem włączenia.) Wypełnij go następującymi danymi:

    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. Utwórz trzy wyżej wymienione pliki map modułów i wypełnij je następującymi elementami:

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

    (Jeśli używasz wersji beta, zamień „Xcode.app” na „Xcode-beta.app”. Zastąp 10.11obecny pakiet SDK systemu operacyjnego, jeśli nie używasz El Capitan.)

  4. Na Info zakładce ustawień projektu, pod Konfiguracje ustaw Debug i Release konfiguracje CommonCrypto do CommonCrypto (odwołującego CommonCrypto.xcconfig ).

  5. Na karcie Fazy ​​kompilacji celu struktury szkieletowej dodaj strukturę CommonCrypto do Zależności docelowych . Dodatkowo dodaj libcommonCrypto.dylib do fazy kompilacji Link Binary With Libraries .

  6. Wybierz CommonCrypto.framework w produktach i upewnij się, że jego docelowe członkostwo dla opakowania jest ustawione na opcjonalne .

Powinieneś być teraz w stanie budować, uruchamiać i import CommonCryptow swoim środowisku opakowującym.

Na przykład zobacz, jak SQLite.swift używa fałszywego narzędzia sqlite3.framework .


4
Działa dla mnie bez kroku (5). Wraz z nim pojawia się błąd kompilacji: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
Doskonały! Użyłem tego do stworzenia github.com/soffes/Crypto, którego nie musiałem jednak łączyć System.framework. Warto zauważyć, że jeśli twoja platforma jest wieloplatformowa, musisz stworzyć oddzielną strukturę opakowania dla komputerów Mac i iOS.
— Sam Soffes,

32
Jak lub gdzie ludzie dowiadują się takich rzeczy?
— hola,

5
Tylko uwaga wyjaśni, że w kroku 1 musisz wybrać Objective-C jako język. Można to łatwo przeoczyć. Być może dlatego, że nie miałem pliku .dylib, musiałem dodać plik .framework w kroku 5.
— Teo Sartori,

7
to jest okropne. Mam zoo Xkodów, z których każdy jest podzielony na różne sposoby, a posiadanie bezwzględnych ścieżek do nagłówków w całym miejscu jest przywoływaniem rzygania. Coś poszło nie tak w Cupertino, a przynajmniej z tym, kto jest odpowiedzialny za ten bałagan z modulemap
— Anton Tropashko

82

Znalazłem projekt GitHub, który z powodzeniem wykorzystuje CommonCrypto w środowisku Swift: SHA256-Swift . Przydał się także ten artykuł o tym samym problemie z sqlite3 .

W oparciu o powyższe kroki są następujące:

1) Utwórz CommonCryptokatalog w katalogu projektu. Wewnątrz utwórz module.mapplik. Mapa modułów pozwoli nam korzystać z biblioteki CommonCrypto jako modułu w Swift. Jego zawartość to:

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) W Ustawieniach kompilacji, w Swift Compiler - Search Paths , dodaj CommonCryptokatalog do Importuj ścieżki ( SWIFT_INCLUDE_PATHS).

Ustawienia kompilacji

3) Na koniec zaimportuj CommonCrypto do plików Swift, tak jak inne moduły. Na przykład:

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

Ograniczenia

Użycie niestandardowej struktury w innym projekcie kończy się niepowodzeniem podczas kompilacji z błędem missing required module 'CommonCrypto'. Wynika to z faktu, że moduł CommonCrypto nie wydaje się być dołączany do niestandardowej struktury. Obejściem tego problemu jest powtórzenie kroku 2 (ustawienie Import Paths) w projekcie korzystającym z frameworka.

Mapa modułów nie jest niezależna od platformy (obecnie wskazuje na konkretną platformę, symulator iOS 8). Nie wiem, jak ustawić ścieżkę nagłówka względem bieżącej platformy.

Aktualizacje dla iOS 8 <= Powinniśmy usunąć link do linii „CommonCrypto” , aby uzyskać udaną kompilację.

AKTUALIZACJA / EDYCJA

Wciąż pojawiał się następujący błąd kompilacji:

ld: nie znaleziono biblioteki dla -lCommonCrypto dla architektury x86_64 clang: error: komenda linkera nie powiodła się z kodem wyjścia 1 (użyj -v, aby zobaczyć wywołanie)

Chyba że usunąłem linię link "CommonCrypto"z utworzonego module.mappliku. Kiedy usunąłem tę linię, zbudowała się dobrze.


30
Ojej, Apple z pewnością chce utrudnić. Czy zabiłoby Swifties, aby pozwolić nam importować pliki / frameworki bez konieczności przechodzenia przez te wszystkie BS?
— zaph

4
Jest to irytujące, ponieważ $SDKROOTzmienna ma umożliwić ci agnostyczne ścieżki platformy, ale nie mam pojęcia, jak się do tego dostać w Swift.
— danimal

2
Dla mnie to nie działało, dopóki nie usunąłem link "CommonCrypto"pliku module.map.
— Teo Sartori,

1
Czy ktoś może potwierdzić, że działa na Xcode 7.3? To rozwiązanie przestało działać dla mnie po aktualizacji.
— Nikita Kukushkin

1
Poprawka: działa poprawnie, gdy buduję dla symulatora, ale nie działa @ link, gdy buduję dla urządzenia z systemem iOS 9.3 z „ld: nie znaleziono biblioteki dla -lCommonCrypto dla architektury arm64”
— Nikita Kukushkin

50

Ta odpowiedź omawia, jak sprawić, by działał wewnątrz frameworka oraz w Cocoapods i Carthage

Approach podejście modulemap

Używam modulemapw swoim opakowaniu wokół CommonCrypto https://github.com/onmyway133/arcane , https://github.com/onmyway133/Reindeer

Dla tych header not found, którzy dostają , spójrz https://github.com/onmyway133/Arcane/issues/4 lub uruchomxcode-select --install

  • Utwórz folder CCommonCryptozawierającymodule.modulemap

      module CCommonCrypto {
        header "/usr/include/CommonCrypto/CommonCrypto.h"
        export *
      }
  • Przejdź do Ustawień wbudowanych -> Importuj ścieżki

      ${SRCROOT}/Sources/CCommonCrypto

🌳 Cocoapods z podejściem modulemap

Approach podejście do nagłówka publicznego

🐏 Cocoapods z publicznym podejściem do nagłówka

🐝 Ciekawe powiązane posty


1
Łał! Ku mojemu zdziwieniu ścieżka nagłówka z najwyższego podejścia (tworzenie pliku module.modulemap) działała świetnie, gdy wcześniej pliki modulemap powodowały wiele problemów. Walczyłem z tym przez jakiś czas, używając pliku module.modulemap z bezwzględną ścieżką do /CommonCrypto/CommonCrypto.hwewnątrz Applications/XCode.app/Contents/Developer/Platforms/iPhoneOS...., co wymagało ręcznej modyfikacji dla osób, które zmieniły nazwę XCode. Zmiana tej linii, aby spojrzeć, "/usr/include/CommonCrypto/CommonCrypto.h"wydaje się działać dobrze dla zespołu z kilkoma wersjami XCode. Dziękuję bardzo!
— Natalia

3
Tworzę kapsułę, ustawiam SWIFT_INCLUDE_PATHS i zachowuję ścieżki. Kiedy uruchamiam pod lib lint, ale kompilacja nie powiodła się z błędem: nie ma takiego modułu „CommonCrypto”. Jak sobie z tym poradzić.
— Klein Mioke

1
Nie ma związku z problemem, ale uwielbiam używanie emoji jako pocisków! 😊
— Fomentia,

2
@ onmyway133 Korzystanie lokalnych prace kapsułowymi rozwój, jeśli zastąpi $(PODS_ROOT)/CommonCryptoSwift/Sources/CCommonCryptosię $(PODS_TARGET_SRCROOT)/Sources/CCommonCrypto. PODS_TARGET_SRCROOTjest ustawiony poprawnie dla lokalnych zasobników.
— Orkhan Alikhanov

Świetna odpowiedź, uratowała mi życie! Dzięki milionowi
— Hassan Shahbazi

45

Dobre wieści! Swift 4.2 (Xcode 10) wreszcie udostępnia CommonCrypto!

Po prostu dodaj import CommonCryptoswój szybki plik.


Dobre wieści! Czy możesz dodać link do dokumentacji?
— Kryštof Matěj

Nie mam linku do dokumentacji, odkryłem to podczas próby skompilowania projektu, w którym miałem tutaj jedno z obejść tego problemu za pomocą Xcode 10. Skarżył się, że może on znaleźć dwa CommonCryptomoduły, dlatego podejrzewałem, że Apple pod warunkiem, że usuną moje obejście i lo! To była prawda. Napisałem o tym na Twitterze i inżynier Apple odpowiedział, że jest zamierzony.
— mxcl

1
App Store pokazuje mi tylko 9.4.7 jako dostępną aktualizację, skąd masz Xcode 10?
— Hammad Tariq

1
Jest w fazie beta, jak powiedziałaby trywialna wyszukiwarka Google.
— mxcl

1
@SomoyDasGupta tak. Po prostu usuń poprzedni import i skompiluj go ponownie. Innymi słowy, nie musisz robić kroków od odpowiedzi MikeWellera
— COLD ICE

7

OSTRZEŻENIE: iTunesConnect może odrzucać aplikacje korzystające z tej metody.


Nowy członek mojego zespołu przypadkowo złamał rozwiązanie podane przez jedną z najlepszych odpowiedzi, więc postanowiłem skonsolidować je w małym projekcie opakowania o nazwie CommonCryptoModule . Możesz zainstalować go ręcznie lub za pośrednictwem Cocoapods:

pod 'CommonCryptoModule', '~> 1.0.2'

Następnie wystarczy zaimportować moduł tam, gdzie jest potrzebny CommonCrypto, w następujący sposób:

import CommonCryptoModule

Mam nadzieję, że ktoś inny uzna to za przydatne.


Ostrzeżenie: Twoja aplikacja zostanie odrzucona, jeśli użyjesz tej metody!
— Segabond

Tak, zostaliśmy również odrzuceni, bardzo dziwni, ponieważ przesyłaliśmy bez problemu przez kilka miesięcy przy użyciu tej metody.
— Nikita Kukushkin

5

Myślę, że poprawiłem doskonałą pracę Mike'a Wellera.

Dodaj fazę Run Script przed Compile Sourcesfazą zawierającą ten 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"

Ten skrypt konstruuje szkielet gołej kości z modułem module.map we właściwym miejscu, a następnie polega na automatycznym wyszukiwaniu BUILT_PRODUCTS_DIRramek przez Xcode .

Połączyłem oryginalny folder dołączania CommonCrypto jako folder nagłówków frameworka, więc wynik powinien również działać w projektach Celu C.


Zobacz odpowiedź dvdblk na ulepszenie, które obejmuje użycie w CocoaPods.
— jjrscott,


4

@mogstad był na tyle miły, że umieścił rozwiązanie @stephencelis w Cocoapod:

pod „libCommonCrypto”

Inne dostępne kapsułki nie działały dla mnie.


4

Rozwiązania z modulemapami mogą być dobre i odporne na zmiany SDK, ale okazało się, że są one niewygodne w użyciu i nie są tak niezawodne, jak bym chciał, gdy przekazuję je innym. Aby uczynić to bardziej niezawodnym, poszedłem inną drogą:

Po prostu skopiuj nagłówki.

Wiem, kruche. Ale Apple prawie nigdy nie wprowadza znaczących zmian w CommonCrypto i żyję marzeniem, że nie zmienią go w żaden znaczący sposób bez ostatecznego przekształcenia CommonCrypto w modułowy nagłówek.

Przez „skopiuj nagłówki” mam na myśli „wytnij i wklej wszystkie potrzebne nagłówki do jednego ogromnego nagłówka w swoim projekcie, tak jak zrobiłby to preprocesor”. Jako przykład tego można skopiować lub dostosować, patrz RNCryptor.h .

Należy pamiętać, że wszystkie te pliki są objęte licencją APSL 2.0, a to podejście celowo utrzymuje prawa autorskie i uwagi dotyczące licencji. Mój krok konkatenacji jest licencjonowany na podstawie MIT, a dotyczy to tylko następnego zawiadomienia o licencji).

Nie twierdzę, że jest to piękne rozwiązanie, ale jak dotąd wydaje się, że było to niezwykle proste rozwiązanie zarówno dla wdrożenia, jak i wsparcia.


Przekonałem się, że to kompilacja niezawodnie i jest po prostu prosta. Czy aplikacja korzystająca z frameworka musi łączyć się z czymkolwiek specjalnym, czy też CommonCrypto jest zawsze dostępne?
— codingFriend1

1
Myślę, że Security.frameworkjest automatycznie łączony (minęło trochę czasu od rozpoczęcia nowego projektu). Jeśli pojawią się błędy, jest to struktura do połączenia.
— Rob Napier

To wydaje się być najprostszym rozwiązaniem i działa świetnie na jednym komputerze, ale za każdym razem, gdy używam frameworka w innym frameworku lub aplikacji, na innym komputerze pojawia się błąd „brakującego modułu”.
— richever

2

Wiem, że to stare pytanie. Ale wymyślam alternatywny sposób korzystania z biblioteki w projekcie Swift, który może być pomocny dla tych, którzy nie chcą importować frameworku przedstawionego w tych odpowiedziach.

W projekcie Swift utwórz nagłówek mostkujący Objective-C, stwórz kategorię NSData (lub klasę niestandardową, która ma korzystać z biblioteki) w Objective-C. Jedyną wadą byłoby to, że musisz napisać cały kod implementacji w Objective-C. Na przykład:

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

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

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

A następnie w nagłówku mostkowania celu c dodaj to

#import "NSData+NSDataEncryptionExtension.h"

A potem w klasie Swift wykonaj podobne rzeczy:

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

Działa zgodnie z oczekiwaniami.


Działa to bardzo płynnie, a nawet pozwala zachować wewnętrzne elementy wewnętrzne ( NSData+NSDataEncryptionExtension.hnie muszą być publiczne).
— Raphael

Ale z jakim systemem operacyjnym powinienem się połączyć, aby użyć tej rzeczy? W przeciwieństwie do innych - muszę pracować z CommonCrypto w projekcie Obj-C, a to samo psuje się na Xcode 9 z SDK MacOS-10.13
— Motti Shneor

@MottiShneor Połącz dowolny system operacyjny od wersji 10.9 lub nowszej. Pracuję na tym samym środowisku i działa dobrze.
— Terence

2

Dodałem trochę magii cocoapods do odpowiedzi jjrscotta na wypadek, gdybyś musiał użyć CommonCrypto w swojej bibliotece cocoapods.


1) Dodaj tę linię do swojego podspec:

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

2) Zapisz to w folderze biblioteki lub gdziekolwiek chcesz (nie zapomnij jednak odpowiednio zmienić fazy skryptu ...)

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

Działa jak marzenie :)


Czy możesz dostarczyć demo lub przykładowy projekt ramowy dla tego samego wraz z plikiem specyfikacji pod?
— Gowtham,

0

Nie jestem pewien, czy coś się zmieniło w Xcode 9.2, ale teraz jest o wiele łatwiej to osiągnąć. Jedyne, co musiałem zrobić, to utworzyć folder o nazwie „CommonCrypto” w moim katalogu projektu frameworka i utworzyć w nim dwa pliki, jeden o nazwie „cc.h” w następujący sposób:

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

I kolejny o nazwie module.modulemap:

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

(Nie wiem, dlaczego nie można odwoływać się do plików nagłówkowych z obszaru SDKROOT bezpośrednio w pliku modulemap, ale nie mogłem go uruchomić)

Trzecią rzeczą jest znalezienie ustawienia „Importuj ścieżki” i ustawienie na $ (SRCROOT). W rzeczywistości możesz ustawić go na dowolny folder, w którym ma znajdować się folder CommonCrypto, jeśli nie chcesz go na poziomie głównym.

Po tym powinieneś być w stanie korzystać

import CommonCrypto

W dowolnym szybkim pliku i wszystkich typach / funkcjach / itp. są dostępne.

Słowo ostrzeżenia - jeśli Twoja aplikacja korzysta z libCommonCrypto (lub libcoreCrypto) wyjątkowo niezbyt wyrafinowanemu hakerowi wyjątkowo łatwo jest podłączyć debugera do Twojej aplikacji i dowiedzieć się, jakie klucze są przekazywane do tych funkcji.


0

Jeśli masz następujący problem:

ld: nie znaleziono biblioteki dla -lapple_crypto clang: error: komenda linkera nie powiodła się z kodem wyjścia 1 (użyj -v, aby zobaczyć wywołanie)

W Xcode 10, Swift 4.0. CommonCrypto jest częścią frameworka.

Dodaj

 import CommonCrypto

Usunąć

  • Plik lib CommonCrpto z pliku binarnego łącza z bibliotekami z faz kompilacji
  • import CommonCrypto z nagłówka Bridging

To zadziałało dla mnie!


-1

Tak samo stało się ze mną po aktualizacji Xcode. Próbowałem wszystkiego, co mogłem zrobić, takich jak ponowna instalacja kokosów i czyszczenie projektu, ale to nie zadziałało. Teraz zostało rozwiązane po ponownym uruchomieniu systemu.


-13

To jest bardzo proste. Dodaj

#import <CommonCrypto/CommonCrypto.h>

do pliku .h (mostkowy plik nagłówkowy twojego projektu). Jako konwencja możesz nazwać go YourProjectName-Bridging-Header.h.

Następnie przejdź do projektu Ustawienia budowania i poszukaj Swift Compiler - Generowanie kodu. Pod nim dodaj nazwę nagłówka pomostowego do wpisu „Objetive-C Bridging Header”.

Jesteś skończony. Nie wymaga importu w kodzie Swift. Wszelkie publiczne nagłówki Celu C wymienione w tym łączącym pliku nagłówkowym będą widoczne dla Swift.


twoja metoda zwraca błąd: użycie mostkowania nagłówków z celami frameworka nie jest obsługiwane
— gorgi93,

5
@ gorgi93 Nie można użyć mostkującego nagłówka w celu ramowym, jak sugeruje błąd. Niestety jedyną opcją jest umieszczenie go w głównym pliku nagłówkowym frameworka.
— Charles A.

1
Gdybyś miał czerwony tytuł tego wątku, zobaczyłbyś, że facet chce zaimportować bibliotekę CommonCrypto do frameworka Swift. Nie można używać łączących nagłówków w ramach i nie można importować struktury CommonCrypto do nagłówka parasola.
— miken.mkndev
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.