Files and persistence
Choose the right storage location
Put application-owned data in Application Support and user-created documents where the user chooses them.
Your app has data to save. The first question is not how. It’s where.
macOS has conventions about where files live. Apps that ignore them lose user data at update time, or fill folders that backups skip.
Never write into the bundle
One place is off limits: the app bundle. The .app you ship is signed, and the signature covers every byte inside it.
Writing into your own bundle breaks the signature. And the next update replaces the bundle wholesale, taking your “saved” data with it. Treat the bundle as read-only, always.
Application Support for app-owned data
Data your app owns and manages, like our notes database, belongs in Application Support. Ask FileManager for it, then add a folder named after your app:
let base = FileManager.default.urls(
for: .applicationSupportDirectory,
in: .userDomainMask
)[0]
let folder = base.appending(path: "Notes")
try FileManager.default.createDirectory(
at: folder,
withIntermediateDirectories: true
)
Always ask the API instead of hardcoding ~/Library/Application Support. New Xcode projects are sandboxed by default, and in a sandboxed app the real location is inside your app’s container. Something like ~/Library/Containers/com.flaviocopes.Notes/Data/Library/Application Support/Notes. The API resolves that for you.
createDirectory with withIntermediateDirectories: true is safe to call on every launch. It creates the folder the first time and quietly succeeds when it already exists.
Caches for anything you can rebuild
Data you can download again or regenerate goes in Caches:
let caches = FileManager.default.urls(
for: .cachesDirectory,
in: .userDomainMask
)[0]
The system may delete caches under disk pressure, and backups don’t guarantee them. That’s exactly right for thumbnails or downloaded previews. It’s exactly wrong for the only copy of the user’s notes.
Documents belong to the user
Documents the user owns, say an exported notes archive, are different again. Don’t bury them in Application Support where nobody will find them. Let the user pick the location with a save panel. We cover that two lessons from now.
Verify
Run the app, save, and find the file in Finder. Go to Folder (⇧⌘G) with the container path gets you there.
Then think through uninstall. Dragging your app to the Trash leaves Application Support data behind. That’s normal on macOS, but worth telling your users.
The mistake to recognize
Building paths with string concatenation and NSHomeDirectory(). It works in development, then breaks the moment sandboxing changes the layout.
FileManager.urls(for:in:) is the contract. String paths are a guess.
Lesson completed