File Coordination


File coordination encompasses a set of system APIs and callbacks that allow you to coordinate file access safely between different processes or different threads.

It consists of two main system APIs:

  • NSFileCoordinator which coordinates the reading and writing of files and directories among multiple processes and objects in the same process.
  • NSFilePresenter a protocol that should be implemented by objects that allow the user to view or edit the content of files or directories.

NSFileCoordinator essentially represents a cross process file locking mechanism while NSFilePresenter offers callbacks that can be used to refresh your application state due to external file changes.

File coordination and PSPDFKit

PSPDFKit for iOS supports file coordination out of the box since version 6.7.0. Coordinated file access is handled on the data provider level, using PSPDFCoordinatedFileDataProvider. PSPDFCoordinatedFileDataProvider is a subclass of our standard PSPDFFileDataProvider, which is used to read and write data from/to a PDF file on disk. The coordinated subclass adds coordinated file access using NSFileCoordinator and implements NSFilePresenter callbacks that act on external file modifications.

Using file coordination in PSPDFKit

If you are using any of the standard PSPDFDocument initializers that take a file URL as input (such as documentWithURL:), then good news, there is nothing you need to do. You are already using file coordination. PSPDFDocument will automatically create a PSPDFCoordinatedFileDataProvider behind the scenes when it receives a file URL during initialization.

If you are initializing the document using an explicit data provider that acts on files (via documentWithDataProvider:), then we recommend switching to PSPDFCoordinatedFileDataProvider or a subclass of it.

Disable file coordination

In most cases, it is recommended to use the default behavior and keep file coordination turned on for all files. File coordination is important whenever there is a chance that multiple processes (or threads inside your app) could be accessing the same file on disk at the same time. That might happen if you are providing extensions, using iCloud, using our FTS library indexing, or simply executing multithreaded code. If you are however sure, that this is not something that affects you, or if you are experiencing problems related to file coordination, you can opt to not use file coordination inside your app.

You can disable file coordination in two ways.

  1. On a case by case basis, using PSPDFDocument via its documentWithDataProvider: initializer, passing a regular PSPDFFileDataProvider instance instead of a PSPDFCoordinatedFileDataProvider.
  2. By changing the global default during PSPDFKit initialization (PSPDFFileCoordinationEnabledKey).
Copy
1
PSPDFKit.setLicenseKey(yourLicenseKey, options: [PSPDFFileCoordinationEnabledKey: false])
Copy
1
[PSPDFKit setLicenseKey:yourLicenseKey options:@{PSPDFFileCoordinationEnabledKey: false});

PSPDFileCoordinationDelegate

PSPDFileCoordinationDelegate is a replacement for NSFilePresenter-like callbacks on the PSPFDDocument level. Since a PSPDFDocument can be composed out of several PSPDFDataProviders (and hence several PSPDFCoordinatedFileDataProviders) it doesn't implement NSFilePresenter directly. Instead the coordinated providers forward the file presenter calls to the document using PSPDFileCoordinationDelegate callbacks. You can override those callbacks in your subclasses, if you need perform custom behaviors in response to document update. If you do so, be sure to call super to ensure appropriate default behaviors are also invoked by PSPDFDocument.

Registering for file presenter callbacks

File presenters need to be enabled from UI classes when they become active, and deactivated when UI presentation ends. NSFileCoordinator defines addFilePresenter: and removeFilePresenter: to do so. To help with this, PSPDFKit adds PSPDFFilePresenterCoordinator, which defines helpers for registering multiple file presenters at the same time and takes care of automatically temporarily unregistering file presenters while the application is in the background. Failing to do so risks, according to Apple documentation, system wide deadlocks.

If you are using PSPDFDocuments in your custom view controllers you should use PSPDFFilePresenterCoordinator to initiate file observation when presenting a PSPDFDocument:

Copy
1
PSPDFFilePresenterCoordinator.shared.observe(document.filePresenters)
Copy
1
[PSPDFFilePresenterCoordinator.sharedCoordinator observeFilePresenters:self.document.filePresenters];

and when ending document presentation:

Copy
1
PSPDFFilePresenterCoordinator.shared.unobserve(document.filePresenters)
Copy
1
[PSPDFFilePresenterCoordinator.sharedCoordinator unobserveFilePresenters:self.document.filePresenters];

Be sure to also implement PSPDFDocumentUnderlyingFileChangedNotification to receive file coordination changes from the presented document(s).

Built-in PSPDFKit controllers (PSPDFViewController and PSPDFMultiDocumentViewController) already implement PSPDFFilePresenterCoordinator methods when setting and changing documents, so if you are using or subclassing them, there is nothing you need to do in this regard. They also implement PSPDFDocumentUnderlyingFileChangedNotification and automatically reload the UI or remove the document, depending on the change type.

Was this page helpful? We're happy to answer any questions.