NSFileCoordinator — co to je, koordinace přístupu k souborům iOS

Autor: IT Sectr Publikováno: 2026-07-11 Doba čtení: 7 min

NSFileCoordinator je třída Foundation v iOS a macOS, která zajišťuje bezpečný přístup k souborům při současné práci více vláken, procesů nebo rozšíření. Podle Apple Developer Documentation, 2024, NSFileCoordinator zabraňuje race conditions při čtení a zápisu souborů a zaručuje, že žádný proces nečte data v okamžiku jejich změny jiným procesem. Koordinátor se používá v iCloud Drive, File Provider Extension a všech vícevláknových souborových operacích.

Hlavní body

  • NSFileCoordinator — třída pro bezpečný přístup k souborům z více vláken a procesů
  • Koordinační bloky (reading/writing intent) deklarují typ operace před jejím provedením
  • Prevence race conditions — hlavní úkol koordinátora při paralelním přístupu
  • Podpora File Provider — koordinátor je povinný při práci se soubory iCloud Drive a rozšířeními
  • NSFilePresenter — protokol pro přijímání oznámení o změnách souborů z jiných procesů

Co je NSFileCoordinator?

NSFileCoordinator — je mechanismus synchronizace přístupu k souborům na úrovni operačního systému, představený Apple v iOS 5 a macOS 10.7 Lion. Na rozdíl od tradičních zámků (NSLock, pthread_mutex), koordinátor pracuje na úrovni souborového systému a může koordinovat přístup mezi různými procesy, nejen mezi vlákny jedné aplikace.

Potřeba NSFileCoordinator vyplývá z architektury Sandbox v iOS: každý proces (aplikace, rozšíření, systémová služba) pracuje v izolovaném prostředí s vlastním přístupem k souborům. Když se několik procesů pokouší současně číst a zapisovat stejný soubor (například při synchronizaci iCloud Drive), bez koordinátora vznikají race conditions: proces A čte soubor v okamžiku, kdy jej proces B již částečně přepsal.

Podle WWDC 2023 Apple důrazně doporučuje používat NSFileCoordinator pro všechny operace se soubory v Ubiquity container (iCloud Drive) a při práci s File Provider Extension. Ignorování koordinace je jedním z častých příčin poškození dat a nereprodukovatelných chyb v iOS aplikacích.

Typy koordinačních záměrů (intents)

Koordinační záměr (NSFileCoordinator.ReadingIntent / WritingIntent) — je objekt, který deklaruje typ operace, kterou vlákno nebo proces plánuje provést. Koordinátor používá tyto záměry k určení pořadí přístupu a řešení konfliktů.

Typ záměruPopisKdy použít
ReadingIntentČtení souboru bez změnOtevření dokumentu, načítání dat
WritingIntentZápis s možnou změnou obsahuUložení dokumentu, editace
ReadingIntent(URL, options: .withoutChanges)Čtení bez sledování změnRychlý náhled obsahu
WritingIntent(URL, options: .contentIndependentMetadataOnly)Změna pouze metadatAktualizace data nebo atributů
WritingIntent(URL, options: .forDeleting)Smazání souboruSmazání dokumentu uživatelem

Pravidla koordinace: více současných čtení je povoleno (pokud není aktivní zápis), zápis je exkluzivní — během operace zápisu není povoleno žádné čtení ani zápis. To odpovídá modelu readers-writer lock, ale s dodatečnou podporou pro meziprocesovou koordinaci prostřednictvím launchd a XPC.

Důležitý detail: NSFileCoordinator nebrání přístupu k souboru prostřednictvím běžného NSData nebo FileManager — koordinuje pouze ty operace, které jsou explicitně zabaleny do koordinačních bloků. Pokud jiné vlákno přistupuje k souboru přímo, obcházejíc koordinátora, vznikají právě ty race conditions, kterým má koordinátor zabránit.

NSFileCoordinator v akci: příklady kódu

Základní vzor použití NSFileCoordinator sestává ze tří kroků: vytvoření instance koordinátora, deklarování záměru (čtení nebo zápis) a provedení operace uvnitř koordinačního bloku. Koordinátor zaručuje, že žádný jiný koordinátor nebude současně pracovat se stejným souborem.

swift
import Foundation

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

// Bezpečné čtení
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)
}

// Bezpečný zápis
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)"
        )
    }
}

Dávková operace — koordinátor může zpracovat více souborů v jedné operaci pomocí pole záměrů. To je vhodné pro přesun, kopírování nebo mazání sady souborů jako jedné transakce. Pokud jeden ze záměrů nelze provést, celá operace je zrušena s chybou.

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)
}

Asynchronní koordinace — od iOS 15 NSFileCoordinator podporuje asynchronní metody s completion handler, což umožňuje provádět koordinaci bez blokování volajícího vlákna. To je kriticky důležité pro UI vlákno, kde synchronní čekání na koordinaci může způsobit zamrznutí rozhraní na sekundy.

