Skip to content
AgileLogics
5 min read

Files and FileManager

Prerequisites: Error handling

Foundation's FileManager, URL, and String/Data methods read and write files. File operations can fail, so they throw.

Writing and reading text

import Foundation

let folder = FileManager.default.temporaryDirectory
let file = folder.appendingPathComponent("notes.txt")

do {
    try "First line\nSecond line\n".write(to: file, atomically: true, encoding: .utf8)

    let text = try String(contentsOf: file, encoding: .utf8)
    for line in text.split(separator: "\n") {
        print("> \(line)")
    }

    print(FileManager.default.fileExists(atPath: file.path))
    try FileManager.default.removeItem(at: file)
    print(FileManager.default.fileExists(atPath: file.path))
} catch {
    print("File error: \(error.localizedDescription)")
}
> First line
> Second line
true
false
  • Files are identified by URLs, not plain path strings.
  • atomically: true writes to a temporary file first and then swaps it in, so a crash mid-write can't leave a half-written file.
  • temporaryDirectory is a safe place for scratch files.

Saving Codable data

Data plus Codable is the simplest way to save structured data:

import Foundation

struct Settings: Codable {
    var theme = "dark"
    var fontSize = 14
}

let url = FileManager.default.temporaryDirectory.appendingPathComponent("settings.json")

try JSONEncoder().encode(Settings()).write(to: url)
let loaded = try JSONDecoder().decode(Settings.self, from: Data(contentsOf: url))
print(loaded.theme, loaded.fontSize)
dark 14

Where apps store files

iOS and macOS apps run in a sandbox: they can only write inside their own container. Use the standard folders:

  • .documentDirectory — user-created content, backed up.
  • .applicationSupportDirectory — app data the user doesn't manage directly.
  • .cachesDirectory — data you can re-create; the system may delete it.
let docs = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask,
                                       appropriateFor: nil, create: true)

For small preferences, UserDefaults is simpler; for larger structured app data, Apple's SwiftData framework.

Common mistakes

  • Hard-coding absolute paths like /Users/ada/.... They won't exist on other machines, and apps can't access them at all.
  • Reading a file with try!. A missing file is a normal situation, not a programming error.