В чем разница между Keychain и UserDefaults в iOS?

«В чем разница между Keychain и UserDefaults в iOS?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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.