Lavorare con il file system è il fondamento di qualsiasi applicazione mobile. Ogni piattaforma offre il proprio modello di accesso: Sandbox su iOS isola le applicazioni in contenitori separati, mentre Scoped Storage su Android limita l'accesso diretto all'archiviazione condivisa. Secondo Google Developer Documentation (2026), l'introduzione di Scoped Storage con Android 10 ha richiesto una revisione completa dell'architettura di archiviazione dei dati. In questa guida tratteremo FileManager, MediaStore API, Storage Access Framework e DocumentProvider per entrambe le piattaforme.
Punti chiave
Il file system nelle applicazioni mobili è un insieme di API, regole di sicurezza e vincoli che definiscono come i dati vengono archiviati e accessibili sui dispositivi iOS e Android. A differenza dei sistemi operativi desktop, le piattaforme mobili isolano ogni applicazione per proteggere i dati dell'utente dalla lettura non autorizzata da parte di altri programmi.
iOS utilizza il modello Sandbox, in cui ogni app esiste nel proprio contenitore con permessi strettamente limitati. Prima della versione 10, Android forniva accesso completo all'archiviazione esterna, ma con l'introduzione di Scoped Storage, l'approccio si è avvicinato a iOS. La differenza principale è che iOS isola completamente il file system, mentre Android offre diversi livelli di accesso: una directory privata, MediaStore pubblico e accesso temporaneo tramite SAF.
Le applicazioni mobili utilizzano tre tipi di archiviazione dati. Archiviazione privata — una directory accessibile solo all'app per file interni e cache. Archiviazione condivisa — file multimediali tramite MediaStore (Android) o Files App (iOS). Archiviazione cloud — iCloud Drive e Google Drive per la sincronizzazione tra dispositivi. Ogni tipo ha i propri limiti di dimensione, durata dei file e condizioni di accesso.
| Tipo di archiviazione | iOS | Android |
|---|---|---|
| Privata | Documents, Library, Caches | getFilesDir(), getCacheDir() |
| Multimedia condivisa | PHPhotoLibrary tramite selettore | MediaStore API (ContentResolver) |
| Documenti condivisi | Files App tramite UIDocumentPicker | Storage Access Framework (SAF) |
| Cloud | iCloud Drive (UIDocument) | Google Drive API |
| Cache | Directory Caches, pulita dal sistema | getCacheDir(), getExternalCacheDir() |
Sandbox è l'architettura di sicurezza di iOS che isola ogni applicazione. Un'app può leggere e scrivere solo all'interno della propria sandbox. Per accedere a contatti, foto o file di altre app, è necessario utilizzare selettori di sistema: UIImagePickerController o UIDocumentPickerViewController. L'accesso a Files App viene configurato tramite il flag UIFileSharingEnabled in Info.plist. Il file system nello sviluppo mobile su iOS richiede la comprensione della struttura delle directory e la scelta della posizione corretta per ogni tipo di dato.
La sandbox iOS è composta da diverse directory standard. Documents — per i file utente, inclusa in iCloud Backup. Caches — per dati temporanei che il sistema può eliminare quando lo spazio di archiviazione è scarso. Temporary — per i file della sessione corrente, cancellata al riavvio. Application Support — per i dati interni dell'app nascosti all'utente. Scegliere la directory sbagliata causa problemi: salvare la cache in Documents spreca spazio iCloud e viola le linee guida di Apple sul file system.
import Foundation
let fileManager = FileManager.default
guard let documentsURL = fileManager.urls(
for: .documentDirectory,
in: .userDomainMask
).first else { return }
let fileURL = documentsURL.appendingPathComponent("notes.txt")
let text = "Содержимое файла"
// Scrittura atomica con crittografia
try text.write(
to: fileURL,
atomically: true,
encoding: .utf8
)
La classe FileManager fornisce un set completo di metodi per gestire i file su iOS. FileManager.default è un singleton thread-safe adatto alla maggior parte delle operazioni. Metodi come fileExists(atPath:), createDirectory(at:withIntermediateDirectories:attributes:), copyItem(at:to:) e removeItem(at:) coprono scenari di base. Le operazioni su file maggiori di 1 MB dovrebbero essere eseguite in un thread in background tramite DispatchQueue.global(). Per lo streaming di grandi volumi, utilizzare FileHandle invece di caricare l'intero file in memoria.
func readDocumentsFile(named fileName: String) -> String? {
guard let docsURL = FileManager.default.urls(
for: .documentDirectory,
in: .userDomainMask
).first else { return nil }
let fileURL = docsURL.appendingPathComponent(fileName)
return try? String(contentsOf: fileURL)
}
Con il rilascio di Android 10, Google ha introdotto Scoped Storage — un modello di accesso limitato al file system. Un'app può leggere e scrivere liberamente solo nelle proprie directory private. Per i file multimediali (foto, video, audio), viene utilizzata MediaStore API tramite ContentResolver. Per documenti arbitrari, viene utilizzato Storage Access Framework tramite Intent ACTION_OPEN_DOCUMENT. Su Android 11+, l'accesso diretto alla radice dell'archiviazione esterna è completamente vietato e tutti gli sviluppatori devono utilizzare le nuove API.
MediaStore è un ContentProvider di sistema per accedere ai file multimediali sul dispositivo. Tramite ContentResolver, l'app richiede l'Uri dei file invece dei percorsi diretti. MediaStore.Files — per tutti i tipi di file, Images — per le immagini, Video — per i video, Audio — per le registrazioni audio. La scrittura nelle directory condivise avviene tramite insert() con DISPLAY_NAME, MIME_TYPE e RELATIVE_PATH. Dopo l'inserimento, l'app riceve un Uri attraverso il quale vengono scritti i byte. I tipi MIME svolgono un ruolo fondamentale — un tipo errato causerà un errore all'apertura del file.
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "report.pdf")
put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf")
put(MediaStore.MediaColumns.RELATIVE_PATH, "Documents/Reports")
}
val uri = contentResolver.insert(
MediaStore.Files.getContentUri("external"),
contentValues
)
uri?.let {
contentResolver.openOutputStream(it)?.use { stream ->
stream.write(pdfBytes)
}
}
SAF fornisce un'interfaccia unificata per selezionare e creare file senza permessi di runtime. Intent ACTION_OPEN_DOCUMENT apre il gestore file di sistema su Android. Dopo la selezione, l'app riceve un Uri content:// con accesso temporaneo tramite FLAG_GRANT_READ_URI_PERMISSION. ACTION_CREATE_DOCUMENT consente di salvare file in qualsiasi posizione di archiviazione esterna scelta dall'utente. SAF funziona su Android 5+ e fornisce accesso a file di provider cloud collegati tramite DocumentsProvider.
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "*/*"
putExtra(Intent.EXTRA_MIME_TYPES, arrayOf(
"application/pdf",
"text/plain"
))
}
startActivityForResult(intent, REQUEST_CODE)
Entrambe le piattaforme forniscono meccanismi integrati per consentire agli utenti di selezionare file. I documenti nelle applicazioni mobili vengono passati tramite selettori di sistema che concedono accesso temporaneo a un file senza permessi permanenti. Su iOS, questo è UIDocumentPickerViewController; su Android, ACTION_OPEN_DOCUMENT. I documenti nelle applicazioni mobili possono essere selezionati sia dall'archiviazione locale che dai servizi cloud. L'utente specifica esplicitamente il file e l'app riceve un Uri o URL con un periodo di validità limitato.
UIDocumentPickerViewController apre Files App e consente di selezionare uno o più documenti. Modalità: import (copia nella sandbox) e apertura (accesso tramite URL con ambito di sicurezza). Per il filtraggio dei file, viene passato un array di tipi UTType — ad esempio, .pdf e .plainText. Dopo aver ricevuto l'URL, l'app deve chiamare startAccessingSecurityScopedResource() prima della lettura e stopAccessingSecurityScopedResource() dopo aver terminato. La mancata chiamata di stopAccessing causa perdite di risorse di sistema. I documenti nelle applicazioni mobili su iOS richiedono il rilascio obbligatorio dei permessi temporanei dopo aver terminato il lavoro con il file.
let picker = UIDocumentPickerViewController(
forOpeningContentTypes: [.pdf, .plainText]
)
picker.allowsMultipleSelection = true
picker.delegate = self
present(picker, animated: true)
// Rilascio dell'accesso nel delegato
func documentPicker(
_ controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL]
) {
guard let url = urls.first else { return }
url.startAccessingSecurityScopedResource()
defer { url.stopAccessingSecurityScopedResource() }
}
FileProvider è una sottoclasse di ContentProvider per condividere file in modo sicuro tra app. Genera Uri content:// temporanei basati su file da directory XML specificate. Altre app ottengono l'accesso tramite Intent con FLAG_GRANT_READ_URI_PERMISSION. DocumentProvider, a differenza di FileProvider, pubblica file in SAF e consente ad altre app di navigare nel contenuto della tua app come parte del file system. Per implementare DocumentsProvider, è necessario sovrascrivere queryRoots(), queryChildDocuments() e openDocument(), quindi registrarlo in AndroidManifest.xml
La sincronizzazione cloud consente agli utenti di accedere ai documenti su tutti i loro dispositivi. Il file system nelle applicazioni mobili è potenziato da un layer cloud: UIDocument su iOS tiene traccia automaticamente delle modifiche e le sincronizza tramite iCloud. Su Android, funzionalità simili vengono costruite tramite Google Drive API o DocumentsProvider con radici cloud. Comprendere il file system nello sviluppo mobile è fondamentale per costruire una sincronizzazione affidabile tra dispositivi.
UIDocument è una classe astratta per lavorare con documenti iCloud. Salva automaticamente le modifiche, legge i dati e notifica il delegato degli aggiornamenti. In caso di conflitto di scrittura, NSFileVersion fornisce un elenco di versioni disponibili — lo sviluppatore può scegliere la più recente o mostrare all'utente opzioni di risoluzione dei conflitti. La configurazione di Ubiquity Container nelle Capabilities del progetto è obbligatoria per iCloud Drive. NSFileCoordinator e NSFilePresenter prevengono le race condition durante l'accesso concorrente da più thread o dispositivi.
iOS include automaticamente la directory Documents in iCloud Backup. Android funziona con Auto Backup for Apps — il sistema salva i dati da getFilesDir(), SharedPreferences e database SQLite in Google Drive. Cache e file esterni non sono inclusi nei backup. Entrambe le piattaforme consentono di configurare esclusioni: su iOS tramite NSURLIsExcludedFromBackupKey, su Android tramite configurazione XML delle regole di backup. La crittografia dei file con dati personali è obbligatoria — su iOS utilizzare NSDataWritingFileProtectionComplete, su Android utilizzare EncryptedFile dalla libreria security-crypto.
| Parametro | iOS | Android |
|---|---|---|
| Backup predefinito | Documents e Library | getFilesDir(), SharedPreferences, DB |
| Esclusione file | isExcludedFromBackupKey | Regole XML di backup (fullBackupContent) |
| Crittografia | NSDataWritingFileProtectionComplete | EncryptedFile (security-crypto) |
| Sync cloud | UIDocument + iCloud | Google Drive API + SAF |
| Ripristino automatico | iCloud Restore dopo installazione | Auto Backup al reinserimento |
Domande frequenti
Sandbox è un ambiente isolato per ogni app su iOS. L'app non può accedere ai file di altre app senza utilizzare selettori di sistema come UIDocumentPickerViewController.
Scoped Storage è un modello di accesso limitato al file system su Android 10+. L'app legge direttamente solo i propri file, utilizza MediaStore API per i media e Storage Access Framework per i documenti.
Utilizza UIDocumentPickerViewController — il selettore di sistema per scegliere documenti da Files App o iCloud Drive. Dopo la selezione, ricevi un URL con ambito di sicurezza e accesso temporaneo.
Per i file multimediali, utilizza MediaStore API tramite ContentResolver specificando il tipo MIME. Per documenti arbitrari, utilizza Storage Access Framework con Intent ACTION_OPEN_DOCUMENT.
FileProvider è una sottoclasse di ContentProvider per condividere file in modo sicuro tra app tramite Uri content:// temporaneo con FLAG_GRANT_READ_URI_PERMISSION.
Riepilogo
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.