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.

hpique
źródło
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
Mike Weller
źródło
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 .

Stephencelis
źródło
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.

hpique
źródło
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

onmyway133
źródło
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.

mxcl
źródło
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.

Nikita Kukushkin
źródło
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.

jjrscott
źródło
Zobacz odpowiedź dvdblk na ulepszenie, które obejmuje użycie w CocoaPods.
jjrscott,
5

Dla każdego używającego swift 4.2 z Xcode 10 :

Moduł CommonCrypto jest teraz dostarczany przez system, więc możesz go zaimportować bezpośrednio, tak jak każdą inną strukturę systemu.

import CommonCrypto
kubrick G.
źródło
Duplikat odpowiedzi @ mxcl: stackoverflow.com/a/50690346/9988514
Rainer Schwarz
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.

Jacob Jennings
źródło
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.

Rob Napier
źródło
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.

Terence
źródło
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 :)

dvdblk
źródło
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.

Dylan Nicholson
źródło
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!

SKSN
źródło
-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.

Joey
źródło
-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.

Juanjo Conti
źródło
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