Document works with local files and custom data providers. The behavior around file observation, conflict resolution, and automatic saving depends on which path you choose.

If you’re opening a file that already exists on disk, use Document(url:) to create the document.

For local file URLs, Document(url:) creates either a CoordinatedFileDataProvider or a FileDataProvider, depending on SDK.Setting.fileCoordinationEnabled. That setting is enabled by default, so the standard setup uses a CoordinatedFileDataProvider.

With a coordinated file-backed document, Nutrient can:

  • Observe changes to the underlying file.
  • Participate in the built-in conflict resolution flow when conflict resolution is available.

When using PDFView and PDFViewController, file presenters are registered for you. If you present documents in custom view controllers, follow the file coordination guide to register and unregister the document’s file presenters.

Data provider choice

If you create a document with Document(dataProviders:), the behavior depends on the provider you pass in:

This matters because only coordinated providers expose file presenter callbacks and conflict resolution APIs. If you pass FileDataProvider yourself, Nutrient can still read and write the file, but it won’t observe external file changes through file presentation callbacks or offer coordinated conflict resolution for that provider.

Choose a save setup

PDFView and PDFViewController save automatically only when isAutosaveEnabled is true. If automatic saving is disabled, no automatic save runs, and your app is responsible for choosing when to save.

When automatic saving is enabled, allowBackgroundSaving controls whether Nutrient saves in the background or synchronously.

The default value follows SDK.Setting.fileCoordinationEnabled. In the standard coordinated setup, that means allowBackgroundSaving defaults to true.

Asynchronous (background) saving is better for UI responsiveness because it doesn’t block the UI while the file is written. The tradeoff is that the save can still be in progress after your code continues. If your app closes a viewer, stops using its Document, and creates another Document for the same backing file before the save finishes, the new instance can load stale on-disk state.

Synchronous saving (when background saving is disabled) requires the save to finish before your code continues. This makes save ordering easier to reason about, but it can block the calling thread, so it’s better suited to background processing or other noninteractive workflows.

File coordination enables Nutrient to detect this kind of conflict. Depending on the situation, Nutrient may reload the file automatically or ask the user whether to save the in-memory changes or reload the external file. These versions aren’t merged, so one side’s changes may be discarded.

Reusing one document instance across opens

If your app shows multiple documents in a list, keep each Document with the corresponding list item or document cache, and pass the same instance to the viewer whenever that file is opened.

This keeps in-memory edits and saving state tied to one object instead of creating a new Document each time the file is shown. Each Document should still be associated with only one active viewer at a time. Reuse the instance across repeated opens, not across simultaneous viewers.

For cache and data source implementation patterns, refer to using document efficiently.

Summary

This table summarizes the recommended setups for working with documents, from safest to riskiest:

SetupRecommendation
Same Document instanceBest option.
Asynchronous saving with file coordinationRecommended for UI flows.
Synchronous savingUse if you can’t use file coordination.
Asynchronous saving without file coordinationAvoid this setup.