Qual é a diferença entre Keychain e User Defaults?
sobes.tech IA
Resposta da IA
UserDefaults é usado para armazenar pequenos dados não confidenciais, como configurações do utilizador ou estado da aplicação. Os dados são armazenados como pares chave-valor num ficheiro .plist e estão acessíveis a todas as partes da aplicação. UserDefaults não cifra os dados e não é adequado para armazenar informações críticas.
Keychain é usado para armazenar de forma segura dados confidenciais, como passwords, certificados, tokens e outras informações sensíveis. Os dados são cifrados e armazenados num armazenamento especializado, acessível apenas à aplicação que os gravou. Keychain é suportado ao nível do sistema operativo e fornece um alto grau de proteção de dados.
Diferenças principais:
| Característica | UserDefaults | Keychain |
|---|---|---|
| Propósito | Armazenamento de configurações não confidenciais | Armazenamento de dados confidenciais (passwords, tokens) |
| Segurança | Não possui cifragem incorporada | Os dados são cifrados |
| Acesso | Disponível para todas as partes da aplicação | Disponível apenas para a aplicação que os gravou |
| Volume de dados | Adequado para pequenos volumes de dados | Adequado para pequenos volumes de dados confidenciais |
| Implementação | API simples, armazenamento em ficheiro .plist |
API mais complexa, armazenamento no armazenamento do sistema |
Exemplo de uso de UserDefaults:
// Guardar valor
UserDefaults.standard.set("dark", forKey: "theme")
// Obter valor
let theme = UserDefaults.standard.string(forKey: "theme")
Exemplo de uso de Keychain (requer trabalhar com a API SecItem ou wrappers):
// Exemplo de adição de password (simplificado, requer tratamento de erros e parâmetros adicionais)
let password = "mySecretPassword".data(using: .utf8)!
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "myAccount",
kSecValueData as String: password
]
let statusAdd = SecItemAdd(query as CFDictionary, nil)
// Tratamento do estado
// Exemplo de obtenção de password (simplificado, requer tratamento de erros)
let queryGet: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "myAccount",
kSecReturnData as String: kCFBooleanTrue!,
kSecMatchLimit as String: kSecMatchLimitOne
]
var item: CFTypeRef?
let statusGet = SecItemCopyMatching(queryGet as CFDictionary, &item)
if statusGet == errSecSuccess {
let retrievedData = item as! Data
let retrievedPassword = String(data: retrievedData, encoding: .utf8)
// Utilização da password
}