Работата с файлова система е основата на всяко мобилно приложение. Всяка платформа предлага свой модел на достъп: Sandbox в iOS изолира приложенията в отделни контейнери, докато Scoped Storage в Android ограничава директния достъп до споделеното хранилище. Според Google Developer Documentation (2026), въвеждането на Scoped Storage с Android 10 изисква пълно преразглеждане на архитектурата за съхранение на данни. В това ръководство ще разгледаме FileManager, MediaStore API, Storage Access Framework и DocumentProvider за двете платформи.
Основни точки
Файловата система в мобилните приложения е набор от API, правила за сигурност и ограничения, които определят съхранението и достъпа до данни на устройства с iOS и Android. За разлика от десктоп операционните системи, мобилните платформи изолират всяко приложение, за да защитят данните на потребителя от неоторизирано четене от други програми.
iOS използва модела Sandbox, където всяко приложение съществува в собствен контейнер със строго ограничени права. Преди версия 10 Android предоставяше пълен достъп до външно хранилище, но с въвеждането на Scoped Storage подходът се доближи до iOS. Ключовата разлика е, че iOS напълно изолира файловата система, докато Android предлага няколко нива на достъп: частна директория, публичен MediaStore и временен достъп чрез SAF.
Мобилните приложения използват три типа съхранение на данни. Частно хранилище — директория, достъпна само за приложението, за вътрешни файлове и кеш. Споделено хранилище — медийни файлове чрез MediaStore (Android) или Files App (iOS). Облачно хранилище — iCloud Drive и Google Drive за синхронизация между устройства. Всеки тип има свои ограничения по отношение на размер, живот на файловете и условия за достъп.
| Тип хранилище | iOS | Android |
|---|---|---|
| Частно | Documents, Library, Caches | getFilesDir(), getCacheDir() |
| Споделени медии | PHPhotoLibrary чрез избирач | MediaStore API (ContentResolver) |
| Споделени документи | Files App чрез UIDocumentPicker | Storage Access Framework (SAF) |
| Облак | iCloud Drive (UIDocument) | Google Drive API |
| Кеш | Директория Caches, почиства се от системата | getCacheDir(), getExternalCacheDir() |
Sandbox е архитектурата за сигурност на iOS, която изолира всяко приложение. Едно приложение може да чете и пише само в своята пясъчна кутия. За достъп до контакти, снимки или файлове на други приложения трябва да се използват системни избирачи: UIImagePickerController или UIDocumentPickerViewController. Достъпът до Files App се конфигурира чрез флага UIFileSharingEnabled в Info.plist. Файловата система в мобилната разработка на iOS изисква разбиране на структурата на директориите и правилен избор на място за всеки тип данни.
Пясъчната кутия на iOS се състои от няколко стандартни директории. Documents — за потребителски файлове, включена в iCloud Backup. Caches — за временни данни, които системата може да изтрие при недостатъчно място. Temporary — за файлове от текущата сесия, изчиства се при рестартиране. Application Support — за вътрешни данни на приложението, скрити от потребителя. Изборът на грешна директория води до проблеми: запазването на кеш в Documents губи място в iCloud и нарушава указанията на Apple за файловата система.
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 = "Содержимое файла"
// Атомен запис с криптиране
try text.write(
to: fileURL,
atomically: true,
encoding: .utf8
)
Класът FileManager предоставя пълен набор от методи за управление на файлове в iOS. FileManager.default е thread-safe сингълтън, подходящ за повечето операции. Методи като fileExists(atPath:), createDirectory(at:withIntermediateDirectories:attributes:), copyItem(at:to:) и removeItem(at:) покриват основни сценарии. Операции с файлове, по-големи от 1 MB, трябва да се изпълняват във фонова нишка чрез DispatchQueue.global(). За поточно предаване на големи обеми използвайте FileHandle вместо зареждане на целия файл в паметта.
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)
}
С пускането на Android 10 Google въведе Scoped Storage — модел с ограничен достъп до файловата система. Приложението може свободно да чете и пише само в своите частни директории. За медийни файлове (снимки, видео, аудио) се използва MediaStore API чрез ContentResolver. За произволни документи се използва Storage Access Framework чрез Intent ACTION_OPEN_DOCUMENT. На Android 11+ директният достъп до корена на външното хранилище е напълно забранен и всички разработчици трябва да използват новите API.
MediaStore е системен ContentProvider за достъп до медийни файлове на устройството. Чрез ContentResolver приложението изисква Uri на файлове вместо директни пътища. MediaStore.Files — за всички типове файлове, Images — за изображения, Video — за видео, Audio — за аудио записи. Записването в споделени директории се извършва чрез insert() с DISPLAY_NAME, MIME_TYPE и RELATIVE_PATH. След вмъкването приложението получава Uri, чрез което се записват байтове. MIME типовете играят ключова роля — неправилен тип ще причини грешка при отваряне на файла.
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 предоставя унифициран интерфейс за избор и създаване на файлове без права по време на изпълнение. Intent ACTION_OPEN_DOCUMENT отваря системния файлов мениджър на Android. След избор приложението получава content:// Uri с временен достъп чрез FLAG_GRANT_READ_URI_PERMISSION. ACTION_CREATE_DOCUMENT позволява запазване на файлове на всяко външно място за съхранение, избрано от потребителя. SAF работи на Android 5+ и предоставя достъп до файлове от облачни доставчици, свързани чрез 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)
И двете платформи предоставят вградени механизми за избор на файлове от потребителите. Документите в мобилни приложения се предават чрез системни избирачи, които предоставят временен достъп до файл без постоянни права. В iOS това е UIDocumentPickerViewController, в Android — ACTION_OPEN_DOCUMENT. Документите в мобилни приложения могат да се избират както от локално хранилище, така и от облачни услуги. Потребителят изрично посочва файла, а приложението получава Uri или URL с ограничен срок на валидност.
UIDocumentPickerViewController отваря Files App и позволява избор на един или повече документи. Режими: импорт (копиране в пясъчната кутия) и отваряне (достъп чрез URL с обхват на сигурност). За филтриране на файлове се предава масив от типове UTType — например .pdf и .plainText. След получаване на URL приложението трябва да извика startAccessingSecurityScopedResource() преди четене и stopAccessingSecurityScopedResource() след завършване. Неизвикването на stopAccessing води до изтичане на системни ресурси. Документите в мобилни приложения на iOS изискват задължително освобождаване на временните права след приключване на работа с файла.
let picker = UIDocumentPickerViewController(
forOpeningContentTypes: [.pdf, .plainText]
)
picker.allowsMultipleSelection = true
picker.delegate = self
present(picker, animated: true)
// Освобождаване на достъпа в делегата
func documentPicker(
_ controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL]
) {
guard let url = urls.first else { return }
url.startAccessingSecurityScopedResource()
defer { url.stopAccessingSecurityScopedResource() }
}
FileProvider е подклас на ContentProvider за сигурно споделяне на файлове между приложения. Той генерира временни content:// Uri въз основа на файлове от указани XML директории. Други приложения получават достъп чрез Intent с FLAG_GRANT_READ_URI_PERMISSION. DocumentProvider, за разлика от FileProvider, публикува файлове в SAF и позволява на други приложения да разглеждат съдържанието на вашето приложение като част от файловата система. За да имплементирате DocumentsProvider, трябва да презапишете queryRoots(), queryChildDocuments() и openDocument(), след което да го регистрирате в AndroidManifest.xml
Облачната синхронизация дава на потребителите достъп до документи на всичките им устройства. Файловата система в мобилни приложения е допълнена от облачен слой: UIDocument в iOS автоматично проследява промените и ги синхронизира чрез iCloud. В Android подобна функционалност се изгражда чрез Google Drive API или DocumentsProvider с облачни корени. Разбирането на файловата система в мобилната разработка е от решаващо значение за изграждане на надеждна синхронизация между устройства.
UIDocument е абстрактен клас за работа с iCloud документи. Той автоматично запазва промените, чете данни и уведомява делегата за актуализации. При конфликт на запис NSFileVersion предоставя списък с налични версии — разработчикът може да избере най-новата или да покаже на потребителя опции за разрешаване на конфликта. Конфигурирането на Ubiquity Container в Capabilities на проекта е задължително за iCloud Drive. NSFileCoordinator и NSFilePresenter предотвратяват състезания на данни при едновременен достъп от множество нишки или устройства.
iOS автоматично включва директорията Documents в iCloud Backup. Android работи с Auto Backup for Apps — системата запазва данни от getFilesDir(), SharedPreferences и SQLite бази данни в Google Drive. Кешът и външните файлове не се включват в резервните копия. И двете платформи позволяват конфигуриране на изключения: в iOS чрез NSURLIsExcludedFromBackupKey, в Android чрез XML конфигурация на правила за архивиране. Криптирането на файлове с лични данни е задължително — в iOS използвайте NSDataWritingFileProtectionComplete, в Android използвайте EncryptedFile от библиотеката security-crypto.
| Параметър | iOS | Android |
|---|---|---|
| Резервно копие по подразбиране | Documents и Library | getFilesDir(), SharedPreferences, БД |
| Изключение на файлове | isExcludedFromBackupKey | XML правила за архивиране (fullBackupContent) |
| Криптиране | NSDataWritingFileProtectionComplete | EncryptedFile (security-crypto) |
| Облачна синхронизация | UIDocument + iCloud | Google Drive API + SAF |
| Автоматично възстановяване | iCloud Restore след инсталиране | Auto Backup при повторно инсталиране |
Често задавани въпроси
Sandbox е изолирана среда за всяко приложение в iOS. Приложението няма достъп до файлове на други приложения без използване на системни избирачи като UIDocumentPickerViewController.
Scoped Storage е модел с ограничен достъп до файловата система в Android 10+. Приложението чете директно само своите файлове, използва MediaStore API за медии и Storage Access Framework за документи.
Използвайте UIDocumentPickerViewController — системния избирач за избор на документи от Files App или iCloud Drive. След избора получавате URL с обхват на сигурност и временен достъп.
За медийни файлове използвайте MediaStore API чрез ContentResolver с посочване на MIME тип. За произволни документи използвайте Storage Access Framework с Intent ACTION_OPEN_DOCUMENT.
FileProvider е подклас на ContentProvider за сигурно споделяне на файлове между приложения чрез временно content:// Uri с FLAG_GRANT_READ_URI_PERMISSION.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.