FileManager — это класс из Foundation framework, предоставляющий интерфейс для работы с файловой системой iOS, macOS и других платформ Apple. Он позволяет создавать, читать, перемещать и удалять файлы и директории, а также управлять метаданными и правами доступа. В iOS все операции FileManager ограничены рамками Sandbox приложения. По данным Apple Developer Documentation (2026), FileManager является потокобезопасным и может использоваться из фоновых потоков, но все операции с файловой системой должны выполняться с учётом песочницы и прав доступа Security-Scoped Bookmarks.
Главное
FileManager — синглтон-класс из Foundation framework, предоставляющий унифицированный API для взаимодействия с файловой системой на всех платформах Apple. Доступен через FileManager.default или через создание экземпляра с кастомным делегатом.
Основные возможности класса включают: проверку существования файла (fileExists), создание директорий (createDirectory), копирование и перемещение (copyItem, moveItem), удаление (removeItem), получение атрибутов (attributesOfItem) и содержимого директорий (contentsOfDirectory). FileManager тесно связан с NSData, String и JSONEncoder/Decoder для сериализации данных.
FileManager является thread-safe: Apple гарантирует безопасность вызова методов из разных потоков. Однако операции с файловой системой могут быть медленными на больших файлах, поэтому Apple рекомендует выполнять их на фоновой очереди (DispatchQueue.global) и вызывать FileManagerDelegate методы для информирования о прогрессе.
let fileManager = FileManager.default
let documentsURL = fileManager.urls(
for: .documentDirectory,
in: .userDomainMask
).first!
let fileURL = documentsURL.appendingPathComponent("data.plist")
if fileManager.fileExists(atPath: fileURL.path) {
print("File exists at \(fileURL.path)")
}
Каждое iOS приложение имеет три основные директории, доступные через FileManager в рамках Sandbox: Documents, Library и tmp. Каждая имеет своё назначение и правила резервного копирования, которые критически важно соблюдать для прохождения ревью в App Store.
Documents — для пользовательских данных, которые должны сохраняться между запусками и бэкапироваться в iCloud. Library — для файлов приложения: кешей (Caches), настроек (Preferences), баз данных (Application Support). tmp — для временных файлов, которые могут быть удалены системой в любой момент между запусками приложения.
| Директория | FileManager URL | Бэкап | Использование |
|---|---|---|---|
| Documents | .documentDirectory | Да | Пользовательские данные, файлы, экспорт |
| Library/Caches | .cachesDirectory | Нет | Кеши изображений, временные данные |
| Library/Preferences | .libraryDirectory + "Preferences" | Да | UserDefaults, настройки приложения |
| Library/Application Support | .applicationSupportDirectory | Да | Базы данных, CoreData, Realm |
| tmp | .tmpDirectory (NSTemporaryDirectory) | Нет | Временные файлы сессии |
Правило Apple: если файл можно восстановить из интернета или пересоздать — он должен храниться в Caches (без бэкапа). Если файл содержит пользовательские данные — Documents (с бэкапом). Неправильное размещение файлов — одна из частых причин отклонения приложения, так как Apple проверяет использование Storage & iCloud Backup Guidelines.
FileManager сам не предоставляет методов для чтения содержимого файлов — для этого используются NSData(contentsOf), String(contentsOf) или методы FileHandle. FileManager отвечает за управление файлами: проверку существования, перемещение, копирование, удаление.
Для записи данных используется метод createFile(atPath:contents:attributes:) или высокоуровневые API — data.write(to:), JSONEncoder.encode и PropertyListEncoder. FileManager также предоставляет FileHandle для потокового чтения и записи больших файлов, который не загружает весь файл в память.
struct UserSettings: Codable {
let username: String
let isDarkMode: Bool
let fontSize: Int
}
let settings = UserSettings(
username: "developer",
isDarkMode: true,
fontSize: 16
)
// Write JSON to Documents
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(settings)
let url = documentsURL.appendingPathComponent("settings.json")
try data.write(to: url, options: .atomic)
// Read JSON
let loadedData = try Data(contentsOf: url)
let loadedSettings = try JSONDecoder()
.decode(UserSettings.self, from: loadedData)
При записи используйте options: .atomic — это гарантирует, что файл не будет повреждён при сбое записи: данные сначала сохраняются во временный файл, а затем атомарно перемещаются в целевой путь. Для чтения больших файлов используйте FileHandle с .readingMode и читайте данные чанками, контролируя потребление памяти.
FileManager предоставляет методы для полного управления директориями: createDirectory (создание всех промежуточных папок через withIntermediateDirectories), contentsOfDirectory (получение списка файлов), enumeratorAt (рекурсивный обход) и subpathsOfDirectory (все пути внутри директории).
Метод enumeratorAt возвращает DirectoryEnumerator, который позволяет эффективно обходить большие директории без загрузки всего содержимого в память. Он поддерживает фильтрацию через skipDescendants и предоставляет атрибуты каждого элемента без дополнительного запроса к файловой системе.
// Recursive directory traversal
if let enumerator = fileManager.enumerator(
at: documentsURL,
includingPropertiesForKeys: [.fileSizeKey, .isDirectoryKey]
) {
for case let fileURL as URL in enumerator {
let attrs = try fileURL.resourceValues(
for: [.fileSizeKey, .isDirectoryKey]
)
if attrs.isDirectory == false {
let size = attrs.fileSize ?? 0
print("File: \(fileURL.lastPathComponent), Size: \(size) bytes")
}
}
}
Для удаления директории используйте removeItem(at:). Внимание: удаление директории в iOS необратимо — файлы не попадают в корзину, как на macOS. Перед удалением убедитесь, что вы больше не используете файлы из этой директории, и выполните операцию на фоновом потоке, так как удаление большого количества файлов может заблокировать UI.
FileManager интегрируется с iCloud Drive через метод URLForUbiquityContainerIdentifier, который возвращает URL директории iCloud для приложения. Для работы требуется включить iCloud capability в проекте и добавить соответствующий entitlement.
iCloud файлы синхронизируются автоматически, но FileManager предоставляет методы для ручного контроля: startDownloadingUbiquitousItem принудительно начинает загрузку, evictUbiquitousItem удаляет локальную копию, а urlOfItem(at:) возвращает локальный URL для iCloud файла. NSMetadataQuery используется для поиска файлов в iCloud.
Критическое ограничение: iCloud Drive не поддерживается для файлов в Documents директории — только для файлов в ubiquityContainer. Не пытайтесь синхронизировать Documents через iCloud; для этого используйте NSUbiquitousKeyValueStore для небольших объёмов данных или Core Data с CloudKit для сложных структур.
Операции с FileManager могут быть дорогими, особенно на устройствах с медленной flash-памятью. Основные рекомендации Apple включают выполнение всех файловых операций на фоновых очередях, минимизацию количества вызовов fileExistsAtPath и использование кеширования результатов.
Метод fileExists выполняет системный вызов stat(), который относительно медленный. Если вы проверяете наличие файла перед его чтением, лучше сразу попытаться прочитать его и обработать ошибку — это выполняет тот же stat, но избавляет от двойного системного вызова. Для массовых проверок используйте enumeratorAt с resourceValues.
Для оптимизации работы с большими объёмами данных:
Apple Instruments предоставляет шаблон File Activity для профилирования файловых операций. Используйте его для выявления узких мест — например, частых вызовов fileExists в цикле или операций записи на main thread. Наиболее частые проблемы производительности связаны с синхронной записью больших файлов при сворачивании приложения.
Часто задаваемые вопросы
FileManager — класс Foundation framework для работы с файловой системой Apple. Предоставляет API для создания, чтения, перемещения, удаления файлов и директорий. В iOS его работа ограничена рамками Sandbox приложения, за исключением Security-Scoped Bookmarks.
Documents — пользовательские данные с бэкапом в iCloud. Library/Caches — кеши без бэкапа. Library/Application Support — базы данных. tmp — временные файлы. App Group Container — для общих данных между приложениями одной группы.
Вызовите FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first. Метод возвращает URL с абсолютным путём к директории Documents внутри Sandbox текущего приложения. Для проверки существования используйте fileExists(atPath:).
Нет, Sandbox iOS запрещает доступ к файловой системе других приложений. Исключения: App Groups (общая директория для приложений одного разработчика) и Security-Scoped Bookmarks (доступ к файлам через UIDocumentPicker и iCloud Drive).
Используйте .atomic опцию при записи — данные сначала сохраняются во временный файл, затем атомарно перемещаются в целевой путь. Это предотвращает повреждение файла при сбое записи. Для больших данных используйте FileHandle с записью чанками по 1-2 MB.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также