NSFilePresenter: 개요, NSFileCoordinator 프로토콜 및 추적 메소드

저자: IT Sectr 게시일: 2026-07-12 읽는 시간: 7 분

NSFilePresenter는 Foundation 프로토콜로, 객체가 iOS 및 macOS 파일 시스템에서 파일 및 디렉토리 변경에 대한 알림을 받을 수 있도록 합니다. 클래스는 프로토콜 메서드를 구현하고 NSFileCoordinator를 통해 등록하며, 이후 시스템은 추적 중인 파일에 대한 모든 작업 중에 자동으로 이러한 메서드를 호출합니다. Apple Developer Documentation(2025)에 따르면 NSFilePresenter는 쓰기 충돌을 방지하기 위해 멀티스레드 문서 액세스가 있는 애플리케이션에서 사용됩니다. 프로토콜은 NSFileCoordinator와 함께 사용해야 합니다 — 그래야만 안전한 액세스 조정이 보장됩니다.

핵심 사항

  • NSFilePresenter — iOS 및 macOS에서 파일 및 디렉토리 변경을 추적하기 위한 Foundation 프로토콜.
  • NSFileCoordinator — 액세스를 관리하고 델리게이트 메서드를 호출하는 필수 동반 클래스.
  • accommodatePresentedItemDeletion — 취소 기능이 있는 추적 파일 삭제 처리를 위한 메서드.
  • presentedItemDidChange — 파일 또는 디렉토리 내용이 변경될 때 호출됩니다.
  • presentedItemURL — 추적 중인 파일의 URL을 반환하는 필수 속성.

NSFilePresenter란?

NSFilePresenter는 Apple 운영 체제에서 파일 및 디렉토리 변경을 추적하도록 설계된 Foundation 프로토콜입니다. 프로토콜은 관찰자 객체가 파일 시스템 이벤트 알림을 받기 위해 구현하는 메서드 집합을 정의합니다.

프로토콜의 주요 목적은 멀티스레드 시나리오에서 안전한 파일 액세스를 제공하는 것입니다. iOS 및 macOS에서는 여러 프로세스와 스레드가 NSFileCoordinator를 통해 동시에 동일한 파일에 액세스할 수 있으며, NSFilePresenter는 각 참가자가 최신 데이터 상태를 받도록 보장합니다.

이 프로토콜은 iOS 5.0 및 macOS 10.7부터 Foundation에 포함되었습니다. 문서, 데이터베이스 및 여러 소스에서 동시에 수정될 수 있는 파일(iCloud 동기화 또는 공동 편집 중)을 사용하는 애플리케이션에서 사용됩니다.

NSFilePresenter 사용처

문서 기반 애플리케이션 — NSFilePresenter의 주요 사용 영역. UIDocument 또는 NSDocument를 사용하는 애플리케이션은 NSFileCoordinator를 통해 자동으로 프레젠터로 등록됩니다. 이를 통해 여러 창이나 장치에서 동일한 파일을 편집할 때 충돌을 올바르게 처리할 수 있습니다.

iCloud 동기화 — 두 번째 주요 시나리오. 한 장치에서 파일이 수정되면 iCloud가 연결된 모든 장치에 동기화합니다. NSFilePresenter는 애플리케이션에 이러한 변경 사항을 알려 적시에 인터페이스를 업데이트할 수 있도록 합니다.

멀티스레드 편집기 — 세 번째 시나리오. 백그라운드 큐가 사용자 작업과 동시에 데이터를 로드하고 저장하는 애플리케이션에서 NSFilePresenter는 파일 쓰기 및 읽기 중 경쟁 상태를 방지합니다.

NSFilePresenter 작동 방식

작동 메커니즘 NSFilePresenter는 위임 모델을 기반으로 합니다. 객체는 프로토콜 메서드를 구현하고, NSFileCoordinator를 통해 등록하며, 추적 중인 파일이 변경될 때마다 호출을 받습니다. 시스템 자체가 변경 발생 시점과 호출할 메서드를 결정합니다.

프로세스는 객체가 NSFileCoordinator 인스턴스를 생성하고 파일 URL을 전달하여 코디네이터의 메서드를 호출할 때 시작됩니다. 코디네이터는 이 URL에 등록된 프레젠터가 있는지 확인합니다. 있으면 읽기 또는 쓰기 액세스를 차단하고 프로토콜 메서드를 통해 프레젠터에 예정된 변경 사항을 알립니다.

작업이 완료된 후 코디네이터는 잠금을 해제하고 최종 알림을 호출합니다. 중요한 점은 프레젠터가 실행 흐름을 제어하지 않는다는 것입니다 — 이벤트에만 반응합니다. NSFileCoordinator가 조정을 완전히 담당합니다.

알림 수명 주기

준비 단계 — 작업을 실행하기 전에 코디네이터가 accommodatePresentedItemDeletion 또는 accommodatePresentedSubitemDeletion을 호출합니다. 프레젠터는 상황을 처리하거나 오류를 반환하여 작업을 취소할 수 있습니다. 이 단계를 통해 애플리케이션은 파일이 수정되기 전에 파일 작업을 올바르게 종료할 수 있습니다.

