Importando CommonCrypto em uma estrutura Swift

184

Como você importa CommonCryptoem uma estrutura Swift para iOS?

Entendo como usar CommonCryptoem um aplicativo Swift: você adiciona #import <CommonCrypto/CommonCrypto.h>ao cabeçalho da ponte. No entanto, as estruturas Swift não suportam pontes de cabeçalho. A documentação diz:

Você pode importar estruturas externas que possuem uma base de código Objective-C pura, uma base de código Swift pura ou uma base de código em idioma misto. O processo para importar uma estrutura externa é o mesmo, seja ela escrita em um único idioma ou contenha arquivos dos dois idiomas. Ao importar uma estrutura externa, verifique se a configuração de criação do Módulo Defines para a estrutura que você está importando está definida como Sim.

Você pode importar uma estrutura para qualquer arquivo Swift dentro de um destino diferente usando a seguinte sintaxe:

import FrameworkName

Infelizmente, a importação CommonCryptonão funciona. Nem adicionar #import <CommonCrypto/CommonCrypto.h>ao cabeçalho do guarda-chuva.

hpique
fonte
CommonCrypto é uma estrutura baseada em C, não uma estrutura de Objective-C.
rmaddy
1
@rmaddy Objective-C é um superconjunto de C. Você está dizendo que não podemos usar o CommonCrypto da Swift?
Hpique
4
@rmaddy Acabei de conseguir que o CommonCrypto funcionasse usando mapas de módulos. Vou polir a solução e publicá-la hoje mais tarde.
Hpique
se você achar conveniente, e o que você procura já estiver implementado, tente CryptoSwift
Marcin
1
A Apple acabou de abrir o CommonCrypto. Talvez possamos colocá-lo em funcionamento se tivermos as fontes.
EYEBALLZ

Respostas:

137

Algo um pouco mais simples e mais robusto é criar um destino Agregado chamado "CommonCryptoModuleMap" com uma fase Executar Script para gerar o mapa do módulo automaticamente e com o caminho Xcode / SDK correto:

insira a descrição da imagem aqui insira a descrição da imagem aqui

A fase Executar Script deve conter este 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

Usar código shell e ${SDKROOT}significa que você não precisa codificar o caminho Xcode.app, que pode variar de sistema para sistema, especialmente se você xcode-selectalternar para uma versão beta ou se estiver construindo em um servidor de IC em que várias versões estão instaladas em locais fora do padrão. Você também não precisa codificar o SDK, portanto isso deve funcionar para iOS, macOS etc. Você também não precisa ter nada no diretório de origem do seu projeto.

Após criar esse destino, faça com que sua biblioteca / estrutura dependa dele com um item de Dependências de Destino:

insira a descrição da imagem aqui

Isso garantirá que o mapa do módulo seja gerado antes da construção da sua estrutura.

Nota para o macOS : se você também oferece suporte macOS, será necessário adicionar macosxà Supported Platformsconfiguração de compilação o novo destino agregado que você acabou de criar, caso contrário, ele não colocará o mapa do módulo na Debugpasta de dados derivados correta com o restante do produtos de estrutura.

insira a descrição da imagem aqui

Em seguida, adicione o diretório pai do mapa do módulo ${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap, à configuração de compilação "Import Paths" na seção Swift ( SWIFT_INCLUDE_PATHS):

insira a descrição da imagem aqui

Lembre-se de adicionar uma $(inherited)linha se você tiver caminhos de pesquisa definidos no nível do projeto ou xcconfig.

É isso aí, agora você deve ser capaz de import CommonCrypto

Atualização para o Xcode 10

O Xcode 10 agora vem com um mapa de módulo CommonCrypto, tornando essa solução desnecessária. Se você deseja dar suporte ao Xcode 9 e 10, faça uma verificação na fase Executar Script para ver se o mapa do módulo existe ou não, por exemplo

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
fonte
8
Esta resposta deve estar no topo. Simples e elegante
Abdullah Saeed
1
Atrasado para o jogo neste jogo - mas esta deve ser a resposta escolhida. É simples e é mais fácil para outros desenvolvedores que trabalham no mesmo projeto ver o requisito.
Fatuous.logic
1
Ótima resposta. Obrigado!
Klaus Busse
1
Se eu fizer isso na minha estrutura., Devo fazer o mesmo nos projetos em que incluo essa estrutura?
Ravi Kiran
2
@IanDundas Atualizei o código acima com uma correção para o problema de recompilação, bem como uma correção para usá-lo no macOS
iwasrobbed
91

Você pode realmente criar uma solução que "simplesmente funcione" (não é necessário copiar um module.modulemap e SWIFT_INCLUDE_PATHSconfigurações para o seu projeto, conforme exigido por outras soluções aqui), mas requer que você crie uma estrutura / módulo fictício que você ' Importar para sua estrutura adequada. Também podemos garantir que ele funciona independentemente da plataforma ( iphoneos, iphonesimulatorou macosx).

  1. Adicione um novo destino de estrutura ao seu projeto e nomeie-o após a biblioteca do sistema, por exemplo , "CommonCrypto". (Você pode excluir o cabeçalho do guarda-chuva, CommonCrypto.h .)

  2. Adicione um novo arquivo de configurações e nomeie-o, por exemplo , "CommonCrypto.xcconfig". (Não marque nenhum dos seus alvos para inclusão.) Preencha-o com o seguinte:

    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. Crie os três arquivos de mapa do módulo referenciado acima e preencha-os com o seguinte:

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

    (Substitua "Xcode.app" por "Xcode-beta.app" se você estiver executando uma versão beta. Substitua 10.11pelo seu atual SDK do sistema operacional se não estiver executando o El Capitan.)

  4. Na guia Informações das configurações do seu projeto, em Configurações , defina as configurações de Depuração e Liberação do CommonCrypto para CommonCrypto (referenciando CommonCrypto.xcconfig ).

  5. Na guia Fases de Construção do seu destino da estrutura , adicione a estrutura CommonCrypto às Dependências de Destino . Além disso, adicione libcommonCrypto.dylib à fase de construção Link Binary With Libraries .

  6. Selecione CommonCrypto.framework em Produtos e verifique se a Associação de Destino do seu wrapper está definida como Opcional .

Agora você deve poder construir, executar e import CommonCryptoem sua estrutura de wrapper.

Por exemplo, veja como o SQLite.swift usa um sqlite3.framework fictício .

stephencelis
fonte
4
Funciona para mim sem o passo (5). Com ele eu recebo um erro de compilação: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
Excelente! Usei isso para criar o github.com/soffes/Crypto , mas não precisei vincular System.framework. Vale ressaltar, você precisa criar uma estrutura de wrapper separada para Mac e iOS se sua estrutura for de plataforma cruzada.
Sam Soffes
32
Como ou onde as pessoas descobrem coisas assim?
Hola
5
Apenas uma observação deixa claro que você precisa selecionar Objective-C como idioma na etapa 1. Isso é facilmente esquecido. Além disso, talvez porque eu não tinha um .dylib, eu precisava para adicionar o .framework na etapa 5.
Teo Sartori
7
isto é horrível. Eu tenho um zoológico de Xcodes, cada um quebrado de maneiras diferentes e ter os caminhos absolutos para os cabeçalhos em todo o lugar é vomitar. Algo vai terrivelmente errado em Cupertino, ou pelo menos com quem está no comando deste modulemap bagunça
Anton Tropashko
82

Encontrei um projeto do GitHub que usa com êxito o CommonCrypto em uma estrutura Swift: SHA256-Swift . Além disso, este artigo sobre o mesmo problema com o sqlite3 foi útil.

Com base no acima, as etapas são:

1) Crie um CommonCryptodiretório dentro do diretório do projeto. Dentro, crie um module.maparquivo. O mapa do módulo nos permitirá usar a biblioteca CommonCrypto como um módulo no Swift. Seu conteúdo é:

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) Em Configurações de compilação, no Swift Compiler - Caminhos de pesquisa , adicione o CommonCryptodiretório a Importar caminhos ( SWIFT_INCLUDE_PATHS).

Configurações de compilação

3) Por fim, importe o CommonCrypto dentro dos seus arquivos Swift como qualquer outro módulo. Por exemplo:

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

Limitações

O uso da estrutura personalizada em outro projeto falha no tempo de compilação com o erro missing required module 'CommonCrypto'. Isso ocorre porque o módulo CommonCrypto não parece estar incluído na estrutura personalizada. Uma solução alternativa é repetir a etapa 2 (configuração Import Paths) no projeto que usa a estrutura.

O mapa do módulo não é independente da plataforma (atualmente aponta para uma plataforma específica, o iOS 8 Simulator). Não sei como fazer o caminho do cabeçalho em relação à plataforma atual.

Atualizações para iOS 8 <= Devemos remover o link da linha "CommonCrypto" , para obter a compilação bem-sucedida.

ATUALIZAÇÃO / EDIÇÃO

Continuei recebendo o seguinte erro de compilação:

ld: biblioteca não encontrada para -lCommonCrypto para arquitetura x86_64 clang: error: erro do linker com o código de saída 1 (use -v para ver a chamada)

