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同期 — 2番目の主要シナリオ。1つのデバイスでファイルが変更されると、iCloudはそれをすべての接続デバイス間で同期します。NSFilePresenterはアプリケーションにこれらの変更を通知し、タイムリーなインターフェース更新を可能にします。

マルチスレッドエディタ — 3番目のシナリオ。バックグラウンドキューがユーザーの作業と同時にデータをロードおよび保存するアプリケーションでは、NSFilePresenterがファイルの書き込みと読み取り中の競合状態を防止します。

NSFilePresenterの仕組み

動作メカニズム NSFilePresenterは委任モデルに基づいています。オブジェクトはプロトコルメソッドを実装し、NSFileCoordinatorを介して登録し、追跡対象ファイルが変更されるたびに呼び出しを受け取ります。システム自体が変更の発生時期と呼び出すメソッドを決定します。

プロセスは、オブジェクトがNSFileCoordinatorのインスタンスを作成し、ファイルURLを渡してコーディネーターのメソッドを呼び出すことから始まります。コーディネーターは、このURLにプレゼンターが登録されているかどうかを確認します。登録されている場合、読み取りまたは書き込みアクセスをブロックし、プロトコルメソッドを介してプレゼンターに今後の変更を通知します。

操作が完了した後、コーディネーターはロックを解除し、最終通知を呼び出します。重要なのは、プレゼンターが実行フローを制御しないことです—イベントに反応するだけです。NSFileCoordinatorが調整に完全に責任を持ちます。

通知のライフサイクル

準備フェーズ — 操作を実行する前に、コーディネーターはaccommodatePresentedItemDeletionまたはaccommodatePresentedSubitemDeletionを呼び出します。プレゼンターは状況を処理するか、エラーを返して操作をキャンセルできます。このフェーズにより、アプリケーションはファイルが変更される前にファイルとの作業を適切に終了できます。

通知フェーズ — 操作が完了した後、コーディネーターはpresentedItemDidChangeまたはpresentedSubitemDidChangeを呼び出します。プレゼンターはファイルが変更されたシグナルを受信し、その内容を再読み取りできます。ファイルの移動については、新しい場所とともにpresentedItemDidMoveToURLが呼び出されます。

完了フェーズ — コーディネーターはすべてのロックを解除し、リソースを解放します。プレゼンターは更新されたデータで作業を続行できます。3つのフェーズすべてが単一のスレッドで同期的に実行されるため、プロトコルメソッドは長時間の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を使用してください。

2番目の間違いは、プレゼンターメソッドでのブロッキングです。プロトコルメソッドはコーディネーターから同期的に呼び出されます。プレゼンターが長時間の操作(データベース書き込み、ネットワークリクエスト)を実行すると、他のすべての参加者に対してコーディネーターをブロックします。重い操作はバックグラウンドキューに移動してください。

3番目の間違いは、accommodatePresentedItemDeletionの無視です。プレゼンターがこのメソッドを実装せず、エラーを返さない場合、現在の状態を保存せずにファイルが削除される可能性があります。このメソッドでは、データがまだディスクに書き込まれていない場合は常に保存してください。

4番目の間違いは、循環調整です。プレゼンターが通知メソッド内で同じファイルに対して再度コーディネーターを呼び出すと、デッドロックが発生します。ハンドラー内で調整を開始する前に、isCoordinatedOperationフラグを確認してください。

間違い結果解決策
操作キューなしマルチスレッドでのデータ競合OperationQueueを指定
メソッドでのブロッキングコーディネーターのハングバックグラウンドスレッドへ移動
削除の無視削除時のデータ損失保存を実装
循環調整アプリケーションのデッドロックisCoordinatedOperationフラグ

よくある質問

NSFileHandleがあるのにNSFilePresenterが必要な理由は?

NSFileHandleはデータの読み書きのための低レベルインターフェースであり、他のプロセスからの変更通知メカニズムを提供しません。NSFilePresenterは調整レベルで機能します:ファイルが変更されるたびに、ソース(別のスレッド、プロセス、iCloud)に関係なく、システムからイベントを受信します。

NSFilePresenterと一緒にNSFileCoordinatorを使用するのは必須ですか?

はい。NSFilePresenterはNSFileCoordinatorなしでは意味がありません。プレゼンターはハンドラーメソッドを定義するだけであり、コーディネーターがロックを管理し、これらのメソッドを呼び出します。コーディネーターなしでNSFilePresenterを使用すると、通知は配信されません。

1つのオブジェクトが複数のファイルのプレゼンターになることはできますか?

可能ですが、制限があります。presentedItemURLプロパティは1つの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アプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください