FileManager — cos'è, lavoro con il file system iOS

Autore: IT Sectr Pubblicato: 2026-07-09 Tempo di lettura: 9 min

FileManager è una classe del framework Foundation che fornisce un'interfaccia per lavorare con il file system su iOS, macOS e altre piattaforme Apple. Permette di creare, leggere, spostare ed eliminare file e directory, nonché gestire metadati e permessi di accesso. In iOS, tutte le operazioni di FileManager sono limitate dal Sandbox dell'app. Secondo la Documentazione per Sviluppatori Apple (2026), FileManager è thread-safe e può essere utilizzato da thread in background, ma tutte le operazioni sul file system devono essere eseguite considerando la sandbox e i permessi di accesso Security-Scoped Bookmarks.

Punti Chiave

  • FileManager è la classe principale di Foundation per le operazioni sul file system: leggere, scrivere, spostare, eliminare file.
  • Sandbox limita l'accesso di FileManager solo alle directory dell'app — Documents, Library, tmp e App Group.
  • API basata su URL (fileManager.urls) è preferibile a quella basata su String (NSHomeDirectory) per applicazioni moderne.
  • FileManagerDelegate permette di tracciare e controllare le operazioni sui file tramite shouldMoveItemAt e shouldRemoveItemAt.
  • iCloud Drive è disponibile tramite FileManager quando ubiquityContainer è abilitato e gli entitlement appropriati sono configurati.

Cos'è FileManager

FileManager è una classe singleton del framework Foundation che fornisce un'API unificata per interagire con il file system su tutte le piattaforme Apple. È disponibile tramite FileManager.default o creando un'istanza con un delegato personalizzato.

Le principali capacità della classe includono: verificare l'esistenza di un file (fileExists), creare directory (createDirectory), copiare e spostare (copyItem, moveItem), eliminare (removeItem), ottenere attributi (attributesOfItem) e contenuti di directory (contentsOfDirectory). FileManager è strettamente correlato a NSData, String e JSONEncoder/Decoder per la serializzazione dei dati.

FileManager è thread-safe: Apple garantisce chiamate di metodo sicure da thread diversi. Tuttavia, le operazioni sul file system possono essere lente su file grandi, quindi Apple raccomanda di eseguirle su una coda in background (DispatchQueue.global) e chiamare i metodi FileManagerDelegate per segnalare l'avanzamento.

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

Directory principali delle app iOS

Ogni app iOS ha tre directory principali accessibili tramite FileManager all'interno del Sandbox: Documents, Library e tmp. Ciascuna ha il proprio scopo e regole di backup che è fondamentale rispettare per superare la revisione dell'App Store.

Documents — per i dati utente che devono persistere tra le esecuzioni ed essere backup su iCloud. Library — per i file dell'app: cache (Caches), impostazioni (Preferences), database (Application Support). tmp — per file temporanei che il sistema può eliminare in qualsiasi momento tra le esecuzioni dell'app.

DirectoryURL FileManagerBackupUtilizzo
Documents.documentDirectoryDati utente, file, esportazione
Library/Caches.cachesDirectoryNoCache immagini, dati temporanei
Library/Preferences.libraryDirectory + "Preferences"UserDefaults, impostazioni app
Library/Application Support.applicationSupportDirectoryDatabase, CoreData, Realm
tmp.tmpDirectory (NSTemporaryDirectory)NoFile temporanei di sessione

Regola Apple: se un file può essere recuperato da Internet o ricreato — deve essere memorizzato in Caches (senza backup). Se un file contiene dati utente — Documents (con backup). Il posizionamento errato dei file è una delle ragioni comuni di rifiuto dell'app, poiché Apple verifica la conformità con le linee guida Storage e iCloud Backup.

Lettura e scrittura di file

FileManager stesso non fornisce metodi per leggere il contenuto dei file — per questo usa NSData(contentsOf), String(contentsOf) o i metodi FileHandle. FileManager è responsabile della gestione dei file: verifica esistenza, spostamento, copia, eliminazione.

Per scrivere dati usa il metodo createFile(atPath:contents:attributes:) o API di alto livello — data.write(to:), JSONEncoder.encode e PropertyListEncoder. FileManager fornisce anche FileHandle per la lettura e scrittura in streaming di file grandi, che non carica l'intero file in memoria.

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)

Durante la scrittura, usa options: .atomic — questo garantisce che il file non venga danneggiato se la scrittura fallisce: i dati vengono prima salvati in un file temporaneo, poi spostati atomicamente al percorso di destinazione. Per leggere file grandi, usa FileHandle con .readingMode e leggi i dati a blocchi, controllando il consumo di memoria.

Gestione delle directory