A menos que eu tenha removido a linha link "CommonCrypto"do module.maparquivo que criei. Depois que eu removi esta linha, ela construiu ok.

hpique
fonte
30
Nossa, a Apple com certeza quer dificultar as coisas. Mataria os Swifties apenas nos permitir importar arquivos / estruturas sem ter que passar por todas essas BS?
Zaph 5/09/14
4
Isso é irritante, pois a $SDKROOTvariável deve permitir caminhos agnósticos de plataforma, mas não tenho idéia de como chegar a isso no Swift.
Danimal 02/10
2
Para mim, não funcionou até remover o link "CommonCrypto"arquivo module.map.
Teo Sartori
1
Alguém pode confirmar isso trabalhando no Xcode 7.3? Esta solução parou de funcionar para mim após a atualização.
Nikita Kukushkin 23/03
1
Correnction: é trabalhar bem quando eu construir para simulador, mas falha @ ligando quando eu construir para um dispositivo iOS 9.3 com "ld: biblioteca não encontrado para -lCommonCrypto para a arquitetura arm64"
Nikita Kukushkin
50

Esta resposta discute como fazê-lo funcionar dentro de uma estrutura e com Cocoapods e Carthage

Approach abordagem de mapa de módulos

Eu uso modulemapno meu wrapper em torno do CommonCrypto https://github.com/onmyway133/arcane , https://github.com/onmyway133/Reindeer

Para aqueles que estão recebendo header not found, dê uma olhada https://github.com/onmyway133/Arcane/issues/4 ou executexcode-select --install

  • Faça uma pasta CCommonCryptocontendomodule.modulemap

      module CCommonCrypto {
        header "/usr/include/CommonCrypto/CommonCrypto.h"
        export *
      }
  • Vá para Configurações incorporadas -> Importar caminhos

      ${SRCROOT}/Sources/CCommonCrypto

Ap Cocoapods com abordagem modulemap

Header abordagem de cabeçalho público

Ap Cocoapods com abordagem de cabeçalho público

🐝 Postagens relacionadas interessantes

onmyway133
fonte
1
Uau! Para minha surpresa, o caminho do cabeçalho da abordagem superior (criando o arquivo module.modulemap) funcionou muito bem quando os arquivos modulemap anteriormente estavam causando muitos problemas. Eu estava lutando com isso há algum tempo usando um arquivo module.modulemap com um caminho absoluto para /CommonCrypto/CommonCrypto.hdentro Applications/XCode.app/Contents/Developer/Platforms/iPhoneOS...., o que exigia modificação manual para as pessoas que renomearam o XCode. Mudar essa linha para olhar "/usr/include/CommonCrypto/CommonCrypto.h"parece funcionar bem para uma equipe com várias versões do XCode. Muito obrigado!
Natalia
3
Estou criando um pod, defino o SWIFT_INCLUDE_PATHS e preserve_paths. Quando executo pod lib lint, mas a compilação falhou com erro: não existe esse módulo 'CommonCrypto'. Como posso lidar com isso.
Klein Mioke
1
Não está relacionado ao problema, mas eu amo o uso de emoji como balas! F
Fomentia
2
@ onmyway133 O uso do pod de desenvolvimento local funciona se você substituir $(PODS_ROOT)/CommonCryptoSwift/Sources/CCommonCryptopor $(PODS_TARGET_SRCROOT)/Sources/CCommonCrypto. PODS_TARGET_SRCROOTestá definido corretamente para pods locais.
Orkhan Alikhanov
Ótima resposta, salvou minha vida! Graças a um milhão
Hassan Shahbazi
45

Boas notícias! O Swift 4.2 (Xcode 10) finalmente fornece o CommonCrypto!

Basta adicionar import CommonCryptoseu arquivo rápido.

mxcl
fonte
Boas notícias! Você pode adicionar o link à documentação?
Kryštof Matěj
Não tenho um link para a documentação, descobri isso ao tentar compilar um projeto em que eu tinha uma das soluções alternativas aqui com o Xcode 10. Ele reclamou que poderia encontrar dois CommonCryptomódulos, suspeitando que a Apple agora desde que eu removi minha solução alternativa e eis! Era verdade. Eu twitei sobre o assunto e um engenheiro da Apple respondeu confirmando que ele era destinado.
Mxcl
1
A App Store está me mostrando apenas 9.4.7 como uma atualização disponível. Como você conseguiu o Xcode 10?
Hammad Tariq
1
Está na versão beta, como uma pesquisa trivial do Google diria.
Mxcl
1
@SomoyDasGupta yes. Basta remover a importação anterior e compilá-la novamente. Em outras palavras, você não tem que fazer os passos de resposta MikeWeller
COLD ICE
7

