Что такое UserDefaults в iOS и для каких задач он предназначен?

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

Ответ

UserDefaults — это простой интерфейс для постоянного key-value хранилища, предназначенный для сохранения небольших объемов данных между запусками приложения. Под капотом данные сохраняются в property list (plist-файл).

Основное назначение: Хранение пользовательских настроек и простых состояний приложения (например, включен ли темный режим, имя пользователя, дата последнего запуска).

Базовый пример использования:

// Запись данных
UserDefaults.standard.set("Алексей", forKey: "userName")
UserDefaults.standard.set(25, forKey: "userAge")
UserDefaults.standard.set(true, forKey: "isOnboardingCompleted")

// Чтение данных
let userName = UserDefaults.standard.string(forKey: "userName") // "Алексей"
let userAge = UserDefaults.standard.integer(forKey: "userAge") // 25
let isCompleted = UserDefaults.standard.bool(forKey: "isOnboardingCompleted") // true

Лучшие практики и организация:

// 1. Используйте enum для ключей, чтобы избежать опечаток.
extension UserDefaults {
    enum Keys {
        static let userName = "userName"
        static let userAge = "userAge"
        static let isOnboardingCompleted = "isOnboardingCompleted"
    }
}
UserDefaults.standard.set("Алексей", forKey: UserDefaults.Keys.userName)

// 2. Используйте property wrapper для типобезопасного доступа.
@propertyWrapper
struct UserDefault<T> {
    let key: String
    let defaultValue: T
    var wrappedValue: T {
        get { UserDefaults.standard.object(forKey: key) as? T ?? defaultValue }
        set { UserDefaults.standard.set(newValue, forKey: key) }
    }
}

struct Settings {
    @UserDefault(key: UserDefaults.Keys.userName, defaultValue: "Гость")
    static var userName: String
    @UserDefault(key: UserDefaults.Keys.isOnboardingCompleted, defaultValue: false)
    static var isOnboardingCompleted: Bool
}

// Теперь доступ типобезопасный и удобный:
Settings.userName = "Мария"
print(Settings.isOnboardingCompleted)

Важные ограничения и предостережения:

  • Не для конфиденциальных данных: Пароли, токены, платежная информация НЕ ДОЛЖНЫ храниться в UserDefaults, так как файл не шифруется. Для этого используйте Keychain Services.
  • Не для больших данных: UserDefaults не предназначен для хранения изображений, больших массивов или сложных графов объектов. Используйте для этого файловую систему, базы данных (Core Data, Realm) или другие специализированные хранилища.
  • Производительность: Частая запись большого объема данных может негативно сказаться на производительности.
  • Синхронизация: Значения, сохраненные в UserDefaults.standard, доступны только в пределах одного приложения. Для обмена данными с App Extensions или между приложениями используйте UserDefaults(suiteName:) с общим App Group.

Итог: UserDefaults — это правильный и простой выбор для хранения настроек и легковесных пользовательских данных, но важно понимать границы его применения.