Protokol NSFilePresenter a oznámení

NSFilePresenter — je protokol, který objekt implementuje pro přijímání oznámení o změnách souborů koordinovaných NSFileCoordinator. Pokud vaše aplikace zobrazuje obsah souboru, který může být změněn jiným procesem (například iCloud Drive synchronizuje novou verzi), implementace NSFilePresenter umožňuje včasnou aktualizaci rozhraní.

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)
    }
}

Metody protokolu: presentedItemDidChange je volána při změně obsahu souboru, presentedItemDidMove(to:) — po přesunu souboru, accommodatePresentedItemDeletion — před smazáním souboru jiným procesem (umožňuje aplikaci správně zavřít soubor). Dále protokol podporuje verzování prostřednictvím presentedItemDidGainVersion: a presentedItemDidLoseVersion:.

Důležité: NSFilePresenter musí být zaregistrován v systému prostřednictvím NSFileCoordinator.addFilePresenter:. Bez registrace nebudou oznámení doručována. Registrace se provádí jednou při spuštění aplikace a nevyžaduje opětovnou registraci při opětovném vytvoření presenteru.

Nejlepší postupy koordinace souborů

Vždy používejte koordinátora pro soubory v Ubiquity container (iCloud Drive) a adresářích přístupných rozšířením. I když je aplikace aktuálně jednovláknová, budoucí aktualizace nebo systémové změny mohou přidat paralelní přístup a nedostatek koordinace povede k obtížně nalezitelným chybám.

Minimalizujte čas v koordinačním bloku. Během provádění bloku nemohou ostatní procesy přistupovat k souboru. Dlouhé operace uvnitř bloku (složité zpracování dat, síťové požadavky) blokují celý systém přístupu k souborům. Provádějte pouze čtení nebo zápis dat uvnitř bloku a zpracování mimo něj.

Vyhněte se deadlockům: nevolajte koordinátora zevnitř bloku jiného koordinátora pro stejný soubor — to povede k vzájemnému blokování. Používejte dávkové operace (pole záměrů) namísto vnořených volání. Pokud je vnoření nezbytné, použijte různé fronty nebo různá URL.

Podle objc.io (2024) typické chyby při práci s NSFileCoordinator zahrnují: chybějící zpracování chyb v completion handler (vede k nedokončeným operacím); koordinace pouze pro zápis, ale ne pro čtení; používání zastaralého synchronního API v UI vlákně; ignorování protokolu NSFilePresenter při práci s iCloud Drive. Poslední chyba je nejzákeřnější: aplikace zobrazuje zastaralá data, aniž by věděla, že soubor již byl změněn.

Často kladené otázky

Co je NSFileCoordinator?

NSFileCoordinator — třída Foundation pro bezpečný přístup k souborům z více vláken nebo procesů. Zabraňuje race conditions koordinací operací čtení a zápisu na úrovni souborového systému.

Čím se NSFileCoordinator liší od NSLock?

NSLock funguje pouze uvnitř jednoho procesu (mezi vlákny). NSFileCoordinator koordinuje přístup mezi různými procesy a rozšířeními, včetně synchronizace iCloud Drive a File Provider Extension.

Je použití NSFileCoordinator pro iCloud Drive povinné?

Ano, Apple důrazně doporučuje používat NSFileCoordinator pro všechny operace se soubory Ubiquity container. Bez koordinátora je možné poškození dat při synchronizaci mezi zařízeními a konflikty s File Provider Extension.

Co je NSFilePresenter?

NSFilePresenter — protokol pro přijímání oznámení o změnách souborů. Umožňuje aplikaci reagovat na změny provedené jinými procesy: aktualizovat UI při změně, zpracovat přesun nebo se připravit na smazání souboru.

Jaké typy záměrů NSFileCoordinator podporuje?

Pět typů: ReadingIntent (čtení), WritingIntent (zápis), ReadingIntent s .withoutChanges (čtení bez sledování), WritingIntent s .contentIndependentMetadataOnly (pouze metadata) a WritingIntent s .forDeleting (smazání). Každý určuje úroveň přístupu k souboru.

Shrnutí

  • NSFileCoordinator — systémový mechanismus pro bezpečný přístup k souborům z vláken, procesů a rozšíření
  • Koordinační záměry (čtení/zápis) deklarují typ operace před jejím provedením
  • Čtení je povoleno paralelně, zápis je exkluzivní (model readers-writer)
  • NSFilePresenter — protokol oznámení o změnách souborů z jiných procesů
  • iCloud Drive a File Provider vyžadují povinnou koordinaci k prevenci poškození dat
  • Minimalizujte čas v koordinačním bloku — dlouhé operace blokují přístup ostatních procesů
  • Deadlocky se předchází dávkovými operacemi a vyhýbáním se vnořeným voláním koordinátora

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také