AVISO: O iTunesConnect pode rejeitar aplicativos que estão usando esse método.


Um novo membro da minha equipe quebrou acidentalmente a solução dada por uma das principais respostas, então decidi consolidá-la em um pequeno projeto de invólucro chamado CommonCryptoModule . Você pode instalá-lo manualmente ou via Cocoapods:

pod 'CommonCryptoModule', '~> 1.0.2'

Então, tudo que você precisa fazer é importar o módulo para onde você precisa CommonCrypto, assim:

import CommonCryptoModule

Espero que alguém ache isso útil.

Nikita Kukushkin
fonte
Aviso: seu aplicativo será rejeitado se você usar este método!
Segabond 30/01
Sim, também fomos rejeitados, muito esquisitos, porque estávamos carregando sem problemas por vários meses usando esse método.
Nikita Kukushkin
5

Eu acho que tenho uma melhoria no excelente trabalho de Mike Weller.

Adicione uma fase Executar Script antes da Compile Sourcesfase que contém este 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"

Este script constrói uma estrutura bare bones com o module.map no local correto e, em seguida, conta com a pesquisa automática de BUILT_PRODUCTS_DIRestruturas do Xcode .

Vinculei a pasta de inclusão CommonCrypto original como a pasta Headers da estrutura, para que o resultado também funcione para projetos de Objetivo C.

jjrscott
fonte
Veja a resposta do dvdblk para uma melhoria que cobre o uso no CocoaPods.
Jjrscott 03/07
5

Para quem usa o swift 4.2 com o Xcode 10 :

O módulo CommonCrypto agora é fornecido pelo sistema, para que você possa importá-lo diretamente como qualquer outra estrutura do sistema.

import CommonCrypto
kubrick G
fonte
Duplicar de @ mxcl de resposta: stackoverflow.com/a/50690346/9988514
Rainer Schwarz
4

O @mogstad teve a gentileza de envolver a solução @stephencelis em um Cocoapod:

pod 'libCommonCrypto'

Os outros pods disponíveis não funcionaram para mim.

Jacob Jennings
fonte
4

As soluções modulemap podem ser boas e robustas contra as alterações do SDK, mas eu as achei difíceis de usar na prática, e não tão confiáveis ​​quanto eu gostaria ao entregar as coisas a outras pessoas. Para tentar tornar tudo mais infalível, segui um caminho diferente:

Basta copiar os cabeçalhos.

Eu sei frágil. Mas a Apple quase nunca faz alterações significativas no CommonCrypto e estou vivendo o sonho de que elas não sejam alteradas de maneira significativa sem também finalmente fazer do CommonCrypto um cabeçalho modular.

Por "copiar os cabeçalhos", quero dizer "recortar e colar todos os cabeçalhos necessários em um cabeçalho maciço no seu projeto, exatamente como o pré-processador faria". Como um exemplo disso que você pode copiar ou adaptar, consulte RNCryptor.h .

Observe que todos esses arquivos são licenciados sob o APSL 2.0, e essa abordagem mantém intencionalmente os avisos de direitos autorais e de licença. Minha etapa de concatenação é licenciada pelo MIT e aplica-se apenas até o próximo aviso de licença).

Não estou dizendo que essa é uma solução bonita, mas até agora parece ter sido uma solução incrivelmente simples para implementar e dar suporte.

Rob Napier
fonte
Eu achei isso compilar de forma confiável e é muito simples. O aplicativo que usa a estrutura precisa vincular a algo especial ou o CommonCrypto está sempre disponível?
codingFriend1
1
Eu acho que Security.frameworké vinculado automaticamente (já faz um tempo desde que um novo projeto foi iniciado). Se você receber erros, essa é a estrutura a ser vinculada.
Rob Napier
Parece a solução mais simples e funciona muito bem em uma máquina, mas sempre que eu uso a estrutura em outra estrutura ou aplicativo, em outra máquina, recebo o erro 'módulo ausente'.
Richever 4/17
2

Eu sei que esta é uma pergunta antiga. Mas descubro uma maneira alternativa de usar a biblioteca no projeto Swift, que pode ser útil para aqueles que não desejam importar a estrutura introduzida nessas respostas.

No projeto Swift, crie um cabeçalho de ponte Objective-C, crie a categoria NSData (ou classe personalizada para usar a biblioteca) em Objective-C. A única desvantagem seria a necessidade de escrever todo o código de implementação no Objective-C. Por exemplo:

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

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

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

E, em seguida, no cabeçalho de ponte de objetivo-c, adicione este

#import "NSData+NSDataEncryptionExtension.h"

