NSFilePresenter — este un protocol Foundation care permite unui obiect să primească notificări despre modificările fișierelor și directoarelor din sistemul de fișiere iOS și macOS. Clasa implementează metodele protocolului și se înregistrează prin NSFileCoordinator, după care sistemul apelează automat aceste metode la orice operație cu fișierul urmărit. Conform Apple Developer Documentation (2025), NSFilePresenter este utilizat în aplicații cu acces multi-thread la documente pentru prevenirea conflictelor de scriere. Protocolul este obligatoriu utilizat împreună cu NSFileCoordinator — numai astfel se asigură coordonarea sigură a accesului.
Puncte principale
NSFilePresenter — este un protocol Foundation destinat urmăririi modificărilor fișierelor și directoarelor în sistemele de operare Apple. Protocolul definește un set de metode pe care obiectul observator le implementează pentru a primi notificări despre evenimentele sistemului de fișiere.
Sarcina principală a protocolului este asigurarea accesului sigur la fișiere în scenarii multi-thread. În iOS și macOS, mai multe procese și fire de execuție pot accesa simultan același fișier prin NSFileCoordinator, iar NSFilePresenter garantează că fiecare participant primește starea actualizată a datelor.
Protocolul este inclus în Foundation începând cu iOS 5.0 și macOS 10.7. Este utilizat în aplicații care lucrează cu documente, baze de date și orice fișiere care pot fi modificate simultan din surse diferite — de exemplu, la sincronizarea prin iCloud sau la editarea colaborativă.
Aplicații orientate pe documente — domeniul principal de utilizare al NSFilePresenter. Aplicațiile care lucrează cu UIDocument sau NSDocument se înregistrează automat ca prezentatori prin NSFileCoordinator. Acest lucru permite gestionarea corectă a conflictelor la editarea aceluiași fișier din mai multe ferestre sau dispozitive.
Sincronizarea iCloud — al doilea scenariu cheie. Când un fișier se modifică pe un dispozitiv, iCloud îl sincronizează pe toate dispozitivele conectate. NSFilePresenter notifică aplicația despre aceste modificări, permițând actualizarea la timp a interfeței.
Editori multi-thread — al treilea scenariu. În aplicațiile unde cozile de fundal încarcă și salvează date simultan cu munca utilizatorului, NSFilePresenter previne condițiile de cursă la scrierea și citirea fișierelor.
Mecanismul de funcționare al NSFilePresenter se bazează pe modelul de delegare: obiectul implementează metodele protocolului, se înregistrează prin NSFileCoordinator și primește apeluri la fiecare modificare a fișierului urmărit. Sistemul însuși determină când a avut loc o modificare și ce metode trebuie apelate.
Procesul începe prin crearea de către obiect a unei instanțe NSFileCoordinator și apelarea metodei coordonatorului cu transmiterea URL-ului fișierului. Coordonatorul verifică dacă pentru acest URL sunt înregistrați prezentatori. Dacă da, blochează accesul la citire sau scriere și notifică prezentatorii despre modificarea iminentă prin metodele protocolului.
După finalizarea operației, coordonatorul elimină blocarea și apelează notificările finale. Important este că prezentatorul nu gestionează fluxul de execuție — el doar reacționează la evenimente. Coordonarea este pe deplin responsabilitatea NSFileCoordinator.
Faza de pregătire — înainte de executarea operației, coordonatorul apelează metoda accommodatePresentedItemDeletion sau accommodatePresentedSubitemDeletion. Prezentatorul poate gestiona situația sau poate anula operația returnând o eroare. Această fază permite aplicației să finalizeze corect lucrul cu fișierul înainte de modificarea acestuia.
Faza de notificare — după finalizarea operației, coordonatorul apelează presentedItemDidChange sau presentedSubitemDidChange. Prezentatorul primește un semnal că fișierul s-a modificat și poate reciti conținutul acestuia. Pentru mutarea fișierului, este apelată presentedItemDidMoveToURL cu noua locație.
Faza de finalizare — coordonatorul elimină toate blocările și eliberează resursele. Prezentatorul poate continua lucrul cu datele actualizate. Toate cele trei faze se execută sincron în același fir de execuție, de aceea metodele protocolului trebuie să ruleze rapid, fără operații lungi de intrare-ieșire.
Protocolul NSFilePresenter conține mai multe metode obligatorii și opționale. Singura proprietate obligatorie este presentedItemURL, care returnează URL-ul fișierului sau directorului urmărit. Fără această proprietate, obiectul nu poate fi înregistrat ca prezentator.
presentedItemURL — proprietate de tip URL? care trebuie să returneze calea către fișierul urmărit. Dacă obiectul urmărește mai multe fișiere, proprietatea returnează URL-ul elementului principal. Pentru directoare, se returnează URL-ul directorului însuși.
presentedItemDidChange — este apelată după modificarea conținutului fișierului urmărit. În această metodă, prezentatorul își actualizează starea internă și reîncarcă datele. Această metodă nu primește informații despre ce anume s-a modificat — doar faptul modificării.
accommodatePresentedItemDeletion — este apelată înainte de ștergerea fișierului. Prezentatorul poate salva starea curentă, poate închide descriptori de fișiere sau poate anula operația returnând NSError. Dacă metoda returnează o eroare, operația de ștergere nu se execută.
presentedItemDidMoveToURL — este apelată după mutarea sau redenumirea fișierului. Metoda primește noul URL, iar prezentatorul trebuie să actualizeze referința către fișier. Fără implementarea acestei metode, prezentatorul va continua să indice calea veche, inexistentă.
NSFileCoordinator și NSFilePresenter — o pereche inseparabilă. NSFileCoordinator gestionează accesul la fișiere și apelează metodele prezentatorului. Prezentatorul nu lucrează direct cu sistemul de fișiere — toate operațiile trec prin coordonator, care garantează atomicitatea modificărilor.
Coordonatorul înregistrează prezentatorul prin metoda addFilePresenter a clasei NSFileCoordinator. După adăugare, prezentatorul începe să primească notificări. Eliminarea se face prin removeFilePresenter. Sistemul păstrează o referință slabă către prezentator, de aceea obiectul trebuie să fie activ pe întreaga perioadă de urmărire.
Conform Apple WWDC 2022, NSFileCoordinator utilizează un mecanism de coordonare la nivel de kernel, ceea ce asigură o întârziere minimă la blocări. În cele mai noi versiuni de iOS, coordonatorul este optimizat pentru lucrul cu Sandbox și extensiile aplicațiilor.
Intention — fiecare operație de citire sau scriere trebuie înfășurată într-un bloc de coordonare: citirea prin coordinateReadingItemAtURL, scrierea prin coordinateWritingItemAtURL. Coordonatorul blochează automat fișierul pentru ceilalți participanți pe durata executării blocului.
Coordonare în lot — pentru operații cu mai multe fișiere se utilizează coordonarea în lot. Coordonatorul blochează atomic toate fișierele specificate, execută operația și elimină blocările. Acest lucru este critic la mutarea sau copierea seturilor de documente.
Vom crea clasa DocumentPresenter care implementează protocolul NSFilePresenter și urmărește modificările fișierului de document. Clasa conține o referință către fișier, date interne și un indicator de actualitate.
import Foundation
class DocumentPresenter: NSObject, NSFilePresenter {
var presentedItemURL: URL? {
return self.fileURL
}
var presentedItemOperationQueue: OperationQueue {
return self.queue
}
private let fileURL: URL
private let queue = OperationQueue()
func presentedItemDidChange() {
self.reloadData()
}
func accommodatePresentedItemDeletion() throws {
try self.saveCurrentState()
}
private func reloadData() {
let coordinator = NSFileCoordinator(filePresenter: self)
var error: NSError?
coordinator.coordinate(readingItemAt: self.fileURL,
options: [],
error: &error)
{ readURL in
guard let data = try? Data(contentsOf: readURL)
else { return }
self.processData(data)
}
}
private func processData(_: Data) {
// Prelucrarea datelor documentului
}
}
Clasa implementează presentedItemDidChange pentru reîncărcarea datelor la modificarea fișierului și accommodatePresentedItemDeletion pentru salvarea stării înainte de ștergere. Coada de operații garantează că toate notificările sunt procesate secvențial.
Înregistrarea prezentatorului se face prin NSFileCoordinator.addFilePresenter la deschiderea documentului. Este important să transmiteți coordonatorului opțiunile corecte de citire — withoutChanges pentru operații fără modificare sau immediatelyAvailable pentru scenarii cu acces imediat.
Prima eroare frecventă — lipsa implementării presentedItemOperationQueue. Dacă nu specificați o coadă, notificările pot veni în fire de execuție arbitrare, provocând condiții de cursă a datelor. Folosiți întotdeauna o OperationQueue secvențială pentru procesarea notificărilor.
A doua eroare — blocarea în metodele prezentatorului. Metodele protocolului sunt apelate sincron din coordonator. Dacă prezentatorul execută o operație lungă (scriere în baza de date, cerere de rețea), blochează coordonatorul pentru toți ceilalți participanți. Transferați operațiile grele în cozile de fundal.
A treia eroare — ignorarea accommodatePresentedItemDeletion. Dacă prezentatorul nu implementează această metodă și nu returnează o eroare, fișierul poate fi șters fără salvarea stării curente. Salvați întotdeauna datele în această metodă, dacă nu au fost încă scrise pe disc.
A patra eroare — coordonarea ciclică. Când prezentatorul în interiorul metodei de notificare apelează din nou coordonatorul pentru același fișier, apare un deadlock. Verificați indicatorul isCoordinatedOperation înainte de a începe coordonarea în interiorul handlerului.
| Eroare | Consecință | Soluție |
|---|---|---|
| Fără coadă de operații | Cursă de date în multi-threading | Specificați OperationQueue |
| Blocarea în metode | Înghețarea coordonatorului | Transferați în firul de fundal |
| Ignorarea deletion | Pierderea datelor la ștergere | Implementați salvarea |
| Coordonarea ciclică | Deadlock al aplicației | Indicatorul isCoordinatedOperation |
Întrebări frecvente
NSFileHandle — este o interfață de nivel scăzut pentru citirea și scrierea datelor care nu oferă mecanisme de notificare a modificărilor din alte procese. NSFilePresenter funcționează la nivel de coordonare: primește evenimente de la sistem la orice modificare a fișierului, indiferent de sursă — alt fir de execuție, proces sau iCloud.
Da. NSFilePresenter nu are sens fără NSFileCoordinator. Prezentatorul doar definește metodele de gestionare, iar coordonatorul gestionează blocările și apelează aceste metode. Dacă utilizați NSFilePresenter fără coordonator, notificările nu vor fi livrate.
Poate, dar cu limitări. Proprietatea presentedItemURL returnează doar un singur URL, prin urmare pentru urmărirea mai multor fișiere se utilizează protocolul NSFilePresenter cu metode suplimentare pentru subelemente. Alternativa — crearea unei instanțe separate de prezentator pentru fiecare fișier.
NSFilePresenter este complet compatibil cu sandbox-ul iOS. Aplicația poate urmări fișiere doar în interiorul containerului său. Pentru accesul la fișierele altor aplicații se utilizează App Groups sau Security-Scoped Bookmark. Coordonatorul funcționează în cadrul permisiunilor sandbox-ului.
Utilizați debounce sau throttle în interiorul metodei presentedItemDidChange. Creați un timer cu o întârziere de 0,3-0,5 secunde și resetați-l la fiecare apel nou. După stabilizare, efectuați reîncărcarea datelor. Aceasta previne procesarea multiplă a aceluiași pachet de modificări.
Concluzii
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.
Citiți și