> Какой протокол нужно реализовать для сохранения файла в iOS? (iOS, Swift)

Уровень: senior · Роль: mobile · Категория: Технические вопросы

Компании: Eltex

Стек: iOS, Swift

> Пример ответа

Короткий ответ

Для сохранения файла в iOS протокол не требуется - достаточно использовать FileManager и класс Data (или URLSession для загрузки из сети). Если речь о Codable-моделях, то реализуют протокол Codable (или Encodable/Decodable). Для работы с файлами напрямую протоколы не нужны, это не Java-интерфейсы.

Подробное объяснение

В iOS нет единого "протокола сохранения файла". В зависимости от задачи:

  • FileManager - основной API для операций с файловой системой: создание, перемещение, удаление, проверка существования.
  • Data.write(to:options:) - запись сырых байт в файл.
  • Codable - для сериализации структур в JSON/PropertyList, затем результат пишется через Data.
  • URLSession - для скачивания файла из сети и сохранения во временную директорию.
  • NSFileCoordinator - для безопасной работы с файлами в iCloud или shared container.

Протоколы в Swift - это контракты для типов. Для сохранения файла вы реализуете Encodable (если модель), но сам процесс записи - это вызов методов FileManager, а не реализация интерфейса.

На практике

Типичный сценарий для senior:

  1. Определить директорию: .documentDirectory, .cachesDirectory, .temporaryDirectory.
  2. Сформировать путь: directory.appendingPathComponent("file.json").
  3. Сериализовать данные: JSONEncoder().encode(model).
  4. Записать: try data.write(to: url, options: .atomic).
  5. Обработать ошибки: try?, do-catch, проверка свободного места.

Для больших файлов используют потоковую запись через FileHandle или OutputStream. Для конкурентного доступа - NSFileCoordinator или DispatchIO.

Пример кода

SWIFT
struct User: Codable {
let id: Int
let name: String
}
func saveUser(_ user: User) throws {
let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let url = documents.appendingPathComponent("user.json")
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(user)
try data.write(to: url, options: .atomic)
}
func loadUser() throws -> User? {
let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let url = documents.appendingPathComponent("user.json")
guard FileManager.default.fileExists(atPath: url.path) else { return nil }
let data = try Data(contentsOf: url)
return try JSONDecoder().decode(User.self, from: data)
}

Как отвечать на собеседовании

Начните с уточнения: "Если вопрос про протоколы Swift - то для сериализации используется Codable. Если про механизм сохранения - это FileManager и Data.write". Покажите понимание различий между протоколом как контрактом и API как инструментом. Упомяните .atomic для атомарности, выбор директории, обработку ошибок. Для senior добавьте про безопасность при конкурентном доступе и работу с большими файлами.

Что проверяет интервьюер

  • Понимание, что протоколы в Swift - это не то же самое, что интерфейсы в Java, и они не нужны для записи файлов.
  • Знание FileManager, Data, Codable, URLSession.
  • Умение выбирать директорию под задачу (кэш vs документы).
  • Понимание атомарности записи и обработки ошибок.
  • Для senior - знание NSFileCoordinator, потоковой записи, работы с iCloud.

Типичные ошибки

  • Путаница между "реализовать протокол" и "использовать API" - кандидат начинает рассуждать про FileManagerDelegate или NSFilePresenter, хотя они не нужны для простого сохранения.
  • Запись в temporaryDirectory без понимания, что файл может быть удалён системой.
  • Игнорирование options: .atomic - при сбое записи файл остаётся повреждённым.
  • Отсутствие обработки ошибок: try! вместо try? или do-catch.
  • Неправильное построение URL: конкатенация строк вместо appendingPathComponent.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью