SecItemAdd sempre retorna o erro -34018 no Xcode 8 no simulador iOS 10

103

Atualização : esse problema foi corrigido no Xcode 8.2. As chaves funcionam no simulador sem permitir o compartilhamento das chaves.

Por que sempre recebo o erro -34018 ao chamar a SecItemAddfunção no simulador Xcode 8 / iOS 10 ?

Passos para reproduzir

Crie um novo projeto de aplicativo iOS de página única no Xcode 8. Execute o código a seguir viewDidLoad(ou abra este projeto Xcode).

let itemKey = "My key"
let itemValue = "My secretive bee 🐝"

// Remove from Keychain
// ----------------

let queryDelete: [String: AnyObject] = [
  kSecClass as String: kSecClassGenericPassword,
  kSecAttrAccount as String: itemKey as AnyObject
]

let resultCodeDelete = SecItemDelete(queryDelete as CFDictionary)

if resultCodeDelete != noErr {
  print("Error deleting from Keychain: \(resultCodeDelete)")
}


// Add to keychain
// ----------------

guard let valueData = itemValue.data(using: String.Encoding.utf8) else {
  print("🐣🐣🐣🐣🐣🐣🐣🐣🐣🐣 Error saving text to Keychain")
  return
}

let queryAdd: [String: AnyObject] = [
  kSecClass as String: kSecClassGenericPassword,
  kSecAttrAccount as String: itemKey as AnyObject,
  kSecValueData as String: valueData as AnyObject,
  kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
]

let resultCode = SecItemAdd(queryAdd as CFDictionary, nil)

if resultCode != noErr {
  print("🐝🐝🐝🐝🐝🐝🐝🐝🐝 Error saving to Keychain: \(resultCode).")
} else {
  print("🍀🍀🍀🍀🍀🍀🍀🍀🍀 Saved to keychain successfully.")
}

resultados esperados

O item é adicionado ao Keychain.

Resultados reais

Função SecItemAdd retorna o seguinte código de erro: -34018.

Versão

Xcode versão 8.1 (8B62), macOS Sierra 10.12.1.

Configuração

Sempre ocorre no Xcode 8 desde o Beta 2 ao testar em um simulador iOS 10.

NÃO ocorre no Xcode 8 ao testar em um simulador iOS 9.3.

Demo

https://dl.dropboxusercontent.com/u/11143285/2016/07/KeychainBugDemo.zip

Referências

Radar: https://openradar.appspot.com/27422249

Fóruns de desenvolvedores da Apple: https://forums.developer.apple.com/message/179846

Esse problema é diferente da postagem a seguir porque ocorre de forma consistente no Xcode 8. SecItemAdd e SecItemCopyMatching retorna o código de erro -34018 (errSecMissingEntitlement)

Evgenii
fonte
8
Isso ainda parece ser um problema no Xcode 8 GM. É bom ver que a Apple ainda está no topo de seu jogo ...
Nicholas Harlen
1
mesmo para mim, ainda este erro
Kostiantyn Koval
Estou realmente cavando seus logs de console :-)
Nicolas Miari
O problema foi corrigido no Xcode 8.2, mas está de volta no Xcode 9.0!
Adil Hussain

Respostas:

183

Consegui contornar isso em meu aplicativo adicionando grupos de acesso às chaves ao arquivo Direitos. Eu ativei o switch Keychain Sharing na seção Capacidades em seu aplicativo de teste, e ele está funcionando para mim também.

Captura de tela de como ligar o interruptor

Item a ser adicionado aos direitos:

<key>keychain-access-groups</key>
<array>
    <string>$(AppIdentifierPrefix)com.evgenii.KeychainBugDemo</string>
</array>

Eu tentei isso apenas no macOS Sierra (10.12), então não tenho certeza se funcionará para você no 10.11.5.

Deyton
fonte
O mesmo aqui, só que estou usando o Xcode 8 beta 5 atualmente (com simulador iOS 10. O problema não apareceu com o beta anterior. Também não acontece ao testar com 8b5 em um iPhone iOS 9 real). Percebi que as notificações push em recursos precisavam de conserto (ou seja, pressionando o botão) e também ativei o compartilhamento de chaves, infelizmente ao mesmo tempo. Então, o aplicativo não obteve mais o erro. Depois de desativar o Compartilhamento de Chaves novamente, ele ainda funciona!
Stefan
2
Eu uso o chaveiro como um alvo de teste e ele falha - como eu contornaria isso? (Como não há recursos nos alvos de teste)
Sam Jarman
1
@SamJarman Eu também tive esse problema. Acabei de entrar nas configurações de compilação para o destino de teste e desativei o campo de direitos. Funcionou bem depois disso.
Jordan Bondo
3
Esta solução funciona bem para App Targets. Infelizmente, estou trabalhando em um framework Swift que usa KeychainSwift que não é mais compilado devido ao erro. Em um destino de estrutura, não posso adicionar um arquivo de direitos afaik. Alguém conhece uma solução alternativa para este caso?
Jan Nash
5
@JanNash, aqui está como eu consegui fazer o teste funcionar evgenii.com/blog/testing-a-keychain-library-in-xcode
Evgenii
17

No Xcode 8.1 GM Release Notes, a Apple reconheceu o problema e sugeriu uma solução mais limpa:

As APIs de Keychain podem não funcionar no Simulador se seu arquivo de direitos não contiver um valor para o direito de identificador de aplicativo. (28338972) Solução alternativa: inclua uma configuração de construção definida pelo usuário em seu destino denominado ENTITLEMENTS_REQUIRED e configure o valor como YES. Isso fará com que o Xcode insira automaticamente uma autorização de identificador de aplicativo ao compilar.

Observe que, pelo que tentei, ele só funciona no Xcode 8.1. Embora o texto possa induzir você a uma configuração de construção, o que você precisa fazer é adicionar isso às suas Variáveis ​​de Ambiente, em seu esquema.

insira a descrição da imagem aqui

O Xcode 8.2 resolverá isso:

Resolvido no Xcode 8.2 beta - IDE Keychain APIs funcionam corretamente no Simulador. (28338972)

Tiago Almeida
fonte
1
@Tiago Esta solução alternativa das notas de lançamento ainda está funcionando para você no Xcode 8.1 no simulador iOS 10.1? Tentei adicionar essa configuração (tanto como uma configuração definida pelo usuário no destino e como uma variável de ambiente no esquema) e ainda obtenho o valor de retorno -34018 ao executar nos simuladores iOS 10.1.
guywithmazda
3
@guywithmazda, mesmo aqui. Ainda obtendo -34018 e tentei criar configurações e variáveis ​​de ambiente.
keithbhunter
Não funciona para mim, nem em configurações de compilação, nem como variável de ambiente de um esquema no Xcode 8.1 (8B62) no Sierra. Estou esquecendo de algo?
Evgenii
4
Estou usando o Xcode 8.2.1 e esse problema ainda pode ser reproduzido. Além disso, minha pergunta é se eu não tenho um aplicativo host e estou criando o destino do Framework, como resolver esse problema?
DShah
2
Esse problema ainda afeta os testes de unidade para destinos do Framework porque, neste caso, seria o stub do host de teste que precisa de direitos. Estamos cientes do problema, mas se for um bloqueador para você, envie um bug duplicado.
russbishop
10

Isso pode acontecer se você tiver um destino de teste que não tenha um aplicativo host. Consertar

  1. adicionar um aplicativo host fictício: insira a descrição da imagem aqui

  2. Ative a assinatura automática de código e adicione uma equipe:

insira a descrição da imagem aqui

  1. Ativar compartilhamento de chaves em recursos

insira a descrição da imagem aqui

Mustafa
fonte
5

Recebi um erro ao assinar com o e-mail, criar um novo usuário ou ao sair usando o firebase.

O erro foi:

código de domínio de erro firauth 17995

Eu ativei o switch Keychain Sharing na seção Capacidades em seu aplicativo de teste, e ele está funcionando para mim também.

kavita patel
fonte
4

Eu estava procurando por uma solução que não usasse o compartilhamento de chaves, já que esse não era o recurso que eu estava procurando. O fórum de desenvolvedores parece ter uma boa solução para o EvergreenCoder, que você pode limitar em escopo apenas ao simulador iOS 10 (já que este parece ser o único simulador afetado). Da postagem:

O problema parece ser que deve haver pelo menos um direito para que o Xcode adicione corretamente o enttilement "identificador de aplicativo" ao aplicativo construído. É por isso que o compartilhamento de chaveiro parece ser uma solução, mas é apenas indiretamente: qualquer outro direito parece funcionar bem.

Você pode criar um .plistassim:

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE plist PUBLIC "-/  
<plist version="1.0">  
    <dict>  
        <key>get-task-allow</key>  
        <true/>  
    </dict>  
</plist>

e forneça um caminho para esse arquivo em Build Settings em

Code Signing->Debug->Simulater iOS 10 SDK->($SRCROOT)/your-path-to-file

Conforme declarado na postagem, este direito apenas permite que o depurador seja anexado.

ahtierney
fonte
1

Tive um problema semelhante, embora recebesse o erro -34018 ao tentar executar no dispositivo. Estou usando o XCode 8.1 no Sierra com iOS 10.1. Trabalho em equipe e de repente tive esse problema quando mudamos para "Gerenciar automaticamente a assinatura" nas configurações do projeto. Quando eu desligo isso e seleciono manualmente meu perfil, tudo funciona bem. Acabei tendo que excluir meu certificado de desenvolvedor do meu chaveiro e selecionar novamente "Gerenciar assinatura automaticamente". Na próxima compilação, ele gerou um novo certificado de assinatura para mim e tudo funciona bem agora. Ainda não tenho certeza do que causou o problema, pois o outro certificado funcionou bem quando selecionado manualmente, mas não quando gerenciado pelo XCode. Espero que isso ajude a parar uma dor de cabeça de horas para outra pessoa.

johnrechd
fonte
1

Consegui resolver esse problema no Xcode 11 sem nenhum ajuste de autorização.

Simplesmente adicionei um novo destino de aplicativo ao projeto do meu framework chamado MyFrameworkTestsHostApp.

Em seguida, selecionei o destino MyFrameworkTests e escolhi seu aplicativo host como MyFrameworkTestsHostApp.

Adam Johns
fonte
0

Funciona depois de habilitar o compartilhamento de chaves nos recursos.

Vid
fonte
0

Há três etapas a serem seguidas para resolver esse problema rapidamente.

  1. Ative o compartilhamento de chaves em seus recursos de projeto.
  2. Selecione Provisionamento automático com um perfil
  3. Certifique-se de que sua opção de direito personalizado esteja definida como Entitlement.plist.

Isso vai fazer a mágica

Uchenna Nnodim
fonte