Sobes.tech
Junior

What is the difference between Keychain and User Defaults?

sobes.tech AI

Answer from AI

UserDefaults is used for storing small, non-confidential data such as user settings or app state. Data is stored as key-value pairs in a .plist file and is accessible to all parts of the app. UserDefaults does not encrypt data and is not suitable for storing critical information.

Keychain is used for securely storing confidential data such as passwords, certificates, tokens, and other sensitive information. Data is encrypted and stored in a specialized storage accessible only to the app that saved it. Keychain is supported at the OS level and provides a high level of data protection.

Key differences:

Characteristic UserDefaults Keychain
Purpose Storage of non-confidential settings Storage of confidential data (passwords, tokens)
Security No built-in encryption Data is encrypted
Access Accessible to all parts of the app Accessible only to the app that saved it
Data volume Suitable for small amounts of data Suitable for small amounts of confidential data
Implementation Simple API, stored in a .plist file More complex API, stored in system storage

Example of using UserDefaults:

// Saving a value
UserDefaults.standard.set("dark", forKey: "theme")

// Retrieving a value
let theme = UserDefaults.standard.string(forKey: "theme")

Example of using Keychain (requires working with SecItem API or wrappers):

// Example of adding a password (simplified, requires error handling and additional parameters)
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)
// Handle status

// Example of retrieving a password (simplified, requires error handling)
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)
    // Use the password
}
What is the difference between Keychain and User… - sobes.tech