알림 단계 — 작업 완료 후 코디네이터가 presentedItemDidChange 또는 presentedSubitemDidChange를 호출합니다. 프레젠터는 파일이 변경되었다는 신호를 받고 내용을 다시 읽을 수 있습니다. 파일 이동의 경우 새 위치와 함께 presentedItemDidMoveToURL이 호출됩니다.

완료 단계 — 코디네이터가 모든 잠금을 해제하고 리소스를 해제합니다. 프레젠터는 업데이트된 데이터로 계속 작업할 수 있습니다. 세 단계 모두 단일 스레드에서 동기적으로 실행되므로 프로토콜 메서드는 긴 I/O 작업 없이 신속하게 실행되어야 합니다.

프로토콜의 주요 메서드

NSFilePresenter 프로토콜에는 여러 필수 및 선택적 메서드가 포함됩니다. 유일한 필수 속성은 presentedItemURL로, 추적 중인 파일 또는 디렉토리의 URL을 반환합니다. 이 속성이 없으면 객체를 프레젠터로 등록할 수 없습니다.

필수 메서드

presentedItemURL — 추적 중인 파일의 경로를 반환해야 하는 URL? 유형의 속성. 객체가 여러 파일을 추적하는 경우 속성은 기본 항목의 URL을 반환합니다. 디렉토리의 경우 디렉토리 URL을 반환합니다.

presentedItemDidChange — 추적 중인 파일의 내용이 변경된 후 호출됩니다. 이 메서드에서 프레젠터는 내부 상태를 업데이트하고 데이터를 다시 로드합니다. 이 메서드는 무엇이 변경되었는지에 대한 정보를 받지 않습니다 — 변경 사실만 받습니다.

선택적 메서드

accommodatePresentedItemDeletion — 파일 삭제 전에 호출됩니다. 프레젠터는 현재 상태를 저장하거나, 파일 디스크립터를 닫거나, NSError를 반환하여 작업을 취소할 수 있습니다. 메서드가 오류를 반환하면 삭제 작업이 수행되지 않습니다.

presentedItemDidMoveToURL — 파일 이동 또는 이름 변경 후 호출됩니다. 메서드는 새 URL을 받고 프레젠터는 파일 참조를 업데이트해야 합니다. 이 메서드를 구현하지 않으면 프레젠터가 존재하지 않는 이전 경로를 계속 가리킵니다.

NSFilePresenter와 NSFileCoordinator

NSFileCoordinatorNSFilePresenter는 떼려야 뗄 수 없는 쌍입니다. NSFileCoordinator는 파일 액세스를 관리하고 프레젠터 메서드를 호출합니다. 프레젠터는 파일 시스템과 직접 작동하지 않습니다 — 모든 작업은 변경의 원자성을 보장하는 코디네이터를 통해 이루어집니다.

코디네이터는 NSFileCoordinator 클래스의 addFilePresenter 메서드를 통해 프레젠터를 등록합니다. 등록 후 프레젠터는 알림 받기를 시작합니다. 제거는 removeFilePresenter를 통해 이루어집니다. 시스템은 프레젠터에 대한 약한 참조를 유지하므로 객체는 추적 기간 동안 계속 존재해야 합니다.

Apple WWDC 2022에 따르면 NSFileCoordinator는 커널 수준 조정 메커니즘을 사용하여 잠금 중 지연 시간을 최소화합니다. 최신 iOS 버전에서는 코디네이터가 Sandbox 및 앱 확장과 함께 작동하도록 최적화되었습니다.

조정 규칙

Intention — 각 읽기 또는 쓰기 작업은 조정 블록으로 래핑되어야 합니다: coordinateReadingItemAtURL을 통한 읽기, coordinateWritingItemAtURL을 통한 쓰기. 코디네이터는 블록 실행 중 다른 참가자에 대해 자동으로 파일을 잠급니다.

배치 조정 — 여러 파일이 포함된 작업에는 배치 조정이 사용됩니다. 코디네이터는 지정된 모든 파일을 원자적으로 잠그고 작업을 수행한 후 잠금을 해제합니다. 문서 세트를 이동하거나 복사할 때 이는 매우 중요합니다.

구현 예제

NSFilePresenter 프로토콜을 구현하고 문서 파일의 변경 사항을 추적하는 DocumentPresenter 클래스를 만들어 보겠습니다. 클래스에는 파일 참조, 내부 데이터 및 유효성 플래그가 포함됩니다.

swift
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) {
        // 문서 데이터 처리
    }
}

클래스는 파일 변경 시 데이터를 다시 로드하기 위한 presentedItemDidChange와 삭제 전 상태 저장을 위한 accommodatePresentedItemDeletion을 구현합니다. 작업 큐는 모든 알림이 순차적으로 처리되도록 보장합니다.

프레젠터 등록은 문서를 열 때 NSFileCoordinator.addFilePresenter를 통해 수행됩니다. 코디네이터에 올바른 읽기 옵션을 전달하는 것이 중요합니다 — 변경되지 않는 작업의 경우 withoutChanges, 즉시 액세스가 필요한 시나리오의 경우 immediatelyAvailable.

