File management is crucial for many apps. Learn to work with files, directories, and document storage.
FileManager Basics
File Operations
swift
import Foundation
class FileManagerHelper {
let fileManager = FileManager.default
// Get documents directory
var documentsDirectory: URL {
fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
}
// Get caches directory
var cachesDirectory: URL {
fileManager.urls(for: .cachesDirectory, in: .userDomainMask)[0]
}
// Get temporary directory
var temporaryDirectory: URL {
fileManager.temporaryDirectory
}
// Create directory
func createDirectory(at url: URL) throws {
var isDirectory: ObjCBool = false
let exists = fileManager.fileExists(atPath: url.path, isDirectory: &isDirectory)
guard !exists || !isDirectory else {
throw FileError.directoryAlreadyExists
}
try fileManager.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)
}
// Delete file
func deleteFile(at url: URL) throws {
try fileManager.removeItem(at: url)
}
enum FileError: Error {
case directoryAlreadyExists
case fileNotFound
}
}Document Directory
Save Documents
swift
class DocumentManager {
let fileManager = FileManager.default
var documentsDirectory: URL {
fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
}
func saveDocument(_ text: String, filename: String) throws {
let fileURL = documentsDirectory.appendingPathComponent(filename)
try text.write(to: fileURL, atomically: true, encoding: .utf8)
}
func loadDocument(filename: String) throws -> String {
let fileURL = documentsDirectory.appendingPathComponent(filename)
return try String(contentsOf: fileURL)
}
func listDocuments() -> [URL] {
do {
let files = try fileManager.contentsOfDirectory(
at: documentsDirectory,
includingPropertiesForDirectories: false
)
return files.filter { $0.pathExtension == "txt" }
} catch {
return []
}
}
func deleteDocument(filename: String) throws {
let fileURL = documentsDirectory.appendingPathComponent(filename)
try FileManager.default.removeItem(at: fileURL)
}
}iCloud Documents
Cloud Storage
swift
import CloudKit
class CloudDocumentManager {
let container = CKContainer(identifier: "iCloud.com.yourapp.Documents")
var documentsDirectory: URL {
FileManager.default.url(forUbiquityContainerIdentifier: "iCloud.com.yourapp.Documents")!
}
func saveToCloud(_ text: String, filename: String) throws {
let fileURL = documentsDirectory.appendingPathComponent(filename)
try text.write(to: fileURL, atomically: true, encoding: .utf8)
// File will be synced automatically
}
func listCloudDocuments() -> [URL] {
do {
let files = try FileManager.default.contentsOfDirectory(
at: documentsDirectory,
includingPropertiesForDirectories: false
)
return files
} catch {
return []
}
}
func deleteCloudDocument(filename: String) throws {
let fileURL = documentsDirectory.appendingPathComponent(filename)
try FileManager.default.removeItem(at: fileURL)
}
func monitorCloudDocuments() -> NSFileCoordinator {
return NSFileCoordinator()
}
}File Coordination
iCloud Conflict Resolution
swift
class FileCoordinatorManager {
func coordinateWriting(at url: URL, intention: NSFileCoordinationWritingIntent) throws {
let fileCoordinator = NSFileCoordinator()
var coordinatorError: NSError?
var coordinatedFile: URL?
NSFileCoordinator().coordinate(writingItemAt: url, options: nil, error: &coordinatorError) { url in
try intention.perform(at: url)
var error: NSError?
NSFileCoordinator().item(at: url, error: &error)
if let error = error {
throw error
}
return url
}
throw coordinatorError ?? FileError.coordinationFailed
}
enum FileError: Error {
case coordinationFailed
}
}File Streaming
Large File Handling
swift
class LargeFileManager {
func processLargeFile(at url: URL, chunkSize: Int = 1024) async throws {
let handle = try FileHandle(forReadingFrom: url)
defer {
try? handle.close()
}
var offset = 0
while offset < try handle.offsetInFile() {
handle.seek(toFileOffset: UInt64(offset))
let data = handle.readData(ofLength: chunkSize)
if data.isEmpty {
break
}
// Process chunk
try await processData(data)
offset += chunkSize
}
}
private func processData(_ data: Data) async throws {
// Process data chunk
print("Processed \(data.count) bytes")
}
}File Protection
Secure Files
swift
class SecureFileManager {
func createSecureFile(at url: URL) throws {
let attributes: [FileAttributeKey: Any] = [
.protectionKey: FileProtectionType.complete
]
try FileManager.default.setAttributes(attributes, ofItemAtPath: url.path)
}
func createEncryptedFile(at url: URL, password: String) throws {
let data = password.data(using: .utf8)!
// Encrypt data
let encryptedData = try AES256.encrypt(data, password: password)
try encryptedData.write(to: url)
}
func readEncryptedFile(at url: URL, password: String) throws -> String {
let encryptedData = try Data(contentsOf: url)
// Decrypt data
let decryptedData = try AES256.decrypt(encryptedData, password: password)
return String(data: decryptedData, encoding: .utf8) ?? ""
}
}Best Practices
- 1Paths: Use URL-based paths
- 2Coordination: Use file coordination
- 3Storage: Store files appropriately
- 4Cleanup: Clean up temporary files
- 5Error Handling: Handle file errors
- 6Security: Secure sensitive files
- 7iCloud: Leverage iCloud sync
- 8Memory: Manage memory for large files
File management is essential for data persistence!