Katalog dokumentów aplikacji to stałe miejsce przechowywania plików użytkownika, które powinny być zachowywane między sesjami i przywracane z kopii zapasowej. Według Apple File System Programming Guide, 2026, w systemie iOS katalog Documents jest automatycznie uwzględniany w kopii zapasowej iCloud, w przeciwieństwie do pamięci podręcznej i katalogów tymczasowych. Prawidłowe korzystanie z katalogu dokumentów gwarantuje, że pliki użytkownika nie zostaną utracone podczas aktualizacji lub ponownej instalacji aplikacji.
Najważniejsze
context.filesDir z ręcznym zarządzaniem kopiami zapasowymiKatalog dokumentów to specjalistyczne miejsce przechowywania w piaskownicy aplikacji, przeznaczone do stałego przechowywania plików użytkownika. W przeciwieństwie do pamięci podręcznej, pliki w tym katalogu są uważane za ważne dla użytkownika: nie są usuwane przez system przy braku miejsca, są zachowywane podczas aktualizacji aplikacji i kopiowane zapasowo podczas synchronizacji urządzenia. W systemie iOS katalog Documents jest częścią kontenera Sandbox i jest automatycznie uwzględniany w kopii zapasowej iCloud. W systemie Android nie ma bezpośredniego odpowiednika — odpowiednikiem jest context.filesDir, który również jest przeznaczony do stałych plików, ale nie ma wbudowanego mechanizmu kopii zapasowej.
Różnica między katalogiem dokumentów a wewnętrznym przechowywaniem (Internal Storage) na Androidzie jest minimalna: oba znajdują się w piaskownicy aplikacji, oba są usuwane przy odinstalowaniu, oba są niedostępne dla innych aplikacji. Główna różnica jest semantyczna: Documents Directory zakłada, że pliki zostały utworzone lub zaimportowane przez użytkownika, podczas gdy Internal Storage może zawierać wewnętrzne pliki aplikacji (bazy danych, konfiguracje). W systemie iOS różnica jest bardziej znacząca: Documents jest automatycznie kopiowany zapasowo, a Library/Application Support — nie. Wpływa to na strategię przechowywania: w Documents umieszczaj tylko to, co użytkownik chce przywrócić na nowym urządzeniu, a w Application Support — dane wewnętrzne, które aplikacja może odtworzyć.
Architektura piaskownicy gwarantuje, że inne aplikacje nie mają dostępu do katalogu dokumentów twojej aplikacji. W systemie iOS dostęp do Documents innych aplikacji jest niemożliwy bez jailbreak. W systemie Android dostęp root pozwala odczytać filesDir dowolnej aplikacji, dlatego poufne dane (tokeny, klucze szyfrowania) należy dodatkowo zabezpieczać za pomocą EncryptedSharedPreferences lub EncryptedFile z biblioteki AndroidX Security.
W katalogu dokumentów należy umieszczać dane, które mają wartość dla użytkownika i powinny być dostępne po ponownym uruchomieniu aplikacji lub przywróceniu urządzenia. Nie wszystkie pliki nadają się do przechowywania w tym katalogu — wybór zależy od typu danych i scenariusza użycia.
Pliki użytkownika — główna zawartość katalogu dokumentów. Mogą to być dokumenty tekstowe utworzone w edytorze, zdjęcia zrobione aparatem aplikacji, wyeksportowane raporty PDF, nagrania audio, notatki. Każdy taki plik został utworzony przez użytkownika lub na jego żądanie i powinien być dostępny w każdej chwili. W systemie iOS pliki z Documents są wyświetlane w systemowej aplikacji Files, co pozwala użytkownikowi zarządzać nimi przez standardowy menedżer plików. W systemie Android nie ma podobnego wyświetlania — aplikacja samodzielnie musi zapewnić interfejs do przeglądania zapisanych plików.
Bazy danych SQLite i pliki ustawień są zwykle przechowywane obok katalogu dokumentów, ale nie w nim samym. W systemie iOS bazy danych umieszcza się w Library/Application Support, ponieważ nie powinny być wyświetlane w aplikacji Files i kopiowane zapasowo osobno. W systemie Android bazy danych domyślnie tworzone są w /data/data/<package>/databases/ przez Room lub SQLiteOpenHelper. Jeśli baza danych zawiera treści użytkownika (notatki, dziennik, zapisy finansowe), można umieścić ją w filesDir, aby zapewnić kopię zapasową przez system. Room pozwala wskazać niestandardowy katalog do przechowywania bazy danych przez callback RoomDatabase.Builder.
val dbFile = File(context.filesDir, "user_database.db")
val db = Room.databaseBuilder<AppDatabase>(
context,
dbFile.absolutePath
).build()
Pliki, które użytkownik importuje z innych aplikacji lub eksportuje z twojej aplikacji, również powinny być zapisywane w katalogu dokumentów. W systemie iOS import przez UIDocumentPickerViewController automatycznie umieszcza kopię pliku w Documents przy użyciu parametru asCopy: true. W systemie Android import przez dialog SAF również tworzy kopię pliku w piaskownicy aplikacji. Podczas eksportu danych (np. tworzenie pliku CSV z kontaktami) zapisz plik najpierw w Documents/filesDir, a następnie zaproponuj użytkownikowi udostępnienie go przez Share Sheet. Gwarantuje to, że nawet jeśli użytkownik zapomni zapisać plik po wysłaniu, kopia pozostanie w aplikacji do późniejszego wykorzystania.
Na Androidzie funkcje katalogu dokumentów pełni context.filesDir. Dodatkowo dostępny jest katalog context.externalFilesDir na karcie SD, ale nie gwarantuje on zachowania danych. Omówmy główne techniki pracy z tymi katalogami.
filesDir — główny katalog dla stałych plików aplikacji na Androidzie. Znajduje się w piaskownicy aplikacji i jest całkowicie usuwany przy odinstalowaniu. Aby uzyskać instancję File, użyj context.filesDir, który zwraca ścieżkę do katalogu /data/data/<package>/files/. Do tworzenia i odczytu plików używaj standardowych operacji File w Javie/Kotlinie lub metod Context openFileInput() i openFileOutput(), które przyjmują nazwę pliku i zwracają FileInputStream/FileOutputStream. Metoda openFileOutput() automatycznie tworzy plik w filesDir, jeśli jeszcze nie istnieje, i pozwala określić tryb dostępu: MODE_PRIVATE (tylko bieżąca aplikacja), MODE_APPEND (dopisywanie) lub MODE_WORLD_READABLE (przestarzałe, nieużywane od API 24+).
val fileName = "report.pdf"
val content = "PDF content".toByteArray()
context.openFileOutput(fileName, Context.MODE_PRIVATE).use { stream ->
stream.write(content)
}
val bytes = context.openFileInput(fileName).use { stream ->
stream.readBytes()
}
Na Android 10+ model Scoped Storage nie wpływa na filesDir — dostęp do własnej piaskownicy aplikacji pozostaje pełny. Wszystkie operacje odczytu i zapisu w filesDir nie wymagają dodatkowych uprawnień. Jednak przy próbie dostępu do plików innej aplikacji przez filesDir otrzymasz wyjątek. Do wymiany plików używaj FileProvider, który tworzy tymczasowy content URI do przekazania pliku innej aplikacji. FileProvider jest deklarowany w AndroidManifest.xml przez znacznik <provider> i konfigurowany w pliku XML ścieżek. Jest to standardowy mechanizm przesyłania plików między aplikacjami, używany na przykład przy wysyłaniu obrazu przez Intent z ACTION_SEND.
W systemie iOS Documents Directory jest częścią kontenera Sandbox aplikacji o specjalnym statusie. Pliki z tego katalogu są automatycznie uwzględniane w kopii zapasowej iCloud, wyświetlane w aplikacji Files i zachowywane podczas aktualizacji aplikacji przez App Store.
Automatyczne kopie zapasowe Documents — kluczowa zaleta iOS. Gdy użytkownik podłącza urządzenie do iTunes lub włącza iCloud Backup, wszystkie pliki z Documents/ są kopiowane do kopii zapasowej. Przy przywracaniu na nowym urządzeniu użytkownik otrzymuje wszystkie swoje pliki bez dodatkowych działań. Jednak ta zaleta staje się wadą, jeśli aplikacja przechowuje w Documents duże ilości danych: czas tworzenia kopii zapasowej wydłuża się, a przestrzeń iCloud może szybko się skończyć. Dlatego w Documents należy przechowywać tylko te pliki, które są rzeczywiście potrzebne użytkownikowi przy przywracaniu. Pliki tymczasowe, pamięć podręczna i dane do odtworzenia powinny znajdować się w Caches lub Library/Application Support. Apple zaleca wykluczanie z kopii zapasowej plików, które można ponownie pobrać z internetu, poprzez atrybut isExcludedFromBackup.
let fm = FileManager.default
let docsURL = fm.urls(
for: .documentDirectory,
in: .userDomainMask
).first!
let fileURL = docsURL.appendingPathComponent("notes.txt")
let text = "Treść notatki"
try text.write(to: fileURL, atomically: true, encoding: .utf8)
iCloud Drive umożliwia synchronizację plików z Documents między urządzeniami tego samego użytkownika. Aby włączyć synchronizację, aplikacja powinna używać API NSDocument lub UIDocument, które automatycznie zarządzają wersjonowaniem i rozwiązywaniem konfliktów. Alternatywne podejście — użycie iCloud z CloudKit, które zapewnia bardziej elastyczną kontrolę nad synchronizacją, ale wymaga konfiguracji na CloudKit Dashboard. Podczas korzystania z iCloud Drive upewnij się, że poprawnie obsługujesz konflikty edycji (merge lub last-write-wins) i informujesz użytkownika o stanie synchronizacji przez interfejs aplikacji. iCloud nie gwarantuje natychmiastowej synchronizacji — opóźnienie może wynosić od kilku sekund do kilku minut w zależności od rozmiaru pliku i jakości połączenia. W przypadku krytycznie ważnych danych używaj zapisu transakcyjnego i wersjonowania, aby w razie konfliktu można było przywrócić poprzednią wersję pliku.
Prawidłowy wybór między Documents Directory a Cache Directory decyduje o niezawodności przechowywania danych użytkownika. Błąd w wyborze prowadzi albo do utraty danych (jeśli ważne pliki są przechowywane w pamięci podręcznej), albo do przepełnienia kopii zapasowej (jeśli pliki tymczasowe są przechowywane w Documents).
| Kryterium | Documents Directory | Cache Directory |
|---|---|---|
| Gwarancja zachowania | Wysoka — nie usuwane przez system | Niska — może zostać wyczyszczona |
| Kopia zapasowa (iOS) | Automatycznie w iCloud | Nie kopiowana |
| Widoczność dla użytkownika (iOS) | W aplikacji Files | Ukryta |
| Czyszczenie przy aktualizacji | Nie czyszczona | Może być czyszczona |
| Zalecany rozmiar | Dowolny, ale z kontrolą przez ustawienia | Do 100–200 MB |
| Typ danych | Pliki użytkownika | Tymczasowe dane do odtworzenia |
Najlepsze praktyki korzystania z katalogu dokumentów obejmują kilka kluczowych zasad. Po pierwsze, zawsze pytaj użytkownika o potwierdzenie przed usunięciem plików z tego katalogu. W przeciwieństwie do pamięci podręcznej, usunięcie dokumentu może prowadzić do nieodwracalnej utraty treści użytkownika. Po drugie, zaimplementuj wersjonowanie plików: przy nadpisywaniu istniejącego pliku zachowaj poprzednią wersję z sufiksem _backup lub użyj mechanizmów Snapshot. Po trzecie, zapewnij użytkownikowi interfejs do przeglądania, zmiany nazwy, usuwania i eksportowania plików z katalogu dokumentów. W systemie iOS pliki z Documents są automatycznie wyświetlane w Files, w systemie Android należy zaimplementować własny menedżer plików lub użyć bibliotek zewnętrznych.
Szczególną uwagę zwróć na migrację danych podczas aktualizacji aplikacji. Jeśli nowa wersja zmienia strukturę przechowywania plików (np. przenosi dane z jednego podkatalogu do innego lub zmienia format plików), zaimplementuj jednorazową migrację przy pierwszym uruchomieniu po aktualizacji. Przechowuj numer wersji schematu danych w SharedPreferences i przy niezgodności uruchamiaj migrację. Nie usuwaj starych plików do czasu zakończenia migracji — w razie awarii użytkownik nie powinien stracić danych. Jeśli migracja obejmuje konwersję formatu (np. przejście z JSON na SQLite), zachowaj oryginalne pliki jako kopię zapasową w osobnym katalogu z datą migracji. Użytkownik powinien mieć możliwość wycofania zmian przez ustawienia aplikacji w ciągu pierwszych 30 dni po aktualizacji, zgodnie z zaleceniami Apple Human Interface Guidelines.
Często zadawane pytania
Documents jest wyświetlane w aplikacji Files i automatycznie kopiowane zapasowo w iCloud. Application Support nie jest wyświetlane w Files i nie jest domyślnie kopiowane zapasowo. Wybieraj Application Support dla wewnętrznych danych aplikacji, które nie muszą być pokazywane użytkownikowi.
Tak, przy usuwaniu konta zaproponuj użytkownikowi wyczyszczenie wszystkich lokalnych plików powiązanych z tym kontem. Pokaż okno dialogowe z pytaniem „Usunąć wszystkie lokalne dane?” i wymień, które pliki zostaną objęte. Jest to wymóg RODO i zgodności z politykami App Store oraz Google Play.
Na iOS wystarczy przywrócić urządzenie z kopii zapasowej iCloud lub iTunes — pliki z Documents są przywracane automatycznie. Na Androidzie użyj Google Drive Backup API do kopiowania zapasowego plików z filesDir lub zaimplementuj eksport przez usługę chmurową.
Na iOS użytkownik może usunąć pliki przez aplikację Files. Na Androidzie usunięcie jest możliwe tylko przez interfejs twojej aplikacji. Zaleca się zaimplementowanie kosza na dokumenty z możliwością przywracania w ciągu 30 dni od usunięcia, aby zapobiec przypadkowej utracie danych.
Nie są wymagane żadne dodatkowe działania — iOS i Android automatycznie zachowują katalog dokumentów podczas aktualizacji przez App Store lub Google Play. Jednak przy zmianie struktury przechowywania zaimplementuj migrację danych przy pierwszym uruchomieniu nowej wersji, sprawdzając numer wersji schematu w ustawieniach.
Podsumowanie
context.filesDir jako odpowiednika — pliki są zachowywane przy aktualizacji, ale nie mają wbudowanego mechanizmu kopii zapasowejOpracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również