NSFileCoordinator — coordenação de acesso a arquivos no iOS

Autor: IT Sectr Publicado: 2026-07-11 Tempo de leitura: 7 min

NSFileCoordinator é uma classe Foundation no iOS e macOS que garante acesso seguro a arquivos quando múltiplas threads, processos ou extensões trabalham simultaneamente. De acordo com a Documentação do Desenvolvedor Apple, 2024, NSFileCoordinator previne condições de corrida ao ler e escrever arquivos, garantindo que nenhum processo leia dados enquanto outro os está modificando. O coordenador é usado no iCloud Drive, File Provider Extension e em qualquer operação de arquivos multithread.

Principais conclusões

  • NSFileCoordinator — uma classe para acesso seguro a arquivos de múltiplas threads e processos
  • Intenções de coordenação (reading/writing intent) declaram o tipo de operação antes da execução
  • Prevenção de condições de corrida — a principal tarefa do coordenador no acesso paralelo
  • Suporte a File Provider — o coordenador é obrigatório ao trabalhar com arquivos do iCloud Drive e extensões
  • NSFilePresenter — um protocolo para receber notificações sobre alterações em arquivos de outros processos

O que é NSFileCoordinator?

NSFileCoordinator é um mecanismo de sincronização de acesso a arquivos a nível do sistema operacional, apresentado pela Apple no iOS 5 e macOS 10.7 Lion. Ao contrário dos locks tradicionais (NSLock, pthread_mutex), o coordenador funciona a nível do sistema de arquivos e pode coordenar o acesso entre diferentes processos, não apenas entre threads da mesma aplicação.

A necessidade do NSFileCoordinator surge da arquitetura Sandbox no iOS: cada processo (aplicação, extensão, serviço do sistema) executa em um ambiente isolado com seu próprio acesso a arquivos. Quando múltiplos processos tentam ler e escrever o mesmo arquivo simultaneamente (por exemplo, durante a sincronização do iCloud Drive), sem um coordenador ocorrem condições de corrida: o processo A lê o arquivo enquanto o processo B já o sobrescreveu parcialmente.

De acordo com a WWDC 2023, a Apple recomenda fortemente o uso do NSFileCoordinator para todas as operações de arquivos no container Ubiquity (iCloud Drive) e ao trabalhar com File Provider Extension. Ignorar a coordenação é uma das causas comuns de corrupção de dados e bugs não reproduzíveis em aplicações iOS.

Tipos de intenções de coordenação

Intenção de coordenação (NSFileCoordinator.ReadingIntent / WritingIntent) é um objeto que declara o tipo de operação que uma thread ou processo planeja realizar. O coordenador usa essas intenções para determinar a ordem de acesso e resolver conflitos.

Tipo de intençãoDescriçãoQuando usar
ReadingIntentLeitura de arquivo sem modificaçõesAbrir um documento, carregar dados
WritingIntentEscrita com possível modificação de conteúdoSalvar um documento, editar
ReadingIntent(URL, options: .withoutChanges)Leitura sem rastreamento de alteraçõesPré-visualização rápida de conteúdo
WritingIntent(URL, options: .contentIndependentMetadataOnly)Modificação apenas de metadadosAtualizar data ou atributos
WritingIntent(URL, options: .forDeleting)Exclusão de arquivoExclusão de documento pelo usuário

Regras de coordenação: múltiplas leituras simultâneas são permitidas (se não houver escrita ativa), a escrita é exclusiva — nenhuma leitura ou escrita é permitida durante uma operação de escrita. Isso segue o modelo de lock leitores-escritores, mas com suporte adicional para coordenação entre processos através de launchd e XPC.

Nuance importante: NSFileCoordinator não impede o acesso a arquivos via NSData ou FileManager comuns — ele coordena apenas as operações que estão explicitamente envolvidas em blocos de coordenação. Se outra thread acessar o arquivo diretamente sem o coordenador, ocorrem exatamente as condições de corrida que o coordenador foi projetado para prevenir.

NSFileCoordinator em ação: exemplos de código

Padrão básico de uso do NSFileCoordinator consiste em três passos: criar uma instância do coordenador, declarar uma intenção (leitura ou escrita) e realizar a operação dentro de um bloco de coordenação. O coordenador garante que nenhum outro coordenador trabalhe simultaneamente com o mesmo arquivo.

swift
import Foundation

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

// Safe reading
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)
}

// Safe writing
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ção em lote — o coordenador pode lidar com múltiplos arquivos em uma única operação usando um conjunto de intenções. Isso é conveniente para mover, copiar ou excluir um conjunto de arquivos como uma transação única. Se uma das intenções não puder ser cumprida, toda a operação é cancelada com um erro.

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

Coordenação assíncrona — a partir do iOS 15, o NSFileCoordinator suporta métodos assíncronos com um handler de conclusão, permitindo coordenação sem bloquear a thread chamadora. Isso é crítico para a thread da UI, onde a espera síncrona por coordenação pode causar congelamento da interface por segundos.

