C.W.K.
Stream
Lesson 02 of 05 · published

Coordinated Access

~12 min · nsfilecoordinator, coordinated-access, concurrency

Level 0Lost in Finder
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Your app is not alone with the files. Finder, Dropbox, iCloud, and Spotlight are all in the room. Coordinate, or collide."

The Files Belong to Everyone

It's tempting to write file code as if your app is the only thing touching the disk. It never is. While Waygate reads a folder, Finder might be renaming a file in it, a sync client might be writing a download, Spotlight might be indexing, and a cloud provider might be materializing a placeholder. If Waygate reads with no awareness of any of that, it can catch a file mid-write — a torn read — or race a sync client and corrupt the picture.

NSFileCoordinator Is the Handshake

macOS provides the mechanism for cooperating: NSFileCoordinator. Coordinating a read or write means announcing intent to the system so other coordinated actors — file providers, other coordinated apps — can pause, flush, or yield appropriately. When Waygate needs a consistent read of a file that a provider might be touching, it coordinates, so it sees a settled state rather than a half-applied change. This is correctness under concurrency, and it's why Waygate uses coordination where external state can change.

Presenters: Being a Good Citizen Back

Coordination goes both ways. Through NSFilePresenter, Waygate can also be notified when something it's displaying is about to change under it, so it can respond — re-enumerate, update a row, mark something offline. Being coordinated isn't only about protecting Waygate's own reads; it's about participating honestly in a shared filesystem so Waygate's projection stays in step with the truth other processes are editing.

Use coordinated access where external state can change. Files are shared with Finder, sync clients, Spotlight, and file providers; NSFileCoordinator lets Waygate read and write with awareness of those other actors, avoiding torn reads and races. Coordination is about correctness under concurrency, not performance.
Coordination is not a lock on the world. It doesn't freeze other apps or guarantee exclusive access forever — it's a cooperative protocol among participants who opt in. A process that ignores coordination can still change a file. That's exactly why Waygate ALSO revalidates at apply time (Track 2): coordination reduces races, and revalidation catches whatever slips through.

Code

A coordinated read: settled state, not a torn one·swift
func coordinatedRead(_ url: URL) throws -> Data {
    let coordinator = NSFileCoordinator(filePresenter: nil)
    var coordError: NSError?
    var result: Data?
    // Announce intent to read; other coordinated actors flush/yield first.
    coordinator.coordinate(readingItemAt: url, options: [], error: &coordError) { safeURL in
        result = try? Data(contentsOf: safeURL)   // reads a SETTLED state
    }
    if let coordError { throw coordError }
    guard let result else { throw OpError.coordinatedReadFailed }
    return result
}
// Without coordination, a sync client mid-write could hand you half a file
// -- valid bytes, wrong content, no error. Coordination avoids the torn read.

External links

Exercise

Describe a torn read concretely: a text editor is saving a 10 MB document while your app reads it uncoordinated. What might your app get, and would it know anything went wrong? Then explain why coordination plus apply-time revalidation is a belt-and-suspenders pair rather than redundant.
Hint
Uncoordinated, you might read the file after the editor truncated it to zero but before it wrote the new content — you get an empty or partial file, with no error at all. Coordination avoids catching that in-between moment. Revalidation is a different guard: it catches identity/state changes at the moment you act. One prevents torn reads during access; the other prevents acting on stale truth. Different failure modes, both needed.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.