Como você importa CommonCrypto
em uma estrutura Swift para iOS?
Entendo como usar CommonCrypto
em 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 CommonCrypto
não funciona. Nem adicionar #import <CommonCrypto/CommonCrypto.h>
ao cabeçalho do guarda-chuva.
fonte
Respostas:
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:
A fase Executar Script deve conter este bash:
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-select
alternar 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:
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 adicionarmacosx
àSupported Platforms
configuraçã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 naDebug
pasta de dados derivados correta com o restante do produtos de estrutura.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
):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
fonte
Você pode realmente criar uma solução que "simplesmente funcione" (não é necessário copiar um module.modulemap e
SWIFT_INCLUDE_PATHS
configuraçõ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
,iphonesimulator
oumacosx
).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 .)
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:
Crie os três arquivos de mapa do módulo referenciado acima e preencha-os com o seguinte:
iphoneos.modulemap
iphonesimulator.modulemap
macosx.modulemap
(Substitua "Xcode.app" por "Xcode-beta.app" se você estiver executando uma versão beta. Substitua
10.11
pelo seu atual SDK do sistema operacional se não estiver executando o El Capitan.)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 ).
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 .
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 CommonCrypto
em sua estrutura de wrapper.Por exemplo, veja como o SQLite.swift usa um sqlite3.framework fictício .
fonte
ld: cannot link directly with /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.2.sdk/usr/lib/system/libcommonCrypto.dylib. Link against the umbrella framework 'System.framework' instead. for architecture x86_64
System.framework
. Vale ressaltar, você precisa criar uma estrutura de wrapper separada para Mac e iOS se sua estrutura for de plataforma cruzada.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
CommonCrypto
diretório dentro do diretório do projeto. Dentro, crie ummodule.map
arquivo. O mapa do módulo nos permitirá usar a biblioteca CommonCrypto como um módulo no Swift. Seu conteúdo é:2) Em Configurações de compilação, no Swift Compiler - Caminhos de pesquisa , adicione o
CommonCrypto
diretório a Importar caminhos (SWIFT_INCLUDE_PATHS
).3) Por fim, importe o CommonCrypto dentro dos seus arquivos Swift como qualquer outro módulo. Por exemplo:
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çãoImport 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:
A menos que eu tenha removido a linha
link "CommonCrypto"
domodule.map
arquivo que criei. Depois que eu removi esta linha, ela construiu ok.fonte
$SDKROOT
variável deve permitir caminhos agnósticos de plataforma, mas não tenho idéia de como chegar a isso no Swift.link "CommonCrypto"
arquivo module.map.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
modulemap
no meu wrapper em torno do CommonCrypto https://github.com/onmyway133/arcane , https://github.com/onmyway133/ReindeerPara 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
CCommonCrypto
contendomodule.modulemap
Vá para Configurações incorporadas -> Importar caminhos
Ap Cocoapods com abordagem modulemap
Aqui está o podspec https://github.com/onmyway133/Arcane/blob/master/Arcane.podspec
O uso
module_map
não funciona, consulte https://github.com/CocoaPods/CocoaPods/issues/5271O uso do Local Development Pod com
path
não funciona, consulte https://github.com/CocoaPods/CocoaPods/issues/809É por isso que você vê que meu Podfile de exemplo https://github.com/onmyway133/CommonCrypto.swift/blob/master/Example/CommonCryptoSwiftDemo/Podfile aponta para o repositório git
Header abordagem de cabeçalho público
Ji é um invólucro em torno da libxml2 e usa a abordagem de cabeçalho público
Ele tem um arquivo de cabeçalho https://github.com/honghaoz/Ji/blob/master/Source/Ji.h com
Target Membership
definido comoPublic
Possui uma lista de arquivos de cabeçalho para libxml2 https://github.com/honghaoz/Ji/tree/master/Source/Ji-libxml
Possui Configurações de Construção -> Caminhos de Pesquisa de Cabeçalho
Possui Configurações de Construção -> Outros Sinalizadores de Linker
Ap Cocoapods com abordagem de cabeçalho público
Dê uma olhada no podspec https://github.com/honghaoz/Ji/blob/master/Ji.podspec
🐝 Postagens relacionadas interessantes
fonte
/CommonCrypto/CommonCrypto.h
dentroApplications/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!pod lib lint
, mas a compilação falhou com erro: não existe esse módulo 'CommonCrypto'. Como posso lidar com isso.$(PODS_ROOT)/CommonCryptoSwift/Sources/CCommonCrypto
por$(PODS_TARGET_SRCROOT)/Sources/CCommonCrypto
.PODS_TARGET_SRCROOT
está definido corretamente para pods locais.Boas notícias! O Swift 4.2 (Xcode 10) finalmente fornece o CommonCrypto!
Basta adicionar
import CommonCrypto
seu arquivo rápido.fonte
CommonCrypto
mó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.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:
Então, tudo que você precisa fazer é importar o módulo para onde você precisa
CommonCrypto
, assim:Espero que alguém ache isso útil.
fonte
Eu acho que tenho uma melhoria no excelente trabalho de Mike Weller.
Adicione uma fase Executar Script antes da
Compile Sources
fase que contém este bash: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_DIR
estruturas 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.
fonte
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.
fonte
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.
fonte
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.
fonte
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.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:
E, em seguida, no cabeçalho de ponte de objetivo-c, adicione este
E então, na classe Swift, faça algo semelhante:
Funciona como esperado.
fonte
NSData+NSDataEncryptionExtension.h
não precisa ser público).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:
2) Salve isso na pasta da biblioteca ou onde quiser (no entanto, não se esqueça de alterar a script_phase de acordo ...)
Funciona como um encanto :)
fonte
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:
E outro chamado module.modulemap:
(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
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.
fonte
Caso você tenha o problema abaixo:
No Xcode 10, Swift 4.0. CommonCrypto faz parte da estrutura.
Adicionar
Remover
import CommonCrypto
do cabeçalho de ponteIsso funcionou para mim!
fonte
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.
fonte
É muito simples. Adicionar
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.
fonte