<!--
{
  "availability" : [
    "iOS: 5.0.0 -",
    "iPadOS: 5.0.0 -",
    "macCatalyst: 13.1.0 -",
    "tvOS: -",
    "visionOS: 1.0.0 -",
    "watchOS: -"
  ],
  "documentType" : "symbol",
  "framework" : "UIKit",
  "identifier" : "/documentation/UIKit/UIDocument",
  "metadataVersion" : "0.1.0",
  "role" : "Class",
  "symbol" : {
    "kind" : "Class",
    "modules" : [
      "UIKit"
    ],
    "preciseIdentifier" : "c:objc(cs)UIDocument"
  },
  "title" : "UIDocument"
}
-->

# UIDocument

An abstract base class for managing discrete portions of your app’s data.

```
nonisolated class UIDocument
```

## Overview

Apps that make use of [`UIDocument`](/documentation/UIKit/UIDocument) and its underlying architecture get many benefits for their documents:

- Asynchronous reading and writing of data on a background queue, meaning your app’s responsiveness is unaffected while reading and writing operations take place
- Coordinated reading and writing of document files automatically integrated with cloud services
- Support for discovering conflicts between different versions of a document
- Safe-saving of document data by writing data first to a temporary file and then replacing the current document file with it
- Automatic saving of document data at opportune moments and support for dealing with suspend behaviors

In the Model-View-Controller design pattern, a [`UIDocument`](/documentation/UIKit/UIDocument) object is a model object or model-controller object — it manages the data of a document or the aggregate model objects that together constitute the document’s data. You typically pair it with a view controller that manages the view presenting the document’s contents. [`UIDocument`](/documentation/UIKit/UIDocument) provides no direct support for managing document views, but view controllers that subclass [`UIDocumentViewController`](/documentation/UIKit/UIDocumentViewController) can present a `UIDocument`, and view controllers that subclass [`UIDocumentBrowserViewController`](/documentation/UIKit/UIDocumentBrowserViewController) can organize and display `UIDocument` collections.

Document-based apps include those that can generate multiple documents, each with its own file-system location. A document-based app must create a subclass of [`UIDocument`](/documentation/UIKit/UIDocument) for its documents.

> Note:
> If you’re using a database to store document data, create a subclass of the ``doc://com.apple.uikit/documentation/UIKit/UIManagedDocument`` class instead of ``doc://com.apple.uikit/documentation/UIKit/UIDocument``; ``doc://com.apple.uikit/documentation/UIKit/UIManagedDocument`` is a subclass of ``doc://com.apple.uikit/documentation/UIKit/UIDocument``.

The primary attribute of a document in the [`UIDocument`](/documentation/UIKit/UIDocument) architecture is its file URL. When you initialize an instance of your document subclass by calling [`init(fileURL:)`](/documentation/UIKit/UIDocument/init(fileURL:)), you must pass a file URL locating the document file in the app sandbox. [`UIDocument`](/documentation/UIKit/UIDocument) determines the file type (the Uniform Type Identifier associated with the file extension) and the document name (the filename component) from the file URL. You can override the accessor methods of the [`fileType`](/documentation/UIKit/UIDocument/fileType) and [`localizedName`](/documentation/UIKit/UIDocument/localizedName) properties to supply different values.

The following outlines the life cycle of a typical document:

1. You create a new document or open an existing document.
- To create a new document, allocate and initialize an instance of your subclass and then call ``doc://com.apple.uikit/documentation/UIKit/UIDocument/save(to:for:completionHandler:)`` on the instance.
- To open an existing document (selected by the user), allocate and initialize an instance of your subclass and then call ``doc://com.apple.uikit/documentation/UIKit/UIDocument/open(completionHandler:)`` on the instance.
1. The user edits the document. As the user edits, track changes to the document. ``doc://com.apple.uikit/documentation/UIKit/UIDocument`` periodically notes when there are unsaved changes and writes the document data to its file.
1. The user requests that the document be integrated with cloud services (optional). You must enable the document for cloud storage. You must also resolve any conflicts between different versions of the same document.
1. The user closes the document. Call ``doc://com.apple.uikit/documentation/UIKit/UIDocument/close(completionHandler:)`` on the document instance. ``doc://com.apple.uikit/documentation/UIKit/UIDocument`` saves the document if there are any unsaved changes.