일반적인 실수

첫 번째 일반적인 실수는 presentedItemOperationQueue 구현 부족입니다. 큐를 지정하지 않으면 알림이 임의의 스레드에 도착하여 데이터 경쟁이 발생할 수 있습니다. 알림 처리를 위해 항상 직렬 OperationQueue를 사용하세요.

두 번째 실수는 프레젠터 메서드에서의 차단입니다. 프로토콜 메서드는 코디네이터에서 동기적으로 호출됩니다. 프레젠터가 긴 작업(데이터베이스 쓰기, 네트워크 요청)을 수행하면 다른 모든 참가자에 대해 코디네이터를 차단합니다. 무거운 작업은 백그라운드 큐로 이동하세요.

세 번째 실수는 accommodatePresentedItemDeletion 무시입니다. 프레젠터가 이 메서드를 구현하지 않고 오류를 반환하지 않으면 현재 상태를 저장하지 않고 파일이 삭제될 수 있습니다. 아직 디스크에 기록되지 않은 경우 이 메서드에서 항상 데이터를 저장하세요.

네 번째 실수는 순환 조정입니다. 프레젠터가 알림 메서드 내에서 동일한 파일에 대해 코디네이터를 다시 호출하면 교착 상태가 발생합니다. 핸들러 내에서 조정을 시작하기 전에 isCoordinatedOperation 플래그를 확인하세요.

실수결과해결책
작업 큐 없음멀티스레딩에서 데이터 경쟁OperationQueue 지정
메서드 차단코디네이터 중단백그라운드 스레드로 이동
삭제 무시삭제 시 데이터 손실저장 구현
순환 조정애플리케이션 교착 상태isCoordinatedOperation 플래그

자주 묻는 질문

NSFileHandle이 있는데 NSFilePresenter가 필요한 이유는?

NSFileHandle은 데이터 읽기 및 쓰기를 위한 저수준 인터페이스로, 다른 프로세스의 변경 알림 메커니즘을 제공하지 않습니다. NSFilePresenter는 조정 수준에서 작동합니다: 소스(다른 스레드, 프로세스 또는 iCloud)에 관계없이 파일이 변경될 때마다 시스템에서 이벤트를 수신합니다.

NSFilePresenter와 함께 NSFileCoordinator를 사용하는 것이 필수인가요?

. NSFilePresenter는 NSFileCoordinator 없이 의미가 없습니다. 프레젠터는 핸들러 메서드만 정의하고 코디네이터가 잠금을 관리하고 이러한 메서드를 호출합니다. 코디네이터 없이 NSFilePresenter를 사용하면 알림이 전달되지 않습니다.

하나의 객체가 여러 파일의 프레젠터가 될 수 있나요?

가능하지만 제한이 있습니다. presentedItemURL 속성은 하나의 URL만 반환하므로 여러 파일을 추적하려면 하위 항목에 대한 추가 메서드와 함께 NSFilePresenter 프로토콜을 사용합니다. 대안은 각 파일에 대해 별도의 프레젠터 인스턴스를 만드는 것입니다.

NSFilePresenter는 iOS Sandbox와 어떻게 작동하나요?

NSFilePresenter는 iOS 샌드박스와 완전히 호환됩니다. 애플리케이션은 자체 컨테이너 내의 파일만 추적할 수 있습니다. 다른 애플리케이션의 파일에 액세스하려면 App Groups 또는 Security-Scoped Bookmarks를 사용합니다. 코디네이터는 샌드박스 권한 내에서 작동합니다.

presentedItemDidChange가 너무 자주 호출되면 어떻게 해야 하나요?

presentedItemDidChange 메서드 내에서 debounce 또는 throttle을 사용하세요. 0.3–0.5초 지연으로 타이머를 만들고 새 호출마다 재설정합니다. 안정화 후 데이터 다시 로드를 수행합니다. 이렇게 하면 단일 변경 배치의 여러 처리를 방지할 수 있습니다.

요약

  • NSFilePresenter — iOS 및 macOS에서 파일 변경 알림을 받기 위한 Foundation 프로토콜로, NSFileCoordinator와 함께만 작동합니다.
  • 필수 속성 presentedItemURL — 이것이 없으면 객체를 프레젠터로 등록할 수 없으며 알림을 받지 못합니다.
  • 주요 메서드 presentedItemDidChange는 파일 내용 변경 후 호출됩니다 — 데이터 다시 로드에 사용합니다.
  • accommodatePresentedItemDeletion을 통해 파일 삭제를 올바르게 처리하고 현재 애플리케이션 상태를 저장할 수 있습니다.
  • NSFileCoordinator는 잠금을 관리하고 작업의 원자성을 보장합니다 — 코디네이터 없이 프레젠터는 무용지물입니다.
  • 일반적인 실수에는 작업 큐 부족, 메서드 차단 및 순환 조정이 포함됩니다 — 적절한 설계를 통해 이를 방지해야 합니다.
  • 빈번한 호출 시 presentedItemDidChange Debounce — 다시 로드 전에 변경 사항을 배치 처리하기 위해 타이머를 사용합니다.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기