E então, na classe Swift, faça algo semelhante:

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

Funciona como esperado.

Terence
fonte
Isso funciona muito bem e até permite que você mantenha os internos internos ( NSData+NSDataEncryptionExtension.hnão precisa ser público).
Raphael
Mas com qual estrutura do SO devo me conectar, para usar essa coisa? Ao contrário de outros - eu tenho que trabalhar com CommonCrypto em um projeto de Obj-C, e que só breaks no Xcode 9 com MacOS-10,13 SDK
Motti Shneor
@MottiShneor Conecte qualquer sistema operacional a partir do 10.9 ou superior. Estou trabalhando no mesmo ambiente e funciona bem.
Terence
2

Adicionei alguma mágica de cocoapods à resposta de jjrscott, caso você precise usar o CommonCrypto na sua biblioteca de cocoapods.


1) Adicione esta linha ao seu podspec:

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

2) Salve isso na pasta da biblioteca ou onde quiser (no entanto, não se esqueça de alterar a script_phase de acordo ...)

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

Funciona como um encanto :)

dvdblk
fonte
Você pode fornecer uma demonstração ou projeto de estrutura de amostra para o mesmo juntamente com o arquivo de especificação do pod?
Gowtham 17/09
0

Não tenho certeza se algo mudou com o Xcode 9.2, mas agora é muito mais simples conseguir isso. As únicas coisas que eu precisava fazer eram criar uma pasta chamada "CommonCrypto" no meu diretório de projeto de estrutura e criar dois arquivos dentro dele, um chamado "cc.h" da seguinte maneira:

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

E outro chamado module.modulemap:

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

(Não sei por que você não pode fazer referência a arquivos de cabeçalho da área SDKROOT diretamente em um arquivo modulemap, mas não consegui fazê-lo funcionar)

A terceira coisa é encontrar a configuração "Import Paths" e definir como $ (SRCROOT). Na verdade, você pode configurá-lo para qualquer pasta em que deseja que a pasta CommonCrypto esteja, se não desejar no nível raiz.

Depois disso, você poderá usar

import CommonCrypto

Em qualquer arquivo rápido e todos os tipos / funções / etc. Estão disponíveis.

Uma palavra de aviso - se seu aplicativo usa libCommonCrypto (ou libcoreCrypto), é excepcionalmente fácil para um hacker não muito sofisticado anexar um depurador ao aplicativo e descobrir quais chaves estão sendo passadas para essas funções.

Dylan Nicholson
fonte
0

Caso você tenha o problema abaixo:

ld: biblioteca não encontrada para -lapple_crypto clang: erro: o comando do vinculador falhou com o código de saída 1 (use -v para ver a chamada)

No Xcode 10, Swift 4.0. CommonCrypto faz parte da estrutura.

Adicionar

 import CommonCrypto

Remover

  • Arquivo lib CommonCrpto do link binário com bibliotecas das fases de Construção
  • import CommonCrypto do cabeçalho de ponte

Isso funcionou para mim!

SKSN
fonte
-1

Aconteceu o mesmo comigo depois de atualizar o Xcode. Eu tentei tudo o que posso fazer, como reinstalar cocoapods e limpar o projeto, mas não funcionou. Agora foi resolvido após reiniciar o sistema.

Joey
fonte
-13

É muito simples. Adicionar

#import <CommonCrypto/CommonCrypto.h>

para um arquivo .h (o arquivo de cabeçalho de ponte do seu projeto). Como convenção, você pode chamá-lo YourProjectName-Bridging-Header.h.

Em seguida, vá para o seu Build Build Settings e procure Swift Compiler - Code Generation. Abaixo dele, adicione o nome do cabeçalho da ponte à entrada "Objetive-C Bridging Header".

Você Terminou. Nenhuma importação é necessária no seu código Swift. Quaisquer cabeçalhos públicos do Objective-C listados neste arquivo de cabeçalho de ponte serão visíveis para o Swift.

Juanjo Conti
fonte
seu erro método retorna: usando cabeçalhos de ponte com as metas de enquadramento não é suportado
gorgi93
5
@ gorgi93 Não é possível usar um cabeçalho de ponte em um destino da estrutura, como sugere o erro. A única opção é colocá-lo no arquivo principal do framework, infelizmente.
Charles A.
1
Se você realmente tivesse redigido o título desse segmento, teria visto que o cara está querendo importar a biblioteca CommonCrypto para uma estrutura Swift. Você não pode usar ponte de cabeçalhos em estruturas e não pode importar a estrutura CommonCrypto para o cabeçalho guarda-chuva.
Miken.mkndev 11/03/16