FileManager — What It Is, Working with the iOS File System

Author: IT Sectr Published: 2026-07-09 Reading time: 9 min

FileManager is a class from the Foundation framework that provides an interface for working with the file system on iOS, macOS and other Apple platforms. It allows you to create, read, move and delete files and directories, as well as manage metadata and access permissions. In iOS, all FileManager operations are limited by the application Sandbox. According to Apple Developer Documentation (2026), FileManager is thread-safe and can be used from background threads, but all file system operations must be performed considering the sandbox and Security-Scoped Bookmarks access permissions.

Key Takeaways

  • FileManager is the main Foundation class for file system operations: reading, writing, moving, deleting files.
  • Sandbox restricts FileManager access to only application directories — Documents, Library, tmp and App Group.
  • URL-based API (fileManager.urls) is preferred over String-based (NSHomeDirectory) for modern applications.
  • FileManagerDelegate allows tracking and controlling file operations through shouldMoveItemAt and shouldRemoveItemAt.
  • iCloud Drive is available through FileManager when ubiquityContainer is enabled and appropriate entitlements are set.

What is FileManager

FileManager is a singleton class from the Foundation framework that provides a unified API for interacting with the file system on all Apple platforms. It is available through FileManager.default or by creating an instance with a custom delegate.

The main capabilities of the class include: checking file existence (fileExists), creating directories (createDirectory), copying and moving (copyItem, moveItem), deleting (removeItem), getting attributes (attributesOfItem) and directory contents (contentsOfDirectory). FileManager is closely related to NSData, String and JSONEncoder/Decoder for data serialization.

FileManager is thread-safe: Apple guarantees safe method calls from different threads. However, file system operations can be slow on large files, so Apple recommends performing them on a background queue (DispatchQueue.global) and calling FileManagerDelegate methods to report progress.

swift
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)")
}

Main iOS App Directories

Each iOS app has three main directories accessible through FileManager within the Sandbox: Documents, Library and tmp. Each has its own purpose and backup rules that are critical to follow for passing App Store review.

Documents — for user data that should persist between launches and be backed up to iCloud. Library — for app files: caches (Caches), settings (Preferences), databases (Application Support). tmp — for temporary files that can be deleted by the system at any time between app launches.

DirectoryFileManager URLBackupUsage
Documents.documentDirectoryYesUser data, files, export
Library/Caches.cachesDirectoryNoImage caches, temporary data
Library/Preferences.libraryDirectory + "Preferences"YesUserDefaults, app settings
Library/Application Support.applicationSupportDirectoryYesDatabases, CoreData, Realm
tmp.tmpDirectory (NSTemporaryDirectory)NoTemporary session files

Apple's rule: if a file can be recovered from the internet or recreated — it should be stored in Caches (no backup). If a file contains user data — Documents (with backup). Incorrect file placement is one of the common reasons for app rejection, as Apple checks compliance with Storage & iCloud Backup Guidelines.

Reading and Writing Files

FileManager itself does not provide methods for reading file contents — for that use NSData(contentsOf), String(contentsOf) or FileHandle methods. FileManager is responsible for managing files: checking existence, moving, copying, deleting.

To write data use the createFile(atPath:contents:attributes:) method or high-level APIs — data.write(to:), JSONEncoder.encode and PropertyListEncoder. FileManager also provides FileHandle for streaming read and write of large files, which does not load the entire file into memory.

swift
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)

When writing, use options: .atomic — this ensures the file will not be corrupted if the write fails: data is first saved to a temporary file, then atomically moved to the target path. For reading large files, use FileHandle with .readingMode and read data in chunks, controlling memory consumption.

Directory Management

FileManager provides methods for full directory management: createDirectory (creating all intermediate folders via withIntermediateDirectories), contentsOfDirectory (getting a file list), enumeratorAt (recursive traversal) and subpathsOfDirectory (all paths within a directory).

