Skip to content
All essays
iOSMarch 27, 202511 min

Swift File Management: Documents and Storage

Manage files and documents in Swift apps. FileManager, iCloud Documents, and file handling.

Ü
Ümit Uz
Mobile & Full Stack Developer

File management is crucial for many apps. Learn to work with files, directories, and document storage.

FileManager Basics

File Operations

swift
import Foundation

class FileManagerHelper {
    let fileManager = FileManager.default

    // Get documents directory
    var documentsDirectory: URL {
        fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
    }

    // Get caches directory
    var cachesDirectory: URL {
        fileManager.urls(for: .cachesDirectory, in: .userDomainMask)[0]
    }

    // Get temporary directory
    var temporaryDirectory: URL {
        fileManager.temporaryDirectory
    }

    // Create directory
    func createDirectory(at url: URL) throws {
        var isDirectory: ObjCBool = false
        let exists = fileManager.fileExists(atPath: url.path, isDirectory: &isDirectory)

        guard !exists || !isDirectory else {
            throw FileError.directoryAlreadyExists
        }

        try fileManager.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)
    }

    // Delete file
    func deleteFile(at url: URL) throws {
        try fileManager.removeItem(at: url)
    }

    enum FileError: Error {
        case directoryAlreadyExists
        case fileNotFound
    }
}

Document Directory

Save Documents

swift
class DocumentManager {
    let fileManager = FileManager.default

    var documentsDirectory: URL {
        fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
    }

    func saveDocument(_ text: String, filename: String) throws {
        let fileURL = documentsDirectory.appendingPathComponent(filename)

        try text.write(to: fileURL, atomically: true, encoding: .utf8)
    }

    func loadDocument(filename: String) throws -> String {
        let fileURL = documentsDirectory.appendingPathComponent(filename)

        return try String(contentsOf: fileURL)
    }

    func listDocuments() -> [URL] {
        do {
            let files = try fileManager.contentsOfDirectory(
                at: documentsDirectory,
                includingPropertiesForDirectories: false
            )

            return files.filter { $0.pathExtension == "txt" }
        } catch {
            return []
        }
    }

    func deleteDocument(filename: String) throws {
        let fileURL = documentsDirectory.appendingPathComponent(filename)
        try FileManager.default.removeItem(at: fileURL)
    }
}

iCloud Documents

Cloud Storage

swift
import CloudKit

class CloudDocumentManager {
    let container = CKContainer(identifier: "iCloud.com.yourapp.Documents")
    var documentsDirectory: URL {
        FileManager.default.url(forUbiquityContainerIdentifier: "iCloud.com.yourapp.Documents")!
    }

    func saveToCloud(_ text: String, filename: String) throws {
        let fileURL = documentsDirectory.appendingPathComponent(filename)

        try text.write(to: fileURL, atomically: true, encoding: .utf8)

        // File will be synced automatically
    }

    func listCloudDocuments() -> [URL] {
        do {
            let files = try FileManager.default.contentsOfDirectory(
                at: documentsDirectory,
                includingPropertiesForDirectories: false
            )

            return files
        } catch {
            return []
        }
    }

    func deleteCloudDocument(filename: String) throws {
        let fileURL = documentsDirectory.appendingPathComponent(filename)
        try FileManager.default.removeItem(at: fileURL)
    }

    func monitorCloudDocuments() -> NSFileCoordinator {
        return NSFileCoordinator()
    }
}

File Coordination

iCloud Conflict Resolution

swift
class FileCoordinatorManager {
    func coordinateWriting(at url: URL, intention: NSFileCoordinationWritingIntent) throws {
        let fileCoordinator = NSFileCoordinator()

        var coordinatorError: NSError?
        var coordinatedFile: URL?

        NSFileCoordinator().coordinate(writingItemAt: url, options: nil, error: &coordinatorError) { url in
            try intention.perform(at: url)

            var error: NSError?
            NSFileCoordinator().item(at: url, error: &error)

            if let error = error {
                throw error
            }
            return url
        }

        throw coordinatorError ?? FileError.coordinationFailed
    }

    enum FileError: Error {
        case coordinationFailed
    }
}

File Streaming

Large File Handling

swift
class LargeFileManager {
    func processLargeFile(at url: URL, chunkSize: Int = 1024) async throws {
        let handle = try FileHandle(forReadingFrom: url)
        defer {
            try? handle.close()
        }

        var offset = 0

        while offset < try handle.offsetInFile() {
            handle.seek(toFileOffset: UInt64(offset))

            let data = handle.readData(ofLength: chunkSize)
            if data.isEmpty {
                break
            }

            // Process chunk
            try await processData(data)

            offset += chunkSize
        }
    }

    private func processData(_ data: Data) async throws {
        // Process data chunk
        print("Processed \(data.count) bytes")
    }
}

File Protection

Secure Files

swift
class SecureFileManager {
    func createSecureFile(at url: URL) throws {
        let attributes: [FileAttributeKey: Any] = [
            .protectionKey: FileProtectionType.complete
        ]

        try FileManager.default.setAttributes(attributes, ofItemAtPath: url.path)
    }

    func createEncryptedFile(at url: URL, password: String) throws {
        let data = password.data(using: .utf8)!

        // Encrypt data
        let encryptedData = try AES256.encrypt(data, password: password)

        try encryptedData.write(to: url)
    }

    func readEncryptedFile(at url: URL, password: String) throws -> String {
        let encryptedData = try Data(contentsOf: url)

        // Decrypt data
        let decryptedData = try AES256.decrypt(encryptedData, password: password)

        return String(data: decryptedData, encoding: .utf8) ?? ""
    }
}

Best Practices

  1. 1Paths: Use URL-based paths
  2. 2Coordination: Use file coordination
  3. 3Storage: Store files appropriately
  4. 4Cleanup: Clean up temporary files
  5. 5Error Handling: Handle file errors
  6. 6Security: Secure sensitive files
  7. 7iCloud: Leverage iCloud sync
  8. 8Memory: Manage memory for large files

File management is essential for data persistence!

Related essays

Next essay
Swift Memory Management: ARC and Optimization