App Sandbox
The iOS Sandbox
Every iOS app runs in its own sandbox - an isolated directory that the app can read and write. Apps cannot access each other's sandboxes directly.
Directory Layout
/AppName.app/ - Bundle resources (read-only)
/Documents/ - User-created data (backed up to iCloud)
/Library/Caches/ - Temporary cached data (not backed up)
/Library/Preferences/ - UserDefaults plist files
/tmp/ - Temporary files (not backed up)
Finding Directories
let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let caches = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
let tmp = FileManager.default.temporaryDirectory
Documents Directory
Store user-created content:
let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentsPath.appendingPathComponent("notes.json")
Caches Directory
Store data that can be recreated:
let cachesPath = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
let cacheURL = cachesPath.appendingPathComponent("image-cache")
// Caches may be cleared by the system under storage pressure
File Protection
iOS provides file protection levels:
- Complete: Accessible only when device is unlocked
- CompleteUnlessOpen: Accessible unless file is already open
- CompleteUntilFirstUserAuthentication: After first unlock
- None: Always accessible
try data.write(to: fileURL, options: .completeProtection)
File Manager
Writing Files
let fileManager = FileManager.default
let documents = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documents.appendingPathComponent("data.json")
let data = try JSONEncoder().encode(myObject)
try data.write(to: fileURL, options: .atomic)
Reading Files
let data = try Data(contentsOf: fileURL)
let object = try JSONDecoder().decode(MyObject.self, from: data)
Checking File Existence
if fileManager.fileExists(atPath: fileURL.path) {
print("File exists")
}
Creating Directories
let directory = documents.appendingPathComponent("Images")
try fileManager.createDirectory(at: directory, withIntermediateDirectories: true)
Listing Directory Contents
let contents = try fileManager.contentsOfDirectory(at: documents, includingPropertiesForKeys: nil)
for file in contents {
print(file.lastPathComponent)
}
Deleting Files
try fileManager.removeItem(at: fileURL)
Moving and Copying
let destination = documents.appendingPathComponent("Backup/data.json")
try fileManager.copyItem(at: fileURL, to: destination)
try fileManager.moveItem(at: fileURL, to: destination)
File Attributes
let attributes = try fileManager.attributesOfItem(atPath: fileURL.path)
if let size = attributes[.size] as? Int {
print("File size: \(size) bytes")
}
if let modDate = attributes[.modificationDate] as? Date {
print("Modified: \(modDate)")
}
iCloud Files
iCloud Document Storage
Enable iCloud in your target and store files in the ubiquity container:
import CloudKit
func saveToiCloud(data: Data, fileName: String) {
guard let container = FileManager.default.url(forUbiquityContainerIdentifier: nil) else {
print("iCloud not available")
return
}
let documentsDir = container.appendingPathComponent("Documents")
let fileURL = documentsDir.appendingPathComponent(fileName)
try? FileManager.default.createDirectory(at: documentsDir, withIntermediateDirectories: true)
try data.write(to: fileURL, options: .atomic)
}
Querying iCloud Files
func listiCloudFiles() {
guard let container = FileManager.default.url(forUbiquityContainerIdentifier: nil) else { return }
let documentsDir = container.appendingPathComponent("Documents")
if let contents = try? FileManager.default.contentsOfDirectory(at: documentsDir, includingPropertiesForKeys: nil) {
for file in contents {
print(file.lastPathComponent)
}
}
}
UIDocument
For document-based apps, use UIDocument for automatic iCloud sync:
class MyDocument: UIDocument {
var content: String = ""
override func load(fromContents contents: Any, ofType typeName: String) throws {
if let data = contents as? Data {
content = String(data: data, encoding: .utf8) ?? ""
}
}
override func contents(forType typeName: String) throws -> Any {
return content.data(using: .utf8) ?? Data()
}
}
File Coordination
For concurrent access to shared files:
import FileCoordination
let coordinator = NSFileCoordinator()
coordinator.coordinate(readingItemAt: fileURL, options: .forUploading) { readingURL, error in
// Safe to read from readingURL
let data = try Data(contentsOf: readingURL)
}
App Sandbox Tips
- Store user data in Documents (backed up)
- Store cache in Library/Caches (not backed up)
- Store temp files in tmp (not backed up)
- Always handle missing files gracefully
- Use .atomic write option for data integrity
Quiz
1. Which directory is backed up to iCloud by default?
2. What method creates directories in FileManager?
3. What is the purpose of the app sandbox?
4. What write option ensures data integrity?
Flashcards
Question
What is the iOS app sandbox?
Click to reveal answer
Answer
An isolated directory structure that each app runs in, preventing access to other apps' data.
Question
Which directory should you use for user-created content?
Click to reveal answer
Answer
The Documents directory (.documentDirectory) which is backed up to iCloud.
Question
What is the .atomic write option?
Click to reveal answer
Answer
It prevents corruption by writing to a temp file first, then replacing the target.
Question
How do you access iCloud document storage?
Click to reveal answer
Answer
Use FileManager.url(forUbiquityContainerIdentifier:) to get the iCloud container URL.
Revision Notes
Key Takeaways
- 1. The app sandbox isolates each app's file system access
- 2. Documents directory is for user data and is backed up to iCloud
- 3. Caches directory is for recreateable data and is not backed up
- 4. FileManager provides all file system operations
- 5. .atomic write option prevents file corruption
Interview Tips
- • Explain the iOS app sandbox and directory structure
- • Know when to use Documents vs Caches vs tmp
- • Describe how to implement iCloud document storage
- • Discuss file coordination for concurrent access
Cheat Sheet
Sandbox: Isolated app directories. Documents: User data, backed up. Caches: Temp data, not backed up. tmp: Temporary files. FileManager for read/write/delete/list. .atomic for safe writes. iCloud via ubiquity container. UIDocument for document-based apps.