Trabajar con el sistema de archivos es la base de cualquier aplicación móvil. Cada plataforma ofrece su propio modelo de acceso: Sandbox en iOS aísla las aplicaciones en contenedores separados, mientras que Scoped Storage en Android restringe el acceso directo al almacenamiento compartido. Según Google Developer Documentation (2026), la introducción de Scoped Storage con Android 10 requirió una revisión completa de la arquitectura de almacenamiento de datos. En esta guía cubriremos FileManager, MediaStore API, Storage Access Framework y DocumentProvider para ambas plataformas.
Puntos clave
El sistema de archivos en aplicaciones móviles es un conjunto de API, reglas de seguridad y restricciones que definen cómo se almacenan y acceden los datos en dispositivos iOS y Android. A diferencia de los sistemas operativos de escritorio, las plataformas móviles aíslan cada aplicación para proteger los datos del usuario contra lecturas no autorizadas por otros programas.
iOS utiliza el modelo Sandbox, donde cada aplicación existe en su propio contenedor con permisos estrictamente limitados. Antes de la versión 10, Android proporcionaba acceso completo al almacenamiento externo, pero con la introducción de Scoped Storage, el enfoque se acercó más a iOS. La diferencia clave es que iOS aísla completamente el sistema de archivos, mientras que Android ofrece varios niveles de acceso: un directorio privado, MediaStore público y acceso temporal a través de SAF.
Las aplicaciones móviles utilizan tres tipos de almacenamiento de datos. Almacenamiento privado — un directorio accesible solo para la aplicación para archivos internos y caché. Almacenamiento compartido — archivos multimedia a través de MediaStore (Android) o Files App (iOS). Almacenamiento en la nube — iCloud Drive y Google Drive para sincronización entre dispositivos. Cada tipo tiene sus propios límites de tamaño, vida útil de los archivos y condiciones de acceso.
| Tipo de almacenamiento | iOS | Android |
|---|---|---|
| Privado | Documents, Library, Caches | getFilesDir(), getCacheDir() |
| Multimedia compartido | PHPhotoLibrary mediante selector | MediaStore API (ContentResolver) |
| Documentos compartidos | Files App mediante UIDocumentPicker | Storage Access Framework (SAF) |
| Nube | iCloud Drive (UIDocument) | Google Drive API |
| Caché | Directorio Caches, limpiado por el sistema | getCacheDir(), getExternalCacheDir() |
Sandbox es la arquitectura de seguridad de iOS que aísla cada aplicación. Una aplicación solo puede leer y escribir dentro de su propia zona de pruebas. Para acceder a contactos, fotos o archivos de otras aplicaciones, se deben utilizar selectores del sistema: UIImagePickerController o UIDocumentPickerViewController. El acceso a Files App se configura mediante el indicador UIFileSharingEnabled en Info.plist. El sistema de archivos en el desarrollo móvil en iOS requiere comprender la estructura de directorios y elegir la ubicación correcta para cada tipo de datos.
La zona de pruebas de iOS consta de varios directorios estándar. Documents — para archivos de usuario, incluido en iCloud Backup. Caches — para datos temporales que el sistema puede eliminar cuando el almacenamiento es escaso. Temporary — para archivos de la sesión actual, se borra al reiniciar. Application Support — para datos internos de la aplicación ocultos al usuario. Elegir el directorio incorrecto genera problemas: guardar caché en Documents desperdicia espacio en iCloud y viola las pautas de Apple sobre el sistema de archivos.
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 = "Содержимое файла"
// Escritura atómica con cifrado
try text.write(
to: fileURL,
atomically: true,
encoding: .utf8
)
La clase FileManager proporciona un conjunto completo de métodos para gestionar archivos en iOS. FileManager.default es un singleton seguro para subprocesos adecuado para la mayoría de las operaciones. Métodos como fileExists(atPath:), createDirectory(at:withIntermediateDirectories:attributes:), copyItem(at:to:) y removeItem(at:) cubren escenarios básicos. Las operaciones con archivos de más de 1 MB deben realizarse en un subproceso en segundo plano mediante DispatchQueue.global(). Para transmitir grandes volúmenes, use FileHandle en lugar de cargar todo el archivo en 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 el lanzamiento de Android 10, Google introdujo Scoped Storage — un modelo de acceso restringido al sistema de archivos. Una aplicación puede leer y escribir libremente solo en sus directorios privados. Para archivos multimedia (fotos, videos, audio), se utiliza MediaStore API a través de ContentResolver. Para documentos arbitrarios, se utiliza Storage Access Framework mediante Intent ACTION_OPEN_DOCUMENT. En Android 11+, el acceso directo a la raíz del almacenamiento externo está completamente prohibido, y todos los desarrolladores deben usar las nuevas API.
MediaStore es un ContentProvider del sistema para acceder a archivos multimedia en el dispositivo. A través de ContentResolver, la aplicación solicita Uri de archivos en lugar de rutas directas. MediaStore.Files — para todos los tipos de archivos, Images — para imágenes, Video — para video, Audio — para grabaciones de audio. La escritura en directorios compartidos se realiza mediante insert() con DISPLAY_NAME, MIME_TYPE y RELATIVE_PATH. Después de la inserción, la aplicación recibe una Uri a través de la cual se escriben los bytes. Los tipos MIME juegan un papel clave: un tipo incorrecto provocará un error al abrir el archivo.
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 proporciona una interfaz unificada para seleccionar y crear archivos sin permisos en tiempo de ejecución. Intent ACTION_OPEN_DOCUMENT abre el administrador de archivos del sistema en Android. Después de la selección, la aplicación recibe una Uri content:// con acceso temporal mediante FLAG_GRANT_READ_URI_PERMISSION. ACTION_CREATE_DOCUMENT permite guardar archivos en cualquier ubicación de almacenamiento externo elegida por el usuario. SAF funciona en Android 5+ y proporciona acceso a archivos de proveedores en la nube conectados a través de 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)
Ambas plataformas proporcionan mecanismos integrados para que los usuarios seleccionen archivos. Los documentos en aplicaciones móviles se pasan a través de selectores del sistema que otorgan acceso temporal a un archivo sin permisos permanentes. En iOS, esto es UIDocumentPickerViewController; en Android, ACTION_OPEN_DOCUMENT. Los documentos en aplicaciones móviles se pueden seleccionar tanto del almacenamiento local como de servicios en la nube. El usuario especifica explícitamente el archivo y la aplicación recibe una Uri o URL con un período de validez limitado.
UIDocumentPickerViewController abre Files App y permite seleccionar uno o más documentos. Modos: importar (copiar a la zona de pruebas) y abrir (acceso mediante URL con ámbito de seguridad). Para filtrar archivos, se pasa una matriz de tipos UTType — por ejemplo, .pdf y .plainText. Después de recibir la URL, la aplicación debe llamar a startAccessingSecurityScopedResource() antes de leer y a stopAccessingSecurityScopedResource() después de terminar. No llamar a stopAccessing provoca fugas de recursos del sistema. Los documentos en aplicaciones móviles en iOS requieren la liberación obligatoria de permisos temporales después de terminar de trabajar con el archivo.
let picker = UIDocumentPickerViewController(
forOpeningContentTypes: [.pdf, .plainText]
)
picker.allowsMultipleSelection = true
picker.delegate = self
present(picker, animated: true)
// Liberando el acceso en el delegado
func documentPicker(
_ controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL]
) {
guard let url = urls.first else { return }
url.startAccessingSecurityScopedResource()
defer { url.stopAccessingSecurityScopedResource() }
}
FileProvider es una subclase de ContentProvider para compartir archivos de forma segura entre aplicaciones. Genera Uri content:// temporales basadas en archivos de directorios XML especificados. Otras aplicaciones obtienen acceso mediante Intent con FLAG_GRANT_READ_URI_PERMISSION. DocumentProvider, a diferencia de FileProvider, publica archivos en SAF y permite que otras aplicaciones naveguen por el contenido de su aplicación como parte del sistema de archivos. Para implementar DocumentsProvider, debe sobrescribir queryRoots(), queryChildDocuments() y openDocument(), luego registrarlo en AndroidManifest.xml
La sincronización en la nube brinda a los usuarios acceso a documentos en todos sus dispositivos. El sistema de archivos en aplicaciones móviles se complementa con una capa en la nube: UIDocument en iOS rastrea automáticamente los cambios y los sincroniza a través de iCloud. En Android, una funcionalidad similar se construye a través de Google Drive API o DocumentsProvider con raíces en la nube. Comprender el sistema de archivos en el desarrollo móvil es fundamental para construir una sincronización confiable entre dispositivos.
UIDocument es una clase abstracta para trabajar con documentos de iCloud. Guarda automáticamente los cambios, lee datos y notifica al delegado sobre las actualizaciones. En caso de conflicto de escritura, NSFileVersion proporciona una lista de versiones disponibles: el desarrollador puede elegir la más reciente o mostrar al usuario opciones de resolución de conflictos. La configuración de Ubiquity Container en las Capacidades del proyecto es obligatoria para iCloud Drive. NSFileCoordinator y NSFilePresenter evitan condiciones de carrera durante el acceso concurrente desde múltiples subprocesos o dispositivos.
iOS incluye automáticamente el directorio Documents en iCloud Backup. Android funciona con Auto Backup for Apps — el sistema guarda datos de getFilesDir(), SharedPreferences y bases de datos SQLite en Google Drive. La caché y los archivos externos no se incluyen en las copias de seguridad. Ambas plataformas permiten configurar exclusiones: en iOS mediante NSURLIsExcludedFromBackupKey, en Android mediante configuración XML de reglas de copia de seguridad. El cifrado de archivos con datos personales es obligatorio — en iOS use NSDataWritingFileProtectionComplete, en Android use EncryptedFile de la biblioteca security-crypto.
| Parámetro | iOS | Android |
|---|---|---|
| Copia de seguridad predeterminada | Documents y Library | getFilesDir(), SharedPreferences, BD |
| Exclusión de archivos | isExcludedFromBackupKey | Reglas XML de backup (fullBackupContent) |
| Cifrado | NSDataWritingFileProtectionComplete | EncryptedFile (security-crypto) |
| Sincronización en la nube | UIDocument + iCloud | Google Drive API + SAF |
| Restauración automática | iCloud Restore después de la instalación | Auto Backup al reinstalar |
Preguntas frecuentes
Sandbox es un entorno aislado para cada aplicación en iOS. La aplicación no puede acceder a archivos de otras aplicaciones sin usar selectores del sistema como UIDocumentPickerViewController.
Scoped Storage es un modelo de acceso restringido al sistema de archivos en Android 10+. La aplicación lee directamente solo sus propios archivos, usa MediaStore API para multimedia y Storage Access Framework para documentos.
Use UIDocumentPickerViewController — el selector del sistema para elegir documentos de Files App o iCloud Drive. Después de la selección, recibe una URL con ámbito de seguridad y acceso temporal.
Para archivos multimedia, use MediaStore API a través de ContentResolver especificando el tipo MIME. Para documentos arbitrarios, use Storage Access Framework con Intent ACTION_OPEN_DOCUMENT.
FileProvider es una subclase de ContentProvider para compartir archivos de forma segura entre aplicaciones mediante Uri content:// temporal con FLAG_GRANT_READ_URI_PERMISSION.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.