No desenvolvimento para os ecossistemas Apple (iOS, macOS, tvOS e watchOS), o armazenamento seguro de dados sensíveis como senhas, tokens de API e chaves de criptografia é fundamental. O KeychainSwift é uma biblioteca de código aberto que abstrai a complexidade da API nativa do Keychain, oferecendo uma interface limpa e intuitiva em Swift para gerenciar esses dados confidenciais.
Configuração Inicial
Existem múltiplas formas de integrar o KeychainSwift ao seu projeto.
Via Swift Package Manager
Este é o método recomendado. No Xcode, navegue até File > Add Packages e insira o URL do repositório: https://github.com/evgenyneu/keychain-swift.git. Selecione a versão desejada e adicione ao projeto.
Via CocoaPods
Adicione a seguinte linha ao seu Podfile:
pod 'KeychainSwift', '~> 24.0'
Execute pod install no terminal.
Via Carthage
Inclua no seu Cartfile:
github "evgenyneu/keychain-swift" ~> 24.0'
Execute carthage update.
Utilização Básica
Instancie KeychainSwift para realizar operações CRUD.
Salvnado e Recuperando uma String
Ideal para dados de texto como senhas e tokens.
let meuArmazenamento = KeychainSwift()
meuArmazenamento.salvar("SenhaForte123", paraChave: "credencial_usuario")
let minhaSenha = meuArmazenamento.recuperarString(paraChave: "credencial_usuario")
Salvando e Recuperando um Booleano
Útil para armazenar preferências de estado do usuário.
let prefsSeguranca = KeychainSwift()
prefsSeguranca.salvar(true, paraChave: "autenticacao_biométrica")
let biometriaAtiva = prefsSeguranca.recuperarBool(paraChave: "autenticacao_biométrica")
Salvando e Recuperando Dados Binários
Para objetos complexos, serialize-os para Data primeiro.
let armazenamento = KeychainSwift()
let dadosPerfil = try JSONEncoder().encode(perfilUsuario)
armazenamento.salvar(dadosPerfil, paraChave: "perfil_serializado")
let dadosRecuperados = armazenamento.recuperarDados(paraChave: "perfil_serializado")
Gerenciamento de Itens
Para excluir um item específico:
armazenamento.apagar(paraChave: "minhaChave")
Para limpar todos os itens do Keychain da aplicação (não disponível em macOS):
armazenamento.limparTudo()
Configurações Avançadas de Segurança
Definindo o Nível de Acesso
O parâmetro comAcesso controla quando os dados podem ser acessados. O padrão .acessivelQuandoDesbloqueado oferece alta segurança. Para acesso em segundo plano, .acessivelAposPrimeiroDesbloqueio é menos restritivo.
armazenamento.salvar("SegredoTotal", paraChave: "dado_confidencial",
comAcesso: .acessivelQuandoDesbloqueado)
Sincronização entre Dispositivos via iCloud
Habilite a sincronização para compartilhar dados entre dispositivos do mesmo usuário com o iCloud Keychain ativado.
// No dispositivo A
let syncArmazenamento = KeychainSwift()
syncArmazenamento.sincronizavel = true
syncArmazenamento.salvar("DadoSincronizado", paraChave: "chave_compartilhada")
// No dispositivo B
let outroDispositivo = KeychainSwift()
outroDispositivo.sincronizavel = true
let dadoSync = outroDispositivo.recuperarString(paraChave: "chave_compartilhada")
Compartilhamento entre Aplicativos
Para compartilhar itens entre apps no mesmo dispositivo, configure um grupo de Keychain nas Capacidades do projeto (Keychain Sharing).
let compartilhado = KeychainSwift()
compartilhado.grupoAcesso = "SEU_TEAM_ID.com.seuapp.GrupoKeychain"
compartilhado.salvar("DadoParaAppParceiro", paraChave: "dado_compartilhado")
Tratamento de Erros e Depuração
Verifique o sucesso das operações analisando o retorno das funções salvar, apagar e limparTudo.
if !armazenamento.salvar("teste", paraChave: "chave_teste") {
print("Falha ao salvar. Código de erro: \(armazenamento.ultimoCodigoResultado)")
}
O atributo ultimoCodigoResultado fornece detalhes específicos sobre o último erro ocorrido.
Estrutura do Projeto e Recursos
O código fonte está organizado de forma clara:
- Sources/: Código principle (
KeychainSwift.swift, opções de acesso, constantes). - Tests/: Suite completa de testes unitários.
- Demo/: Aplicativo de exemplo para iOS.
A biblioteca é compatível com Swift 5.0+ e suporta iOS 7.0+, macOS 10.9+, tvOS 9.0+ e watchOS 2.0+.
Soluções para Problemas Comuns
Valor nil Inesperado: Um problema intermitente pode ocorrer, possivelmente relacionado a restrições de acesso. Verifique as configurações de acesso, o espaço disponível no Keychain e considere implementar uma lógica de repetição.
Isolamento em Testes Unitários: Use um prefixo de chave durante a inicialização para evitar poluição dos dados de produção.
let testeStorage = KeychainSwift(prefixoChave: "teste_unit_")
testeStorage.salvar("valor_teste", paraChave: "dado_experimento")
// A chave real no Keychain será "teste_unit_dado_experimento"
Obtenção de Referência: Para cenários como configuração de VPN (NEVPNProtocol), onde uma referência ao dado é necessária, use comoReferencia: true.
let refArmazenamento = KeychainSwift()
refArmazenamento.salvar(configVPN, paraChave: "vpn_config")
let referência = refArmazenamento.recuperarDados(paraChave: "vpn_config", comoReferencia: true)
Adotar a biblioteca KeychainSwift simplifica drasticamente o código relacionado à segurança de dados, permitindo que os desenvolvedores foquem na lógica de negócios da aplicação.