A typical document-based app calls [`open(completionHandler:)`](/documentation/UIKit/UIDocument/open(completionHandler:)), [`close(completionHandler:)`](/documentation/UIKit/UIDocument/close(completionHandler:)), and [`save(to:for:completionHandler:)`](/documentation/UIKit/UIDocument/save(to:for:completionHandler:)) on the main thread. When the read or save operation kicked off by these methods concludes, the system executes the completion-handler block on the same dispatch queue as the system used to invoke the method, allowing you to complete any tasks contingent on the read or save operation. If the operation isn’t successful, the system passes <doc://com.apple.documentation/documentation/Swift/false> to the completion-handler block.

### Implement the NSFilePresenter protocol

The [`UIDocument`](/documentation/UIKit/UIDocument) class adopts the <doc://com.apple.documentation/documentation/Foundation/NSFilePresenter> protocol. When another client attempts to read the document of a [`UIDocument`](/documentation/UIKit/UIDocument)-based app, the system suspends reading until the system provides the [`UIDocument`](/documentation/UIKit/UIDocument) object an opportunity to save any changes made to the document.

Although some implementations do nothing, [`UIDocument`](/documentation/UIKit/UIDocument) implements all <doc://com.apple.documentation/documentation/Foundation/NSFilePresenter> methods. Specifically, [`UIDocument`](/documentation/UIKit/UIDocument):

- Implements <doc://com.apple.documentation/documentation/Foundation/NSFilePresenter/relinquishPresentedItem(toReader:)> to forward the incoming block to ``doc://com.apple.uikit/documentation/UIKit/UIDocument/performAsynchronousFileAccess(_:)``
- Implements <doc://com.apple.documentation/documentation/Foundation/NSFilePresenter/relinquishPresentedItem(toWriter:)> to check if the file-modification date changed; if the file is newer than before, it calls ``doc://com.apple.uikit/documentation/UIKit/UIDocument/revert(toContentsOf:completionHandler:)`` with the value of the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/fileURL`` as the URL parameter
- Implements <doc://com.apple.documentation/documentation/Foundation/NSFilePresenter/presentedItemDidMove(to:)> to update the document’s file URL (``doc://com.apple.uikit/documentation/UIKit/UIDocument/fileURL``)

In your [`UIDocument`](/documentation/UIKit/UIDocument) subclass, if you override a <doc://com.apple.documentation/documentation/Foundation/NSFilePresenter> method, you can always invoke the superclass implementation (`super`).

### Create a subclass

Each document-based app must create a subclass of [`UIDocument`](/documentation/UIKit/UIDocument) whose instances represent its documents. The subclassing requirements for most apps are simple:

- For writing operations, implement the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/contents(forType:)`` method to provide a snapshot of document data. The data must be in the form of an <doc://com.apple.documentation/documentation/Foundation/NSData> object (for flat files) or an <doc://com.apple.documentation/documentation/Foundation/FileWrapper> object (for file packages). Writing operations are usually initiated through the autosave feature.
- For reading operations, implement the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/load(fromContents:ofType:)`` method to receive an <doc://com.apple.documentation/documentation/Foundation/NSData> or <doc://com.apple.documentation/documentation/Foundation/FileWrapper> object and initialize the app’s data structures with it.
- Implement change tracking to enable the autosaving feature. See <doc://com.apple.uikit/documentation/UIKit/UIDocument#Track-changes> for details.
- When cloud services are enabled for a document, resolve conflicts between different versions of a document. See <doc://com.apple.uikit/documentation/UIKit/UIDocument#Resolve-conflicts-and-handle-errors> for details.
  
  The system typically calls the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/contents(forType:)`` and ``doc://com.apple.uikit/documentation/UIKit/UIDocument/load(fromContents:ofType:)`` methods on the main queue. More specifically:
