Working with the file system is the foundation of any mobile application. Each platform offers its own access model: Sandbox on iOS isolates applications in separate containers, while Scoped Storage on Android restricts direct access to shared storage. According to Google Developer Documentation (2026), the introduction of Scoped Storage with Android 10 required a complete overhaul of data storage architecture. In this guide, we'll cover FileManager, MediaStore API, Storage Access Framework, and DocumentProvider for both platforms.
Key Takeaways
The file system in mobile applications is a set of APIs, security rules, and constraints that define how data is stored and accessed on iOS and Android devices. Unlike desktop operating systems, mobile platforms isolate each application to protect user data from unauthorized reading by other programs.
iOS uses the Sandbox model, where each app exists in its own container with strictly limited permissions. Before version 10, Android provided full access to external storage, but with the introduction of Scoped Storage, the approach became closer to iOS. The key difference is that iOS completely isolates the file system, while Android offers several access levels: a private directory, public MediaStore, and temporary access via SAF.
Mobile applications use three types of data storage. Private storage — a directory accessible only to the app for internal files and cache. Shared storage — media files via MediaStore (Android) or Files App (iOS). Cloud storage — iCloud Drive and Google Drive for synchronization between devices. Each type has its own limits on size, file lifetime, and access conditions.
| Storage Type | iOS | Android |
|---|---|---|
| Private | Documents, Library, Caches | getFilesDir(), getCacheDir() |
| Shared Media | PHPhotoLibrary via picker | MediaStore API (ContentResolver) |
| Shared Documents | Files App via UIDocumentPicker | Storage Access Framework (SAF) |
| Cloud | iCloud Drive (UIDocument) | Google Drive API |
| Cache | Caches Directory, cleared by system | getCacheDir(), getExternalCacheDir() |
Sandbox is iOS's security architecture that isolates each application. An app can read and write only inside its own sandbox. To access contacts, photos, or files from other apps, system pickers must be used: UIImagePickerController or UIDocumentPickerViewController. Access to Files App is configured via the UIFileSharingEnabled flag in Info.plist. File system in mobile development on iOS requires understanding the directory structure and choosing the right location for each data type.
The iOS sandbox consists of several standard directories. Documents — for user files, included in iCloud Backup. Caches — for temporary data that the system may delete when storage is low. Temporary — for current session files, cleared on restart. Application Support — for internal app data hidden from the user. Choosing the wrong directory leads to problems: saving cache in Documents wastes iCloud space and violates Apple's file system guidelines.
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 = "Содержимое файла"
// Atomic write with encryption
try text.write(
to: fileURL,
atomically: true,
encoding: .utf8
)
The FileManager class provides a complete set of methods for managing files on iOS. FileManager.default is a thread-safe singleton suitable for most operations. Methods like fileExists(atPath:), createDirectory(at:withIntermediateDirectories:attributes:), copyItem(at:to:), and removeItem(at:) cover basic scenarios. File operations larger than 1 MB should be performed on a background thread via DispatchQueue.global(). For streaming large volumes, use FileHandle instead of loading the entire file into memory.
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)
}
With the release of Android 10, Google introduced Scoped Storage — a restricted access model for the file system. An app can freely read and write only in its private directories. For media files (photos, videos, audio), the MediaStore API is used through ContentResolver. For arbitrary documents, the Storage Access Framework is used via Intent ACTION_OPEN_DOCUMENT. On Android 11+, direct access to the root of external storage is completely forbidden, and all developers must use the new APIs.
MediaStore is a system ContentProvider for accessing media files on the device. Through ContentResolver, the app requests file Uri instead of direct paths. MediaStore.Files — for all file types, Images — for images, Video — for video, Audio — for audio recordings. Writing to shared directories is done via insert() with DISPLAY_NAME, MIME_TYPE, and RELATIVE_PATH. After insertion, the app receives a Uri through which bytes are written. MIME types play a key role — an incorrect type will cause an error when opening the 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 provides a unified interface for selecting and creating files without runtime permissions. Intent ACTION_OPEN_DOCUMENT opens the system file manager on Android. After selection, the app receives a content:// Uri with temporary access via FLAG_GRANT_READ_URI_PERMISSION. ACTION_CREATE_DOCUMENT allows saving files to any external storage location chosen by the user. SAF works on Android 5+ and provides access to files from cloud providers connected through 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)
Both platforms provide built-in mechanisms for users to select files. Documents in mobile applications are passed through system pickers that grant temporary access to a file without permanent permissions. On iOS, this is UIDocumentPickerViewController; on Android, ACTION_OPEN_DOCUMENT. Documents in mobile applications can be selected from both local storage and cloud services. The user explicitly specifies the file, and the app receives a Uri or URL with a limited validity period.
UIDocumentPickerViewController opens Files App and allows selecting one or more documents. Modes: import (copy to sandbox) and open (access via security-scoped URL). For file filtering, an array of UTType types is passed — for example, .pdf and .plainText. After receiving the URL, the app must call startAccessingSecurityScopedResource() before reading and stopAccessingSecurityScopedResource() after finishing. Failing to call stopAccessing leads to system resource leaks. Documents in mobile applications on iOS require mandatory release of temporary permissions after finishing work with the file.
let picker = UIDocumentPickerViewController(
forOpeningContentTypes: [.pdf, .plainText]
)
picker.allowsMultipleSelection = true
picker.delegate = self
present(picker, animated: true)
// Releasing access in the delegate
func documentPicker(
_ controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL]
) {
guard let url = urls.first else { return }
url.startAccessingSecurityScopedResource()
defer { url.stopAccessingSecurityScopedResource() }
}
FileProvider is a subclass of ContentProvider for securely sharing files between apps. It generates temporary content:// Uri based on files from specified XML directories. Other apps get access via Intent with FLAG_GRANT_READ_URI_PERMISSION. DocumentProvider, unlike FileProvider, publishes files in SAF and allows other apps to browse your app's contents as part of the file system. To implement DocumentsProvider, you need to override queryRoots(), queryChildDocuments(), and openDocument(), then register it in AndroidManifest.xml
Cloud synchronization gives users access to documents on all their devices. The file system in mobile applications is enhanced by a cloud layer: UIDocument on iOS automatically tracks changes and syncs them via iCloud. On Android, similar functionality is built through the Google Drive API or DocumentsProvider with cloud roots. Understanding the file system in mobile development is critical for building reliable cross-device synchronization.
UIDocument is an abstract class for working with iCloud documents. It automatically saves changes, reads data, and notifies the delegate of updates. On write conflict, NSFileVersion provides a list of available versions — the developer can choose the latest or show the user conflict resolution options. Configuring Ubiquity Container in project Capabilities is mandatory for iCloud Drive. NSFileCoordinator and NSFilePresenter prevent data races during concurrent access from multiple threads or devices.
iOS automatically includes the Documents Directory in iCloud Backup. Android works with Auto Backup for Apps — the system saves data from getFilesDir(), SharedPreferences, and SQLite databases to Google Drive. Cache and external files are not included in backups. Both platforms allow configuring exclusions: on iOS via NSURLIsExcludedFromBackupKey, on Android via XML backup rules configuration. Encryption of files with personal data is mandatory — on iOS use NSDataWritingFileProtectionComplete, on Android use EncryptedFile from the security-crypto library.
| Parameter | iOS | Android |
|---|---|---|
| Default Backup | Documents and Library | getFilesDir(), SharedPreferences, DB |
| File Exclusion | isExcludedFromBackupKey | XML backup rules (fullBackupContent) |
| Encryption | NSDataWritingFileProtectionComplete | EncryptedFile (security-crypto) |
| Cloud Sync | UIDocument + iCloud | Google Drive API + SAF |
| Auto Restore | iCloud Restore after installation | Auto Backup on reinstall |
Frequently Asked Questions
Sandbox is an isolated environment for each app on iOS. The app cannot access files from other apps without using system pickers like UIDocumentPickerViewController.
Scoped Storage is a restricted file system access model on Android 10+. The app directly reads only its own files, uses MediaStore API for media, and Storage Access Framework for documents.
Use UIDocumentPickerViewController — the system picker for selecting documents from Files App or iCloud Drive. After selection, you receive a security-scoped URL with temporary access.
For media files, use MediaStore API through ContentResolver with the MIME type specified. For arbitrary documents, use Storage Access Framework with Intent ACTION_OPEN_DOCUMENT.
FileProvider is a subclass of ContentProvider for securely sharing files between apps via temporary content:// Uri with FLAG_GRANT_READ_URI_PERMISSION.
Summary
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.