The enumeratorAt method returns a DirectoryEnumerator, which allows efficiently traversing large directories without loading all contents into memory. It supports filtering via skipDescendants and provides attributes of each item without an additional file system query.

swift
// 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")
        }
    }
}

To delete a directory use removeItem(at:). Warning: deleting a directory in iOS is irreversible — files do not go to the trash as on macOS. Before deleting, make sure you no longer need the files from that directory, and perform the operation on a background thread, as deleting many files can block the UI.

FileManager and iCloud

FileManager integrates with iCloud Drive through the URLForUbiquityContainerIdentifier method, which returns the URL of the iCloud directory for the app. This requires enabling the iCloud capability in the project and adding the appropriate entitlement.

iCloud files sync automatically, but FileManager provides methods for manual control: startDownloadingUbiquitousItem forces download, evictUbiquitousItem removes the local copy, and urlOfItem(at:) returns the local URL for an iCloud file. NSMetadataQuery is used for searching files in iCloud.

Critical limitation: iCloud Drive is not supported for files in the Documents directory — only for files in ubiquityContainer. Do not try to sync Documents via iCloud; for that use NSUbiquitousKeyValueStore for small amounts of data or Core Data with CloudKit for complex structures.

FileManager Performance

FileManager operations can be expensive, especially on devices with slow flash memory. Apple's main recommendations include performing all file operations on background queues, minimizing the number of fileExistsAtPath calls, and caching results.

The fileExists method performs a stat() system call, which is relatively slow. If you check for file existence before reading, it is better to just attempt to read it and handle the error — this performs the same stat but avoids a double system call. For bulk checks, use enumeratorAt with resourceValues.

For optimizing work with large data volumes:

  • Use FileHandle for streaming processing of large files
  • Cache fileManager.urls results for frequently used directories
  • Perform batch operations on a granular queue, avoiding main thread blocking
  • Use CoordinatedFileManager for safe access from multiple threads

Apple Instruments provides the File Activity template for profiling file operations. Use it to identify bottlenecks — for example, frequent fileExists calls in a loop or write operations on the main thread. The most common performance issues are related to synchronous writing of large files when the app is being suspended.

Frequently Asked Questions

What is FileManager in iOS?

FileManager is a Foundation framework class for working with the Apple file system. It provides an API for creating, reading, moving, deleting files and directories. In iOS, its operation is limited to the application Sandbox, except for Security-Scoped Bookmarks.

Which directories are accessible through FileManager in iOS?

Documents — user data with iCloud backup. Library/Caches — caches without backup. Library/Application Support — databases. tmp — temporary files. App Group Container — for shared data between apps in the same group.

How to get the path to Documents via FileManager?

Call FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first. The method returns a URL with the absolute path to the Documents directory inside the current app's Sandbox. Use fileExists(atPath:) to check existence.

Can I access other apps' files through FileManager?

No, iOS Sandbox prevents access to other apps' file systems. Exceptions: App Groups (shared directory for apps from the same developer) and Security-Scoped Bookmarks (file access through UIDocumentPicker and iCloud Drive).

How to safely write files via FileManager?

Use the .atomic option when writing — data is first saved to a temporary file, then atomically moved to the target path. This prevents file corruption on write failure. For large data, use FileHandle with chunked writes of 1-2 MB.

Summary

  • FileManager is the central Foundation class for all file system operations in iOS: from existence checks to recursive directory traversal.
  • Documents, Library, tmp — the three main app directories with different backup rules and lifecycles.
  • URL-based API is preferred over String-based paths for compatibility with Sandbox and Security-Scoped Bookmarks.
  • FileHandle and streaming processing are the only way to work with large files without memory overflow.
  • FileManagerDelegate allows controlling move, copy and delete operations through should-methods.
  • iCloud integration is available through ubiquityContainer and NSMetadataQuery for working with cloud files.
  • Performance of file operations is critical — perform them on background queues and minimize fileExists calls.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also