Как и где хранить настройки пользователя в iOS?

Ответ

UserDefaults — стандартный и рекомендуемый способ для хранения простых настроек пользователя (логические флаги, строки, числа, даты, небольшие массивы).

Преимущества:

  • Простой API.
  • Автоматически сохраняется между запусками приложения.
  • Поддерживает синхронизацию через iCloud (с помощью NSUbiquitousKeyValueStore).

Базовый пример:

// Сохранение настроек
UserDefaults.standard.set(true, forKey: "isDarkModeEnabled")
UserDefaults.standard.set("John", forKey: "userName")

// Чтение настроек
let isDarkMode = UserDefaults.standard.bool(forKey: "isDarkModeEnabled")
let name = UserDefaults.standard.string(forKey: "userName") ?? "Guest"

Для структурированных настроек используйте Codable:

struct AppSettings: Codable {
    var theme: String
    var notificationsEnabled: Bool
    var refreshRate: Int
}

// Сохранение структуры
var settings = AppSettings(theme: "dark", notificationsEnabled: true, refreshRate: 30)

let encoder = JSONEncoder()
if let encoded = try? encoder.encode(settings) {
    UserDefaults.standard.set(encoded, forKey: "appSettings")
}

// Загрузка структуры
if let savedData = UserDefaults.standard.data(forKey: "appSettings") {
    let decoder = JSONDecoder()
    if let loadedSettings = try? decoder.decode(AppSettings.self, from: savedData) {
        settings = loadedSettings
    }
}

Когда НЕ использовать UserDefaults:

  • Большие данные (изображения, большие массивы) — используйте файловую систему.
  • Чувствительная информация (пароли, токены) — используйте Keychain.
  • Сложные реляционные данные — используйте Core Data или другую базу данных.

Best Practice: Определите константы для ключей, чтобы избежать опечаток:

enum UserDefaultsKeys {
    static let isDarkModeEnabled = "isDarkModeEnabled"
    static let appSettings = "appSettings"
}

Ответ 18+ 🔞

А, ну вот, смотри, смотри! Опять про эту вашу стандартную помойку для настроек заговорили — UserDefaults. Ну, типа, классика жанра, да? Для всякой хуйни типа включен ли тёмный режим, как зовут юзверя или сколько раз в день он хочет получать пуш-уведомления о том, что он лох.

Почему все его тащат?

  • API — проще некуда, в рот меня чих-пых. Сел и написал.
  • Само всё сохраняется между запусками. Закрыл приложение, включил — а твои настройки на месте, как ни в чём не бывало.
  • Через iCloud можно синхронизировать (это уже NSUbiquitousKeyValueStore, но суть та же).

Смотри, как просто, блядь:

// Запихнули настройки
UserDefaults.standard.set(true, forKey: "isDarkModeEnabled")
UserDefaults.standard.set("John", forKey: "userName")

// Достали обратно
let isDarkMode = UserDefaults.standard.bool(forKey: "isDarkModeEnabled")
let name = UserDefaults.standard.string(forKey: "userName") ?? "Guest"

А если настроек овердохуища и они в кучке? Используй Codable, не будь мудаком!

struct AppSettings: Codable {
    var theme: String
    var notificationsEnabled: Bool
    var refreshRate: Int
}

// Упаковал всю структуру разом
var settings = AppSettings(theme: "dark", notificationsEnabled: true, refreshRate: 30)

let encoder = JSONEncoder()
if let encoded = try? encoder.encode(settings) {
    UserDefaults.standard.set(encoded, forKey: "appSettings")
}

// Распаковал обратно
if let savedData = UserDefaults.standard.data(forKey: "appSettings") {
    let decoder = JSONDecoder()
    if let loadedSettings = try? decoder.decode(AppSettings.self, from: savedData) {
        settings = loadedSettings
    }
}

Но слушай сюда, ёпта! Это не волшебный унитаз, куда можно скидывать всё подряд.

  • Большие данные (картинки, гигабайтные массивы) — иди в файловую систему, нахуй.
  • Пароли, токены, данные кредиток — ты что, охуел? Только Keychain, блядь! Иначе тебя взломают, и ты останешься без штанов.
  • Сложные связи между данными — тут уже Core Data или какая-нибудь другая БД. UserDefaults для этого — как молотком гвозди в монитор забивать.

И главный лайфхак, чтобы не облажаться: Сделай константы для ключей, а то опечатаешься где-нибудь в "isDarkModeEnebled" и будешь потом три часа искать, почему тёмная тема не работает. Пиздец.

enum UserDefaultsKeys {
    static let isDarkModeEnabled = "isDarkModeEnabled"
    static let appSettings = "appSettings"
}

Вот и вся магия, ничего сложного. Главное — не пытайся запихнуть туда слона, а то получишь перформанс на уровне улитки в смоле.