Protocolo NSFilePresenter e notificações

NSFilePresenter é um protocolo que um objeto implementa para receber notificações sobre alterações em arquivos coordenados pelo NSFileCoordinator. Se sua aplicação exibe o conteúdo de um arquivo que pode ser alterado por outro processo (por exemplo, iCloud Drive sincroniza uma nova versão), implementar NSFilePresenter permite atualizar a interface oportunamente.

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

Métodos do protocolo: presentedItemDidChange é chamado quando o conteúdo do arquivo muda, presentedItemDidMove(to:) — após a realocação do arquivo, accommodatePresentedItemDeletion — antes da exclusão do arquivo por outro processo (permite que a aplicação feche o arquivo graciosamente). Adicionalmente, o protocolo suporta versionamento através de presentedItemDidGainVersion: e presentedItemDidLoseVersion:.

Importante: NSFilePresenter deve ser registrado no sistema através de NSFileCoordinator.addFilePresenter:. Sem registro, as notificações não serão entregues. O registro é realizado uma vez na inicialização da aplicação e não requer novo registro quando o apresentador é recriado.

Melhores práticas de coordenação de arquivos

Sempre use o coordenador para arquivos no container Ubiquity (iCloud Drive) e diretórios acessíveis por extensões. Mesmo que a aplicação atualmente seja single-thread, futuras atualizações ou mudanças do sistema podem adicionar acesso paralelo, e a falta de coordenação levará a bugs difíceis de encontrar.

Minimize o tempo dentro do bloco de coordenação. Enquanto o bloco está executando, outros processos não podem acessar o arquivo. Operações longas dentro do bloco (processamento complexo de dados, requisições de rede) bloqueiam todo o sistema de acesso a arquivos. Realize apenas leitura ou escrita de dados dentro do bloco e processe fora dele.

Evite deadlocks: não chame o coordenador de dentro do bloco de outro coordenador para o mesmo arquivo — isso causará um deadlock mútuo. Use operações em lote (conjunto de intenções) em vez de chamadas aninhadas. Se o aninhamento for necessário, use filas diferentes ou URLs diferentes.

De acordo com objc.io (2024), erros típicos ao trabalhar com NSFileCoordinator incluem: falta de tratamento de erros no handler de conclusão (leva a operações incompletas); coordenação apenas para escritas mas não para leituras; uso da API síncrona obsoleta na thread da UI; ignorar o protocolo NSFilePresenter ao trabalhar com iCloud Drive. O último erro é o mais insidioso: a aplicação exibe dados desatualizados sem perceber que o arquivo já foi modificado.

Perguntas frequentes

O que é NSFileCoordinator?

NSFileCoordinator é uma classe Foundation para acesso seguro a arquivos de múltiplas threads ou processos. Ele previne condições de corrida coordenando operações de leitura e escrita a nível do sistema de arquivos.

Qual a diferença entre NSFileCoordinator e NSLock?

NSLock funciona apenas dentro de um único processo (entre threads). NSFileCoordinator coordena o acesso entre diferentes processos e extensões, incluindo sincronização do iCloud Drive e File Provider Extension.

É obrigatório usar NSFileCoordinator para iCloud Drive?

Sim, a Apple recomenda fortemente o uso do NSFileCoordinator para todas as operações de arquivos no container Ubiquity. Sem o coordenador, podem ocorrer corrupção de dados durante a sincronização entre dispositivos e conflitos com File Provider Extension.

O que é NSFilePresenter?

NSFilePresenter é um protocolo para receber notificações sobre alterações em arquivos. Permite que a aplicação reaja a alterações feitas por outros processos: atualizar a UI em modificações, lidar com realocações ou preparar-se para exclusão de arquivos.

Quais tipos de intenção o NSFileCoordinator suporta?

Cinco tipos: ReadingIntent (leitura), WritingIntent (escrita), ReadingIntent com .withoutChanges (leitura sem rastreamento), WritingIntent com .contentIndependentMetadataOnly (apenas metadados) e WritingIntent com .forDeleting (exclusão). Cada um define o nível de acesso ao arquivo.

Resumo

  • NSFileCoordinator — um mecanismo do sistema para acesso seguro a arquivos de threads, processos e extensões
  • Intenções de coordenação (leitura/escrita) declaram o tipo de operação antes da execução
  • Leituras permitidas em paralelo, escritas exclusivas (modelo leitores-escritores)
  • NSFilePresenter — um protocolo para notificações sobre alterações em arquivos de outros processos
  • iCloud Drive e File Provider requerem coordenação obrigatória para prevenir corrupção de dados
  • Minimize o tempo dentro do bloco de coordenação — operações longas bloqueiam o acesso de outros processos
  • Deadlocks são prevenidos através de operações em lote e evitando chamadas aninhadas ao coordenador

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também