- The system calls the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/contents(forType:)`` method on the queue that the system called the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/save(to:for:completionHandler:)`` method on; writing of data takes place on a background thread.
- The system calls the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/load(fromContents:ofType:)`` method on the queue that the system called the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/open(completionHandler:)`` method on.

If you have special requirements for reading and writing document data for which the [`contents(forType:)`](/documentation/UIKit/UIDocument/contents(forType:)) and [`load(fromContents:ofType:)`](/documentation/UIKit/UIDocument/load(fromContents:ofType:)) methods won’t suffice, you can override other methods of the [`UIDocument`](/documentation/UIKit/UIDocument) class. See [`Override input and output methods`](/documentation/UIKit/UIDocument#Override-input-and-output-methods) for a discussion of these requirements and methods.

#### Track changes

To enable the autosaving feature of [`UIDocument`](/documentation/UIKit/UIDocument), you must notify it when users make changes to a document. [`UIDocument`](/documentation/UIKit/UIDocument) periodically checks whether the [`hasUnsavedChanges`](/documentation/UIKit/UIDocument/hasUnsavedChanges) method returns <doc://com.apple.documentation/documentation/Swift/true>; if it does, it initiates the save operation for the document.

There are two primary ways to implement change tracking in your [`UIDocument`](/documentation/UIKit/UIDocument) subclass:

- Call the methods of the <doc://com.apple.documentation/documentation/Foundation/UndoManager> class to implement undo and redo for the document. You can access the default <doc://com.apple.documentation/documentation/Foundation/UndoManager> object from the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/undoManager`` property. This is the preferred approach, especially for existing apps that already support undo and redo.
- Call the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/updateChangeCount(_:)`` method at the appropriate junctures in your code.

#### Resolve conflicts and handle errors

A [`UIDocument`](/documentation/UIKit/UIDocument) object has a specific state at any moment in its life cycle. You can check the current state by querying the [`documentState`](/documentation/UIKit/UIDocument/documentState) property, and get notified about changes by observing the [`stateChangedNotification`](/documentation/UIKit/UIDocument/stateChangedNotification) notification.

If the owner enables a document for iCloud, it’s important to check for conflicting versions and to attempt to resolve conflicts. Listen for the [`stateChangedNotification`](/documentation/UIKit/UIDocument/stateChangedNotification) notification and then checking if the document state is [`inConflict`](/documentation/UIKit/UIDocument/State/inConflict). This state indicates that there are conflicting versions of the document, which you can access by calling the <doc://com.apple.documentation/documentation/Foundation/NSFileVersion> class method <doc://com.apple.documentation/documentation/Foundation/NSFileVersion/unresolvedConflictVersionsOfItem(at:)>, passing in the document’s file URL. If you can resolve a conflict correctly without user interaction, do so. Otherwise, discretely notify the user that a conflict exists and let them choose how to resolve it. Possible approaches include:

- Display the conflicting versions, from which a user can pick one or both versions to keep.
- Display a merged version and giving the user an option to pick it.
- Display the file modification dates and giving the user the option to choose one or both.

Document state, in addition to indicating an inter-file conflict, can indicate errors. For example, [`closed`](/documentation/UIKit/UIDocument/State/closed) indicates an error in reading, and [`savingError`](/documentation/UIKit/UIDocument/State/savingError) indicates an error in saving or reverting a document. The system notifies your app of reading and writing errors through the `success` parameter passed into the completion handlers of the [`open(completionHandler:)`](/documentation/UIKit/UIDocument/open(completionHandler:)), [`close(completionHandler:)`](/documentation/UIKit/UIDocument/close(completionHandler:)), [`revert(toContentsOf:completionHandler:)`](/documentation/UIKit/UIDocument/revert(toContentsOf:completionHandler:)), and [`save(to:for:completionHandler:)`](/documentation/UIKit/UIDocument/save(to:for:completionHandler:)) methods.

You can handle errors by calling or implementing the [`handleError(_:userInteractionPermitted:)`](/documentation/UIKit/UIDocument/handleError(_:userInteractionPermitted:)) method; the default implementations of the [`open(completionHandler:)`](/documentation/UIKit/UIDocument/open(completionHandler:)) and [`save(to:for:completionHandler:)`](/documentation/UIKit/UIDocument/save(to:for:completionHandler:)) methods call `handleError(_:userInteractionPermitted:)` when a [`UIDocument`](/documentation/UIKit/UIDocument) object encounters a reading or writing error, respectively. You can handle read, save, and reversion errors by informing the user and, if the situation permits, trying to recover from the error.

Be sure to read the description for the [`contents(forType:)`](/documentation/UIKit/UIDocument/contents(forType:)) method for its guidance on handling errors encountered during document saving.

#### Override input and output methods

If you app has special requirements for reading or writing document data, it can override methods of [`UIDocument`](/documentation/UIKit/UIDocument) other than [`load(fromContents:ofType:)`](/documentation/UIKit/UIDocument/load(fromContents:ofType:)) and [`contents(forType:)`](/documentation/UIKit/UIDocument/contents(forType:)). These requirements often include the following:

- Incremental reading and writing of large data files
  
  Override the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/read(from:)`` and ``doc://com.apple.uikit/documentation/UIKit/UIDocument/writeContents(_:to:for:originalContentsURL:)`` methods, respectively.
- Custom representations of document data (that is, not an <doc://com.apple.documentation/documentation/Foundation/NSData> or <doc://com.apple.documentation/documentation/Foundation/FileWrapper> object)
  
  Override the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/read(from:)`` method when reading document data and the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/writeContents(_:to:for:originalContentsURL:)`` method when writing document data.
- Performing actions before or after reading or writing data
  
  Override ``doc://com.apple.uikit/documentation/UIKit/UIDocument/open(completionHandler:)`` and ``doc://com.apple.uikit/documentation/UIKit/UIDocument/save(to:for:completionHandler:)``.
- A custom approach to safe-saving
  
  Override the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/writeContents(_:andAttributes:safelyTo:for:)`` method.
- Changing the file type of a document before it’s saved
  
  Override the ``doc://com.apple.uikit/documentation/UIKit/UIDocument/savingFileType`` method to return a file type other than the default (``doc://com.apple.uikit/documentation/UIKit/UIDocument/fileType``). An example of this is an RTF document which, after a user adds an image to it, should be saved as an RTFD document.

If you override these methods, be aware that all reading and writing of document data must be done on a background queue and must be coordinated with other attempts to read from and write to the same document file. Because of this, you usually call the superclass implementation (`super`) as part of your override, and if you call other `UIDocument` methods, you usually invoke them in the block passed into a call of the [`performAsynchronousFileAccess(_:)`](/documentation/UIKit/UIDocument/performAsynchronousFileAccess(_:)) method. Read the method descriptions for details.

#### Access document attributes

If you override any of the document-attribute properties (listed under [`Accessing document attributes`](/documentation/UIKit/UIDocument#Accessing-document-attributes)) by overriding the related accessor methods, be aware that the UIKit framework can call these accessor methods on a background thread. Thus your overriding implementation must be thread safe.

### Rename documents

`UIDocument` provides support for changing the document’s title. Security considerations require that clients can’t programmatically rename a file on the file system, and that the system confirms that a person intends to rename their file. To satisfy these restrictions, the system, instead of your app, presents a renaming user interface using a process outside your app. The external process renames the underlying file and reports the new location back to the client.

To support this external process, `UIDocument` conforms to [`UINavigationItemRenameDelegate`](/documentation/UIKit/UINavigationItemRenameDelegate-96g5t) and handles the rename request internally when a person invokes renaming from the title menu. If you’re using [`UIDocumentViewController`](/documentation/UIKit/UIDocumentViewController), it automatically configures renaming for you. Otherwise, you manually assign the document as the navigation item’s [`renameDelegate`](/documentation/UIKit/UINavigationItem/renameDelegate-o32h).

```swift
init(document: MyDocument) {
    self.document = document
    super.init(nibName:nil, bundle: nil)
    self.navigationItem.renameDelegate = document
}
```

The Rename action appears in the title menu as one of the system-suggested actions. When a person taps the Rename action, the system shows an inline text field for changing the navigation item’s `title`. Upon renaming the item, the system changes the file name in storage as though the person renamed the file in another application.

Prior to iOS 17, to enable the system rename user interface, a client view controller adopts the `UINavigationItemRenameDelegate` protocol and assigns itself as the navigation item’s `renameDelegate`. It’s the client’s responsibility to implement callbacks such as [`navigationItem(_:didEndRenamingWith:)`](/documentation/UIKit/UINavigationItemRenameDelegate-5j4ws/navigationItem(_:didEndRenamingWith:)) (Swift) or [`navigationItem:didEndRenamingWithTitle:`](/documentation/UIKit/UINavigationItemRenameDelegate-96g5t/navigationItem:didEndRenamingWithTitle:) (Objective-C) to explicitly move the file in storage.

```swift
class EditorViewController: UIViewController,
        UINavigationItemRenameDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.renameDelegate = self
    }

    func navigationItem(_ navigationItem: UINavigationItem, didEndRenamingWith: title: String) {
        // Move the file, update the model, and so on.
    }
}
```

## Topics

### Initializing a document object

[`init(fileURL:)`](/documentation/UIKit/UIDocument/init(fileURL:))

Returns a document object initialized with its file-system location.

### Accessing document attributes

[`fileURL`](/documentation/UIKit/UIDocument/fileURL)

The file URL you use to initialize the document.

[`localizedName`](/documentation/UIKit/UIDocument/localizedName)

The localized name of the document.

[`fileType`](/documentation/UIKit/UIDocument/fileType)

The file type of the document.

[`fileModificationDate`](/documentation/UIKit/UIDocument/fileModificationDate)

The date and time your app last modified the document file.

[`documentState`](/documentation/UIKit/UIDocument/documentState)

The current state of the document.

[`progress`](/documentation/UIKit/UIDocument/progress)

The upload or download progress of a document.

### Writing document data

[`close(completionHandler:)`](/documentation/UIKit/UIDocument/close(completionHandler:))

Asynchronously closes the document after saving any changes.

[`contents(forType:)`](/documentation/UIKit/UIDocument/contents(forType:))

Returns the document data to be saved.

[`save(to:for:completionHandler:)`](/documentation/UIKit/UIDocument/save(to:for:completionHandler:))

Saves document data to the specified location in the application sandbox.

[`writeContents(_:andAttributes:safelyTo:for:)`](/documentation/UIKit/UIDocument/writeContents(_:andAttributes:safelyTo:for:))

Ensures that document data is written safely to a specified location in the application sandbox.

[`writeContents(_:to:for:originalContentsURL:)`](/documentation/UIKit/UIDocument/writeContents(_:to:for:originalContentsURL:))

Writes the document data to disk at the sandbox location indicated by a file URL.

[`savingFileType`](/documentation/UIKit/UIDocument/savingFileType)

Returns the file type to use for saving a document.

[`fileAttributesToWrite(to:for:)`](/documentation/UIKit/UIDocument/fileAttributesToWrite(to:for:))

Returns a dictionary of file attributes to associate with the document file when writing or updating it.

[`fileNameExtension(forType:saveOperation:)`](/documentation/UIKit/UIDocument/fileNameExtension(forType:saveOperation:))

Returns a file extension to append to the file URL of the document file being written.

### Reading document data

[`open(completionHandler:)`](/documentation/UIKit/UIDocument/open(completionHandler:))

Opens a document asynchronously.

[`load(fromContents:ofType:)`](/documentation/UIKit/UIDocument/load(fromContents:ofType:))

Loads the document data into the app’s data model.

[`read(from:)`](/documentation/UIKit/UIDocument/read(from:))

Reads the document data in a file at a specified location in the application sandbox.

### Creating new documents

[`UIDocument.CreationIntent`](/documentation/UIKit/UIDocument/CreationIntent)

An app intent that creates new documents for your app.

### Accessing document files asynchronously

[`performAsynchronousFileAccess(_:)`](/documentation/UIKit/UIDocument/performAsynchronousFileAccess(_:))

Schedules a document-reading or document-writing operation on a concurrent background queue.

### Reverting a document

[`revert(toContentsOf:completionHandler:)`](/documentation/UIKit/UIDocument/revert(toContentsOf:completionHandler:))

Reverts a document to the most recent document data stored on-disk.

### Disabling and enabling editing

[`disableEditing()`](/documentation/UIKit/UIDocument/disableEditing())

Disables editing when it’s unsafe to make changes to a document.

[`enableEditing()`](/documentation/UIKit/UIDocument/enableEditing())

Enables editing when it’s safe again to make changes to a document.

### Tracking changes and autosaving

[`hasUnsavedChanges`](/documentation/UIKit/UIDocument/hasUnsavedChanges)

A Boolean value that indicates whether the document has any unsaved changes.

[`updateChangeCount(_:)`](/documentation/UIKit/UIDocument/updateChangeCount(_:))

Updates the change counter by indicating the kind of change.

[`undoManager`](/documentation/UIKit/UIDocument/undoManager)

The undo manager for the document.

[`changeCountToken(for:)`](/documentation/UIKit/UIDocument/changeCountToken(for:))

Returns a change token for a specific save operation.

[`updateChangeCount(withToken:for:)`](/documentation/UIKit/UIDocument/updateChangeCount(withToken:for:))

Updates the change count with reference to a change-count token passed in by UIKit.

[`autosave(completionHandler:)`](/documentation/UIKit/UIDocument/autosave(completionHandler:))

Initiates automatic saving of documents with unsaved changes.

### Supporting user activities

[`userActivity`](/documentation/UIKit/UIDocument/userActivity)

An object encapsulating a user activity supported by this document.

[`restoreUserActivityState(_:)`](/documentation/UIKit/UIDocument/restoreUserActivityState(_:))

Restores the state needed to continue the given user activity.

[`updateUserActivityState(_:)`](/documentation/UIKit/UIDocument/updateUserActivityState(_:))

Updates the state of the given user activity.

### Resolving conflicts and handling errors

[`handleError(_:userInteractionPermitted:)`](/documentation/UIKit/UIDocument/handleError(_:userInteractionPermitted:))

Handles an error that occurs during an attempt to read, save, or revert a document.

[`finishedHandlingError(_:recovered:)`](/documentation/UIKit/UIDocument/finishedHandlingError(_:recovered:))

Tells UIKit that you finished handling the error.

[`userInteractionNoLongerPermitted(forError:)`](/documentation/UIKit/UIDocument/userInteractionNoLongerPermitted(forError:))

Indicates when it’s no longer safe to proceed without immediately handling the error.

### Constants

[`UIDocument.ChangeKind`](/documentation/UIKit/UIDocument/ChangeKind)

Constants that specify the kind of change to a document.

[`UIDocument.SaveOperation`](/documentation/UIKit/UIDocument/SaveOperation)

Constants that specify the type of save operation.

[`UIDocument.State`](/documentation/UIKit/UIDocument/State)

Constants that specify the document state.

[`userActivityURLKey`](/documentation/UIKit/UIDocument/userActivityURLKey)

The key that identifies the document associated with a user activity.

### Notifications

[`stateChangedNotification`](/documentation/UIKit/UIDocument/stateChangedNotification)

A notification the document object posts when there’s a change in the state of the document.



---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)
