← Назад к вопросам

Какие знаешь способы сохранения локальных данных в iOS?

1.3 Junior🔥 201 комментариев
#Хранение данных

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Способы сохранения локальных данных в iOS

В iOS существует несколько основных подходов для локального хранения данных, каждый из которых имеет свои особенности, преимущества и оптимальные сценарии использования. Выбор конкретного механизма зависит от типа данных, требований к производительности, безопасности и сложности структуры.

1. UserDefaults

UserDefaults (или NSUserDefaults) — простейший способ хранения небольших объемов данных в формате "ключ-значение". Идеально подходит для настроек приложения, флагов, пользовательских предпочтений.

// Запись данных
UserDefaults.standard.set("JohnDoe", forKey: "username")
UserDefaults.standard.set(25, forKey: "userAge")

// Чтение данных
let username = UserDefaults.standard.string(forKey: "username")
let age = UserDefaults.standard.integer(forKey: "userAge")

Особенности:

  • Автоматически кэширует данные в памяти для быстрого доступа.
  • Не предназначен для хранения больших объемов данных или сложных объектов.
  • Данные сохраняются в .plist файле в песочнице приложения.
  • Для безопасности чувствительных данных рекомендуется использовать связку с Keychain.

2. Файловая система (FileManager)

Прямая работа с файловой системой через FileManager позволяет сохранять любые данные: изображения, PDF-документы, JSON, бинарные файлы и т.д. Данные хранятся в структурированных папках внутри песочницы приложения (Documents, Caches, Temporary).

let documentsURL = FileManager.default.urls(for: .documentDirectory, 
                                            in: .userDomainMask).first!
let fileURL = documentsURL.appendingPathComponent("data.json")

// Запись Data в файл
let jsonData = try JSONEncoder().encode(someObject)
try jsonData.write(to: fileURL)

// Чтение из файла
let loadedData = try Data(contentsOf: fileURL)
let object = try JSONDecoder().decode(MyObject.self, from: loadedData)

Ключевые директории:

  • Documents: Для данных пользователя, которые можно воссоздать, но нежелательно терять (синхронизируется с iCloud по умолчанию).
  • Caches: Для временных данных, ускоряющих работу приложения (не синхронизируется, может очищаться системой).
  • Temporary: Для кратковременных файлов (очищается системой).
  • Application Support: Для внутренних данных приложения (можно скрыть от пользователя).

3. Базы данных (SQLite, Core Data, Realm)

Для структурированного хранения больших объемов данных со сложными связями используются системы управления базами данных.

  • SQLite (через оболочки вроде FMDB или GRDB): Легковесная встраиваемая реляционная СУБД. Требует знания SQL, обеспечивает полный контроль.
// Пример с GRDB: Определение модели и запись
struct Player: Codable, FetchableRecord, PersistableRecord {
    var id: Int64?
    var name: String
    var score: Int
}

try dbQueue.write { db in
    try Player(id: 1, name: "Alice", score: 100).insert(db)
}
  • Core Data: Мощный фреймворк объектного графа и persistence от Apple. Работает на более высоком уровне абстракции, чем SQLite (хотя часто использует его как бэкенд). Обеспечивает валидацию, отслеживание изменений, работу в памяти, миграции схемы.
// Сохранение объекта в Core Data
let context = persistentContainer.viewContext
let newUser = UserEntity(context: context)
newUser.name = "Jane"
newUser.id = UUID()

try context.save() // Сохранение контекста
  • Realm: Современная альтернатива с простым API, высокой производительностью и возможностью реактивного программирования. Хранит данные как объекты.
// Запись в Realm
let realm = try! Realm()
let task = Task()
task.name = "Buy milk"

try! realm.write {
    realm.add(task)
}

4. Keychain

Keychain Services — безопасное хранилище для конфиденциальной информации: паролей, токенов, ключей шифрования. Данные шифруются аппаратно и защищены на уровне системы (не удаляются при удалении приложения, если не задан соответствующий флаг).

// Используя обертку KeychainSwift
let keychain = KeychainSwift()
keychain.set("secretToken123", forKey: "userAuthToken")
let token = keychain.get("userAuthToken")

Отличия от UserDefaults: Keychain предназначен исключительно для секретных данных, доступ к которым строго контролируется.

5. Property List (.plist) и JSON

Стандартные форматы сериализации данных, которые можно хранить как в виде файлов в песочнице (через FileManager), так и внутри пакета приложения (для read-only данных, например, конфигурации).

// Чтение из .plist в Bundle
guard let url = Bundle.main.url(forResource: "Config", withExtension: "plist"),
      let data = try? Data(contentsOf: url),
      let config = try? PropertyListSerialization.propertyList(from: data, format: nil) as? [String: Any] else {
    return
}
print(config["apiEndpoint"] as? String)

6. NSCache и In-Memory хранение

NSCache — изменяемая коллекция для временного хранения объектов в памяти. Автоматически удаляет объекты при нехватке памяти. Идеален для кэширования вычислений или изображений.

let cache = NSCache<NSString, UIImage>()
cache.setObject(image, forKey: "avatar")
let cachedImage = cache.object(forKey: "avatar")

Критерии выбора

  • Небольшие настройки: UserDefaults.
  • Конфиденциальные данные: Keychain.
  • Произвольные файлы (изображения, PDF): FileManager.
  • Сложные, структурированные данные с запросами: Core Data (нативный путь) или Realm (производительность, простота).
  • Прямой контроль над SQL: SQLite с оболочкой.
  • Временные, часто используемые данные в памяти: NSCache.

Важно также учитывать необходимость шифрования данных, миграции схемы при обновлениях и синхронизации между устройствами (где решения вроде Core Data с CloudKit или Realm Sync предоставляют готовую инфраструктуру).

Какие знаешь способы сохранения локальных данных в iOS? | PrepBro