Какие механизмы хранения данных пользователя вы использовали в iOS-приложениях?

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

Ответ

Выбор механизма хранения зависит от типа, объема и чувствительности данных. Вот основные подходы, которые я применял:

Механизм Назначение Пример использования
UserDefaults Простые настройки, флаги, небольшие примитивные данные. Сохранение выбора темы, логина пользователя, настроек отображения.
Keychain Безопасное хранение конфиденциальных данных (токены, пароли, биометрия). Токены аутентификации (OAuth, JWT), пин-коды.
Core Data Сложные объектные графы, реляционные данные, требующие запросов, сортировки, миграций. Кэширование ленты новостей, локальная база задач, история транзакций.
SQLite / GRDB Прямая работа с реляционной БД, сложные запросы. Приложения с интенсивной работой с табличными данными.
Файловая система (FileManager) Документы, медиафайлы, кэши изображений, пользовательский контент. Сохранение отредактированных фото, загруженных PDF-файлов.

Примеры кода:

1. UserDefaults (простые данные):

// Сохранение
UserDefaults.standard.set("dark", forKey: "appTheme")
// Загрузка
let theme = UserDefaults.standard.string(forKey: "appTheme")

2. Keychain (безопасное хранение): Использование фреймворка KeychainSwift для удобства.

import KeychainSwift
let keychain = KeychainSwift()
// Сохранение токена
keychain.set("eyJhbGciOiJ...", forKey: "userAccessToken")
// Получение токена
let token = keychain.get("userAccessToken")

3. Core Data (структурированные данные):

// Создание и сохранение объекта
let context = persistentContainer.viewContext
let newItem = Item(context: context)
newItem.timestamp = Date()
try? context.save()
// Fetch Request
let request: NSFetchRequest<Item> = Item.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "timestamp", ascending: false)]
let items = try? context.fetch(request)

Критерии выбора: Всегда начинаю с самого простого подхода (UserDefaults) и перехожу к более сложным (Core Data) только при необходимости, строго разделяя данные по уровню безопасности.