FileManager fornisce metodi per la gestione completa delle directory: createDirectory (creazione di tutte le cartelle intermedie tramite withIntermediateDirectories), contentsOfDirectory (ottenere elenco file), enumeratorAt (attraversamento ricorsivo) e subpathsOfDirectory (tutti i percorsi all'interno di una directory).

Il metodo enumeratorAt restituisce un DirectoryEnumerator, che permette di attraversare efficientemente grandi directory senza caricare tutto il contenuto in memoria. Supporta il filtraggio tramite skipDescendants e fornisce gli attributi di ogni elemento senza una query aggiuntiva al file system.

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

Per eliminare una directory usa removeItem(at:). Attenzione: eliminare una directory in iOS è irreversibile — i file non vanno nel cestino come su macOS. Prima di eliminare, assicurati di non aver più bisogno dei file da quella directory ed esegui l'operazione su un thread in background, poiché eliminare molti file può bloccare l'interfaccia utente.

FileManager e iCloud

FileManager si integra con iCloud Drive tramite il metodo URLForUbiquityContainerIdentifier, che restituisce l'URL della directory iCloud per l'app. Ciò richiede l'abilitazione della capacità iCloud nel progetto e l'aggiunta dell'entitlement appropriato.

I file iCloud si sincronizzano automaticamente, ma FileManager fornisce metodi per il controllo manuale: startDownloadingUbiquitousItem forza il download, evictUbiquitousItem rimuove la copia locale e urlOfItem(at:) restituisce l'URL locale per un file iCloud. NSMetadataQuery viene utilizzato per cercare file in iCloud.

Limitazione critica: iCloud Drive non è supportato per i file nella directory Documents — solo per i file in ubiquityContainer. Non tentare di sincronizzare Documents tramite iCloud; usa invece NSUbiquitousKeyValueStore per piccole quantità di dati o Core Data con CloudKit per strutture complesse.

Prestazioni di FileManager

Le operazioni con FileManager possono essere costose, specialmente su dispositivi con memoria flash lenta. Le principali raccomandazioni Apple includono l'esecuzione di tutte le operazioni su code in background, la minimizzazione del numero di chiamate fileExistsAtPath e la memorizzazione nella cache dei risultati.

Il metodo fileExists esegue una chiamata di sistema stat(), che è relativamente lenta. Se controlli l'esistenza di un file prima di leggerlo, è meglio provare a leggerlo direttamente e gestire l'errore — questo esegue lo stesso stat ma evita una doppia chiamata di sistema. Per controlli di massa, usa enumeratorAt con resourceValues.

Per ottimizzare il lavoro con grandi volumi di dati:

  • Usa FileHandle per l'elaborazione in streaming di file grandi
  • Memorizza nella cache i risultati di fileManager.urls per le directory usate frequentemente
  • Esegui operazioni batch in una coda granulare, evitando di bloccare il thread principale
  • Usa CoordinatedFileManager per l'accesso sicuro da più thread

Apple Instruments fornisce il modello File Activity per il profiling delle operazioni sui file. Usalo per identificare i colli di bottiglia — ad esempio, chiamate frequenti a fileExists in un loop o operazioni di scrittura sul thread principale. I problemi di prestazioni più comuni sono legati alla scrittura sincrona di file grandi durante la sospensione dell'app.

Domande Frequenti

Cos'è FileManager in iOS?

FileManager è una classe del framework Foundation per lavorare con il file system Apple. Fornisce un'API per creare, leggere, spostare ed eliminare file e directory. In iOS, il suo funzionamento è limitato al Sandbox dell'app, ad eccezione di Security-Scoped Bookmarks.

Quali directory sono accessibili tramite FileManager in iOS?

Documents — dati utente con backup su iCloud. Library/Caches — cache senza backup. Library/Application Support — database. tmp — file temporanei. App Group Container — per dati condivisi tra app dello stesso gruppo.

Come ottenere il percorso di Documents tramite FileManager?

Chiama FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first. Il metodo restituisce un URL con il percorso assoluto alla directory Documents all'interno del Sandbox dell'app corrente. Usa fileExists(atPath:) per verificare l'esistenza.

Posso accedere ai file di altre app tramite FileManager?

No, il Sandbox di iOS impedisce l'accesso al file system di altre applicazioni. Eccezioni: App Groups (directory condivisa per app dello stesso sviluppatore) e Security-Scoped Bookmarks (accesso ai file tramite UIDocumentPicker e iCloud Drive).

Come scrivere file in modo sicuro tramite FileManager?

Usa l'opzione .atomic durante la scrittura — i dati vengono prima salvati in un file temporaneo, poi spostati atomicamente al percorso di destinazione. Questo previene il danneggiamento del file in caso di fallimento della scrittura. Per dati grandi, usa FileHandle con scrittura a blocchi di 1-2 MB.

Riepilogo

  • FileManager è la classe centrale di Foundation per tutte le operazioni sul file system in iOS: dalla verifica dell'esistenza all'attraversamento ricorsivo delle directory.
  • Documents, Library, tmp — le tre directory principali dell'app con diverse regole di backup e cicli di vita.
  • API basata su URL è preferibile ai percorsi basati su String per la compatibilità con Sandbox e Security-Scoped Bookmarks.
  • FileHandle e l'elaborazione in streaming sono l'unico modo per lavorare con file grandi senza overflow di memoria.
  • FileManagerDelegate permette di controllare le operazioni di spostamento, copia ed eliminazione tramite i metodi should-.
  • Integrazione iCloud è disponibile tramite ubiquityContainer e NSMetadataQuery per lavorare con file cloud.
  • Prestazioni delle operazioni sui file sono critiche — eseguile su code in background e minimizza le chiamate fileExists.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche