NSFileCoordinator — ce este, coordonarea accesului la fișiere iOS

Autor: IT Sectr Publicat: 2026-07-11 Timp de citire: 7 min

NSFileCoordinator este o clasă Foundation în iOS și macOS, care asigură accesul sigur la fișiere atunci când mai multe fire, procese sau extensii lucrează simultan. Potrivit Apple Developer Documentation, 2024, NSFileCoordinator previne condițiile de cursă (race conditions) la citirea și scrierea fișierelor, garantând că niciun proces nu citește datele în momentul modificării lor de către altul. Coordonatorul este utilizat în iCloud Drive, File Provider Extension și orice operațiuni de fișiere multi-thread.

Puncte cheie

  • NSFileCoordinator — clasă pentru acces sigur la fișiere din mai multe fire și procese
  • Blocurile de coordonare (reading/writing intent) declară tipul operației înainte de execuție
  • Prevenirea race conditions — sarcina principală a coordonatorului la accesul paralel
  • Suport File Provider — coordonatorul este obligatoriu la lucrul cu fișiere iCloud Drive și extensii
  • NSFilePresenter — protocol pentru primirea notificărilor de modificări ale fișierelor din alte procese

Ce este NSFileCoordinator?

NSFileCoordinator — este un mecanism de sincronizare a accesului la fișiere la nivelul sistemului de operare, introdus de Apple în iOS 5 și macOS 10.7 Lion. Spre deosebire de blocările tradiționale (NSLock, pthread_mutex), coordonatorul operează la nivelul sistemului de fișiere și poate coordona accesul între diferite procese, nu doar între firele aceleiași aplicații.

Necesitatea NSFileCoordinator provine din arhitectura Sandbox în iOS: fiecare proces (aplicație, extensie, serviciu de sistem) funcționează într-un mediu izolat cu propriul acces la fișiere. Când mai multe procese încearcă să citească și să scrie simultan același fișier (de exemplu, la sincronizarea iCloud Drive), fără coordonator apar condiții de cursă: procesul A citește fișierul în momentul în care procesul B l-a suprascris deja parțial.

Potrivit WWDC 2023, Apple recomandă insistent utilizarea NSFileCoordinator pentru toate operațiunile cu fișiere în Ubiquity container (iCloud Drive) și la lucrul cu File Provider Extension. Ignorarea coordonării este una dintre cauzele frecvente ale deteriorării datelor și erorilor nereproductibile în aplicațiile iOS.

Tipuri de intenții de coordonare (intents)

Intenția de coordonare (NSFileCoordinator.ReadingIntent / WritingIntent) — este un obiect care declară tipul operației pe care un fir sau proces intenționează să o execute. Coordonatorul folosește aceste intenții pentru a determina ordinea accesului și a rezolva conflictele.

Tipul intențieiDescriereCând să utilizați
ReadingIntentCitirea fișierului fără modificăriDeschiderea documentului, încărcarea datelor
WritingIntentScrierea cu posibila modificare a conținutuluiSalvarea documentului, editare
ReadingIntent(URL, options: .withoutChanges)Citirea fără urmărirea modificărilorVizualizare rapidă a conținutului
WritingIntent(URL, options: .contentIndependentMetadataOnly)Modificarea doar a metadatelorActualizarea datei sau atributelor
WritingIntent(URL, options: .forDeleting)Ștergerea fișieruluiȘtergerea documentului de către utilizator

Reguli de coordonare: lecturile simultane multiple sunt permise (dacă nu există o scriere activă), scrierea este exclusivă — nicio citire sau scriere nu este permisă în timpul operației de scriere. Aceasta corespunde modelului readers-writer lock, dar cu suport suplimentar pentru coordonarea inter-proces prin launchd și XPC.

Nuanță importantă: NSFileCoordinator nu împiedică accesul la fișier prin NSData sau FileManager obișnuit — coordonează doar operațiunile care sunt explicit încapsulate în blocuri de coordonare. Dacă un alt fir accesează fișierul direct, ocolind coordonatorul, apar exact acele race conditions pe care coordonatorul ar trebui să le prevină.

NSFileCoordinator în acțiune: exemple de cod

Modelul de bază de utilizare a NSFileCoordinator constă în trei pași: crearea unei instanțe a coordonatorului, declararea intenției (citire sau scriere) și executarea operației în interiorul blocului de coordonare. Coordonatorul garantează că niciun alt coordonator nu va lucra simultan cu același fișier.

swift
import Foundation

let coordinator = NSFileCoordinator()
let fileURL = getDocumentURL()

// Citire sigură
let readIntent = NSFileCoordinator
    .ReadingIntent(url: fileURL)
var content: Data?
var readError: NSError?

coordinator.coordinate(with: readIntent) { error in
    if let error = error {
        readError = error
        return
    }
    content = try? Data(contentsOf: fileURL)
}

// Scriere sigură
let writeIntent = NSFileCoordinator
    .WritingIntent(url: fileURL)

coordinator.coordinate(with: writeIntent) { error in
    guard error == nil else { return }
    do {
        try newData.write(to: fileURL)
    } catch {
        Logger.storage.error(
            "Write failed: \(error)"
        )
    }
}

Operația în lot — coordonatorul poate gestiona mai multe fișiere într-o singură operație, utilizând un tablou de intenții. Acest lucru este convenabil pentru mutarea, copierea sau ștergerea unui set de fișiere ca o singură tranzacție. Dacă una dintre intenții nu poate fi executată, întreaga operație este anulată cu o eroare.

swift
let coordinator = NSFileCoordinator()
let readIntent = NSFileCoordinator
    .ReadingIntent(url: sourceURL)
let writeIntent = NSFileCoordinator
    .WritingIntent(url: destURL)

coordinator.coordinate(
    with: [readIntent, writeIntent]
) { error in
    try? FileManager.default
        .copyItem(at: sourceURL, to: destURL)
}

Coordonarea asincronă — începând cu iOS 15, NSFileCoordinator suportă metode asincrone cu completion handler, permițând executarea coordonării fără blocarea firului apelant. Acest lucru este critic pentru firul UI, unde așteptarea sincronă a coordonării poate cauza înghețarea interfeței pentru secunde.

Protocolul NSFilePresenter și notificările

NSFilePresenter — este un protocol pe care un obiect îl implementează pentru a primi notificări despre modificările fișierelor coordonate de NSFileCoordinator. Dacă aplicația dvs. afișează conținutul unui fișier care poate fi modificat de un alt proces (de exemplu, iCloud Drive sincronizează o nouă versiune), implementarea NSFilePresenter permite actualizarea la timp a interfeței.

swift
class DocumentPresenter: NSFilePresenter {
    let presentedItemURL: URL?
    let presentedItemOperationQueue: OperationQueue

    init(url: URL) {
        presentedItemURL = url
        presentedItemOperationQueue = OperationQueue()
    }

    func presentedItemDidChange() {
        DispatchQueue.main.async {
            NotificationCenter.default
                .post(name: .documentDidChange,
                      object: self)
        }
    }

    func presentedItemDidMove(to newURL: URL) {
        Logger.storage.info(
            "File moved to: \(newURL.lastPathComponent)"
        )
    }

    func accommodatePresentedItemDeletion(
        completionHandler: @escaping (Error?) -> Void
    ) {
        Logger.storage.warn("File deleted externally")
        completionHandler(nil)
    }
}

Metodele protocolului: presentedItemDidChange este apelată la modificarea conținutului fișierului, presentedItemDidMove(to:) — după mutarea fișierului, accommodatePresentedItemDeletion — înainte de ștergerea fișierului de către un alt proces (permite aplicației să închidă corect fișierul). În plus, protocolul suportă versionarea prin presentedItemDidGainVersion: și presentedItemDidLoseVersion:.

Important: NSFilePresenter trebuie înregistrat în sistem prin NSFileCoordinator.addFilePresenter:. Fără înregistrare, notificările nu vor fi livrate. Înregistrarea se efectuează o singură dată la pornirea aplicației și nu necesită reînregistrare la recrearea prezentatorului.

Cele mai bune practici de coordonare a fișierelor

Utilizați întotdeauna coordonatorul pentru fișierele din Ubiquity container (iCloud Drive) și directoarele accesibile extensiilor. Chiar dacă în prezent aplicația este single-thread, actualizările viitoare sau modificările sistemului pot adăuga acces paralel, iar lipsa coordonării va duce la erori greu de depistat.

Minimizați timpul în blocul de coordonare. În timp ce blocul se execută, alte procese nu pot accesa fișierul. Operațiunile lungi în interiorul blocului (procesare complexă de date, cereri de rețea) blochează întregul sistem de acces la fișiere. Efectuați doar citirea sau scrierea datelor în interiorul blocului, iar procesarea — în afara acestuia.

Evitați deadlock-urile: nu apelați coordonatorul din interiorul blocului unui alt coordonator pentru același fișier — acest lucru va duce la o blocare mutuală. Utilizați operațiuni în lot (tablou de intenții) în loc de apeluri imbricate. Dacă imbricarea este necesară, utilizați cozi diferite sau URL-uri diferite.

Potrivit objc.io (2024), erorile tipice la lucrul cu NSFileCoordinator includ: lipsa gestionării erorilor în completion handler (duce la operațiuni neterminate); coordonarea doar pentru scriere, dar nu și pentru citire; utilizarea API-ului sincron vechi în firul UI; ignorarea protocolului NSFilePresenter la lucrul cu iCloud Drive. Ultima eroare este cea mai perfidă: aplicația afișează date învechite, fără să știe că fișierul a fost deja modificat.

Întrebări frecvente

Ce este NSFileCoordinator?

NSFileCoordinator — clasă Foundation pentru acces sigur la fișiere din mai multe fire sau procese. Previne race conditions, coordonând operațiunile de citire și scriere la nivelul sistemului de fișiere.

Cu ce se deosebește NSFileCoordinator de NSLock?

NSLock funcționează doar în interiorul unui singur proces (între fire). NSFileCoordinator coordonează accesul între diferite procese și extensii, inclusiv sincronizarea iCloud Drive și File Provider Extension.

Este obligatoriu să folosesc NSFileCoordinator pentru iCloud Drive?

Da, Apple recomandă insistent utilizarea NSFileCoordinator pentru toate operațiunile cu fișiere Ubiquity container. Fără coordonator, sunt posibile deteriorări ale datelor în timpul sincronizării între dispozitive și conflicte cu File Provider Extension.

Ce este NSFilePresenter?

NSFilePresenter — protocol pentru primirea notificărilor de modificări ale fișierelor. Permite aplicației să reacționeze la modificările făcute de alte procese: actualizarea UI la modificare, gestionarea mutării sau pregătirea pentru ștergerea fișierului.

Ce tipuri de intenții suportă NSFileCoordinator?

Cinci tipuri: ReadingIntent (citire), WritingIntent (scriere), ReadingIntent cu .withoutChanges (citire fără urmărire), WritingIntent cu .contentIndependentMetadataOnly (doar metadate) și WritingIntent cu .forDeleting (ștergere). Fiecare definește nivelul de acces la fișier.

Concluzii

  • NSFileCoordinator — mecanism de sistem pentru acces sigur la fișiere din fire, procese și extensii
  • Intențiile de coordonare (citire/scriere) declară tipul operației înainte de execuție
  • Citirea este permisă în paralel, scrierea — exclusiv (model readers-writer)
  • NSFilePresenter — protocol de notificare a modificărilor fișierelor din alte procese
  • iCloud Drive și File Provider necesită coordonare obligatorie pentru prevenirea deteriorării datelor
  • Minimizați timpul în blocul de coordonare — operațiunile lungi blochează accesul altor procese
  • Deadlock-urile se previn prin operațiuni în lot și evitarea apelurilor imbricate ale coordonatorului

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și