Ответ
Keychain — это безопасное зашифрованное хранилище для конфиденциальных данных. UserDefaults — это простое хранилище типа «ключ-значение» для нефункциональных настроек.
| Характеристика | Keychain | UserDefaults |
|---|---|---|
| Назначение | Пароли, токены доступа, ключи шифрования, платежные данные. | Настройки приложения, флаги, прочая некритичная информация. |
| Безопасность | Данные шифруются на уровне системы. Защищены аппаратным Security Enclave (на поддерживаемых устройствах). | Данные хранятся в виде plain-text plist-файла в sandbox приложения. Легко извлекаются при взломе устройства. |
| Стойкость | Сохраняется между переустановками приложения. | Удаляется вместе с приложением. |
| Производительность | Медленнее из-за шифрования и системных вызовов. | Очень быстро, обращение к in-memory кэшу. |
| API | Низкоуровневый C-API (Security.framework) или обертки (например, из SwiftKeychainWrapper). |
Простой Swift/Obj-C API. |
Пример сохранения токена в Keychain:
import Security
let token = "user_auth_token"
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "com.yourapp.authToken",
kSecValueData as String: token.data(using: .utf8)!
]
// Удаляем старую запись, если есть
SecItemDelete(query as CFDictionary)
// Добавляем новую
let status = SecItemAdd(query as CFDictionary, nil)
guard status == errSecSuccess else { /* Обработка ошибки */ }
Пример работы с UserDefaults:
// Запись
UserDefaults.standard.set("dark", forKey: "appTheme")
// Чтение
let theme = UserDefaults.standard.string(forKey: "appTheme")
Правило: Для любых данных, компрометация которых нанесет ущерб пользователю, используйте Keychain. Для всего остального — UserDefaults.