В iOS существует несколько основных способов сохранения данных между запусками приложения. Вот детальный разбор каждого из них:
1. UserDefaults
// Запись
UserDefaults.standard.set("value", forKey: "key")
// Чтение
let value = UserDefaults.standard.string(forKey: "key")
- Назначение: Хранение простых типов данных (String, Int, Bool и т.д.)
- Особенности:
- Работает как словарь ключ-значение
- Не подходит для больших объемов данных
- Автоматически синхронизируется между девайсами через iCloud (при включении)
- Лучше всего подходит для настроек приложения
2. Файловая система
// Запись в файл
let data = Data()
try data.write(to: fileURL)
// Чтение из файла
let data = try Data(contentsOf: fileURL)
- Основные подходы:
- FileManager: Работа с файлами и директориями
- Прямая запись данных: Для бинарных данных, изображений и т.д.
- Использование:
- Documents: Пользовательские данные
- Caches: Временные файлы
- tmp: Временные файлы (удаляются при перезапуске)
3. Keychain
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "userToken",
kSecValueData as String: token.data(using: .utf8)!
]
SecItemAdd(query as CFDictionary, nil)
- Назначение: Безопасное хранение чувствительных данных
- Особенности:
- Сохраняется даже после удаления приложения
- Шифрование на уровне системы
- Сложный API (часто используют обертки типа KeychainAccess)
- Что хранят: Пароли, токены, платежные данные
4. Core Data
// Создание объекта
let newUser = User(context: viewContext)
newUser.name = "John"
// Сохранение
try viewContext.save()
- Назначение: Объектно-ориентированное хранение сложных данных
- Особенности:
- SQLite "под капотом" (может использовать другие хранилища)
- Включает валидацию, миграции, отношения между объектами
- Требует настройки Data Model
- Работа через NSManagedObjectContext
5. SQLite
// Пример с GRDB
try dbQueue.write { db in
try Player(name: "Alice", score: 1000).insert(db)
}
- Популярные библиотеки:
- Преимущества:
- Полный контроль над запросами
- Высокая производительность
- Подходит для сложных запросов
6. Realm
let realm = try! Realm()
try! realm.write {
realm.add(Person(value: ["name": "John"]))
}
- Особенности:
- Альтернатива Core Data
- Собственный движок базы данных
- Проще в использовании чем Core Data
- Поддержка live-объектов
7. Codable + Архивация
// Сохранение
let data = try JSONEncoder().encode(object)
try data.write(to: fileURL)
// Загрузка
let data = try Data(contentsOf: fileURL)
let object = try JSONDecoder().decode(MyType.self, from: data)
- Идеально для:
- Сохранения сложных структур
- Обмена данными с сервером
- Локальных кэшей API-ответов
8. CloudKit
let record = CKRecord(recordType: "User")
record["name"] = "John"
CKContainer.default().privateCloudDatabase.save(record) { ... }
- Назначение: Синхронизация данных между устройствами через iCloud
- Особенности:
- Бесплатное решение от Apple
- Автоматическая синхронизация
- Работает даже когда приложение выключено
9. Firebase Realtime Database
ref.child("users").child(userId).setValue(["username": name])
- Плюсы:
- Облачное хранение
- Реальное время обновлений
- Кроссплатформенность
Сравнительная таблица
Метод | Объем данных | Сложность | Безопасность | Оффлайн доступ |
UserDefaults | Малый | Низкая | Низкая | Да |
Файловая система | Любой | Средняя | Зависит | Да |
Keychain | Малый | Высокая | Высокая | Да |
Core Data | Средний-большой | Высокая | Средняя | Да |
Realm | Средний-большой | Средняя | Средняя | Да |
CloudKit | Любой | Высокая | Высокая | Нет (требует сеть) |
Резюмируем
Выбор метода хранения данных зависит от:
- Типа данных: Простые настройки → UserDefaults, чувствительные данные → Keychain
- Объема: Маленькие объемы → UserDefaults, большие → Core Data/Realm
- Требований к безопасности: Keychain для критически важных данных
- Необходимости синхронизации: CloudKit или Firebase для мультидевайс синхронизации
- Сложности данных: Структурированные данные → Core Data/Realm, документы → файловая система
Для большинства приложений используется комбинация нескольких методов (например: UserDefaults для настроек + Core Data для основных данных + Keychain для токенов).