FileManager — to klasa z frameworka Foundation, zapewniająca interfejs do pracy z systemem plików iOS, macOS i innych platform Apple. Umożliwia tworzenie, odczytywanie, przenoszenie i usuwanie plików oraz katalogów, a także zarządzanie metadanymi i uprawnieniami dostępu. W iOS wszystkie operacje FileManager są ograniczone do Sandbox aplikacji. Według Apple Developer Documentation (2026), FileManager jest bezpieczny wątkowo i może być używany z wątków tła, ale wszystkie operacje na systemie plików muszą być wykonywane z uwzględnieniem sandboxa i uprawnień Security-Scoped Bookmarks.
Najważniejsze
FileManager — klasa singletonowa z frameworka Foundation, zapewniająca ujednolicone API do interakcji z systemem plików na wszystkich platformach Apple. Jest dostępny przez FileManager.default lub przez utworzenie instancji z niestandardowym delegatem.
Główne możliwości klasy obejmują: sprawdzanie istnienia pliku (fileExists), tworzenie katalogów (createDirectory), kopiowanie i przenoszenie (copyItem, moveItem), usuwanie (removeItem), pobieranie atrybutów (attributesOfItem) i zawartości katalogów (contentsOfDirectory). FileManager jest ściśle powiązany z NSData, String i JSONEncoder/Decoder do serializacji danych.
FileManager jest thread-safe: Apple gwarantuje bezpieczeństwo wywoływania metod z różnych wątków. Jednak operacje na systemie plików mogą być wolne w przypadku dużych plików, dlatego Apple zaleca wykonywanie ich w kolejce tła (DispatchQueue.global) i wywoływanie metod FileManagerDelegate w celu informowania o postępie.
let fileManager = FileManager.default
let documentsURL = fileManager.urls(
for: .documentDirectory,
in: .userDomainMask
).first!
let fileURL = documentsURL.appendingPathComponent("data.plist")
if fileManager.fileExists(atPath: fileURL.path) {
print("File exists at \(fileURL.path)")
}
Każda aplikacja iOS ma trzy główne katalogi dostępne przez FileManager w ramach Sandbox: Documents, Library i tmp. Każdy ma swoje przeznaczenie i zasady tworzenia kopii zapasowych, których przestrzeganie jest kluczowe dla przejścia recenzji w App Store.
Documents — dla danych użytkownika, które powinny być zachowywane między uruchomieniami i kopiowane do iCloud. Library — dla plików aplikacji: pamięci podręcznych (Caches), ustawień (Preferences), baz danych (Application Support). tmp — dla plików tymczasowych, które mogą zostać usunięte przez system w dowolnym momencie między uruchomieniami aplikacji.
| Katalog | FileManager URL | Kopia zapasowa | Zastosowanie |
|---|---|---|---|
| Documents | .documentDirectory | Tak | Dane użytkownika, pliki, eksport |
| Library/Caches | .cachesDirectory | Nie | Pamięć podręczna obrazów, dane tymczasowe |
| Library/Preferences | .libraryDirectory + "/Preferences" | Tak | UserDefaults, ustawienia aplikacji |
| Library/Application Support | .applicationSupportDirectory | Tak | Bazy danych, CoreData, Realm |
| tmp | .tmpDirectory (NSTemporaryDirectory) | Nie | Tymczasowe pliki sesji |
Zasada Apple: jeśli plik można przywrócić z internetu lub odtworzyć — powinien być przechowywany w Caches (bez kopii zapasowej). Jeśli plik zawiera dane użytkownika — Documents (z kopią zapasową). Nieprawidłowe umieszczanie plików to jedna z częstych przyczyn odrzucenia aplikacji, ponieważ Apple sprawdza zgodność z wytycznymi Storage & iCloud Backup Guidelines.
FileManager sam nie udostępnia metod do odczytu zawartości plików — służą do tego NSData(contentsOf), String(contentsOf) lub metody FileHandle. FileManager odpowiada za zarządzanie plikami: sprawdzanie istnienia, przenoszenie, kopiowanie, usuwanie.
Do zapisu danych używana jest metoda createFile(atPath:contents:attributes:) lub wysokopoziomowe API — data.write(to:), JSONEncoder.encode i PropertyListEncoder. FileManager udostępnia również FileHandle do strumieniowego odczytu i zapisu dużych plików, który nie ładuje całego pliku do pamięci.
struct UserSettings: Codable {
let username: String
let isDarkMode: Bool
let fontSize: Int
}
let settings = UserSettings(
username: "developer",
isDarkMode: true,
fontSize: 16
)
// Zapisz JSON do Documents
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(settings)
let url = documentsURL.appendingPathComponent("settings.json")
try data.write(to: url, options: .atomic)
// Odczytaj JSON
let loadedData = try Data(contentsOf: url)
let loadedSettings = try JSONDecoder()
.decode(UserSettings.self, from: loadedData)
Podczas zapisu używaj options: .atomic — gwarantuje to, że plik nie zostanie uszkodzony w przypadku awarii zapisu: dane są najpierw zapisywane do pliku tymczasowego, a następnie atomowo przenoszone do docelowej ścieżki. Do odczytu dużych plików używaj FileHandle z .readingMode i czytaj dane porcjami, kontrolując zużycie pamięci.
FileManager udostępnia metody do pełnego zarządzania katalogami: createDirectory (tworzenie wszystkich pośrednich folderów przez withIntermediateDirectories), contentsOfDirectory (pobieranie listy plików), enumeratorAt (rekurencyjne przechodzenie) i subpathsOfDirectory (wszystkie ścieżki wewnątrz katalogu).
Metoda enumeratorAt zwraca DirectoryEnumerator, który umożliwia efektywne przeglądanie dużych katalogów bez ładowania całej zawartości do pamięci. Obsługuje filtrowanie przez skipDescendants i udostępnia atrybuty każdego elementu bez dodatkowego zapytania do systemu plików.
// Rekurencyjne przechodzenie katalogów
if let enumerator = fileManager.enumerator(
at: documentsURL,
includingPropertiesForKeys: [.fileSizeKey, .isDirectoryKey]
) {
for case let fileURL as URL in enumerator {
let attrs = try fileURL.resourceValues(
for: [.fileSizeKey, .isDirectoryKey]
)
if attrs.isDirectory == false {
let size = attrs.fileSize ?? 0
print("File: \(fileURL.lastPathComponent), Size: \(size) bytes")
}
}
}
Do usuwania katalogu używaj removeItem(at:). Uwaga: usunięcie katalogu w iOS jest nieodwracalne — pliki nie trafiają do kosza, jak na macOS. Przed usunięciem upewnij się, że nie używasz już plików z tego katalogu, i wykonaj operację w wątku tła, ponieważ usunięcie dużej liczby plików może zablokować UI.
FileManager integruje się z iCloud Drive przez metodę URLForUbiquityContainerIdentifier, która zwraca URL katalogu iCloud dla aplikacji. Do działania wymaga włączenia iCloud capability w projekcie i dodania odpowiedniego entitlement.
Pliki iCloud są synchronizowane automatycznie, ale FileManager udostępnia metody do ręcznej kontroli: startDownloadingUbiquitousItem wymusza rozpoczęcie pobierania, evictUbiquitousItem usuwa lokalną kopię, a urlOfItem(at:) zwraca lokalny URL dla pliku iCloud. NSMetadataQuery jest używane do wyszukiwania plików w iCloud.
Krytyczne ograniczenie: iCloud Drive nie jest obsługiwany dla plików w katalogu Documents — tylko dla plików w ubiquityContainer. Nie próbuj synchronizować Documents przez iCloud; do tego celu używaj NSUbiquitousKeyValueStore dla małych ilości danych lub Core Data z CloudKit dla złożonych struktur.
Operacje na FileManager mogą być kosztowne, szczególnie na urządzeniach z wolną pamięcią flash. Główne zalecenia Apple obejmują wykonywanie wszystkich operacji plikowych w kolejkach tła, minimalizację liczby wywołań fileExistsAtPath i używanie buforowania wyników.
Metoda fileExists wykonuje wywołanie systemowe stat(), które jest stosunkowo wolne. Jeśli sprawdzasz istnienie pliku przed jego odczytem, lepiej od razu spróbować go odczytać i obsłużyć błąd — to wykonuje ten sam stat, ale eliminuje podwójne wywołanie systemowe. Do masowych sprawdzeń używaj enumeratorAt z resourceValues.
Do optymalizacji pracy z dużymi ilościami danych:
Apple Instruments udostępnia szablon File Activity do profilowania operacji plikowych. Używaj go do identyfikacji wąskich gardeł — na przykład częstych wywołań fileExists w pętli lub operacji zapisu na main thread. Najczęstsze problemy z wydajnością są związane z synchronicznym zapisem dużych plików podczas zwijania aplikacji.
Często zadawane pytania
FileManager — klasa frameworka Foundation do pracy z systemem plików Apple. Udostępnia API do tworzenia, odczytu, przenoszenia i usuwania plików i katalogów. W iOS jego działanie jest ograniczone do Sandbox aplikacji, z wyjątkiem Security-Scoped Bookmarks.
Documents — dane użytkownika z kopią zapasową w iCloud. Library/Caches — pamięć podręczna bez kopii zapasowej. Library/Application Support — bazy danych. tmp — pliki tymczasowe. App Group Container — do współdzielenia danych między aplikacjami jednej grupy.
Wywołaj FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first. Metoda zwraca URL z bezwzględną ścieżką do katalogu Documents wewnątrz Sandbox bieżącej aplikacji. Do sprawdzenia istnienia użyj fileExists(atPath:).
Nie, Sandbox iOS zabrania dostępu do systemu plików innych aplikacji. Wyjątki: App Groups (wspólny katalog dla aplikacji jednego dewelopera) i Security-Scoped Bookmarks (dostęp do plików przez UIDocumentPicker i iCloud Drive).
Używaj opcji .atomic podczas zapisu — dane są najpierw zapisywane do pliku tymczasowego, następnie atomowo przenoszone do docelowej ścieżki. Zapobiega to uszkodzeniu pliku w przypadku awarii zapisu. Do dużych danych używaj FileHandle z zapisem porcjami po 1-2 MB.
Podsumowanie
Opracujemy 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ż