PSPDFInstantDocumentDescriptor

@protocol PSPDFInstantDocumentDescriptor <NSObject>

A PSPDFInstantDocumentDescriptor represents an editing context for annotations on a PDF file managed by Instant.

The document descriptor allows you to download the file and synchronize the annotations in this context, while display and editing of the annotations happens via the specialized PSPDFDocument objects that it provides. You obtain instances that conform to this protocol from a PSPDFInstantClient, which also keeps the instances it creates alive.

Instant manages the PDF files on disk efficiently, and will reuse the same file for all document descriptors with the same identifier. Therefore, there are some limitations to what you can do with the PSPDFDocument instances you obtain from a document descriptor. For details, see the documentation of editableDocument.

Notifications

A document descriptor posts the following notifications to inform you of relevant events:

Each of these notifications will typically be posted on a background thread, and have the document descriptor as their object property. For a centralized, more type-safe alternative see PSPDFInstantClientDelegate, and for more details on the sync cycle, refer to the documentation of PSPDFInstantDocumentState.

  • Uniquely identifies the PDF file backing this editing context.

    There can be multiple document descriptors that share the same PDF file and therefore the same identifier. To uniquely identify a document descriptor, you have to take the layerName into account as well.

    Declaration

    Objective-C

    @property (readonly, nonatomic) NSString *_Nonnull identifier;

    Swift

    var identifier: String { get }
  • Name of the layer that specifies the annotations to use for this editing context.

    The name of the default layer is an empty string.

    Declaration

    Objective-C

    @property (readonly, nonatomic) NSString *_Nonnull layerName;

    Swift

    var layerName: String { get }
  • Value encoded in the JWT used to authenticate the receiver.

    This property will be nil when you JWTs do not contain the user_id claim. It may also be nil, IFF you have downloaded the data with a version of Instant prior to the one bundled with PSPDFKit 7.6, obtained this object from the deprecated -[PSPDFInstantClient documentDescriptorWithIdentifier:error:] method, and have not updated its JWT yet.

    Declaration

    Objective-C

    @property (readonly, nonatomic, nullable) NSString *userID;

    Swift

    var userID: String? { get }
  • A Boolean value indicating whether the PDF file for this document descriptor has been downloaded from the server.

    Declaration

    Objective-C

    @property (readonly, getter=isDownloaded, nonatomic) BOOL downloaded;

    Swift

    var isDownloaded: Bool { get }
  • The current state of the document descriptor.

    Warning

    This property is not observable through KVO! Please listen to the notifications listed in this header or use PSPDFInstantClientDelegate instead.

    Declaration

    Objective-C

    @property (readonly, nonatomic) PSPDFInstantDocumentState documentState;

    Swift

    var documentState: PSPDFInstantDocumentState { get }
  • Starts asynchronously downloading the PDF file and annotation data from PSPDFKit Server.

    When the download completes successfully, the PSPDFInstantDidFinishDownloadNotification will be posted. If it fails, PSPDFInstantDidFailDownloadNotification will be posted, containing the error in its user info dictionary.

    Should the PDF file and annotation data already be available locally, no download will be attempted. Instead this method with fail with PSPDFInstantErrorAlreadyDownloaded. If a download is already in progress but has not finished yet, this method will succeed without starting a duplicate download.

    This method will fail with PSPDFInstantErrorInvalidJWT if the value you passed cannot be decoded, or the decoded data relates to another layer. It will fail with PSPDFInstantErrorUserIDMismatch if the decoded user ID is incompatible with the receiver’s value.

    Declaration

    Objective-C

    - (BOOL)downloadUsingJWT:(nonnull NSString *)JWT
                       error:(NSError *_Nullable *_Nullable)error;

    Swift

    func download(usingJWT JWT: String) throws

    Parameters

    JWT

    A JWT that grants access to the layer represented by the receiver. This must be supplied by your own server.

  • The progress of the PDF and annotation download — may be used to cancel an in-progress download.

    This will be nil if when the PDF file and annotation have been downloaded. It will exist before a download starts with a fractionComplete of zero.

    @not Important: The progress object should be considered read-only! Do not modify the totalUnitCount, completedUnitCount, cancellationHandler or other properties, and do not add any child progress objects.

    Declaration

    Objective-C

    @property (readonly, nonatomic, nullable) NSProgress *downloadProgress;

    Swift

    var downloadProgress: Progress? { get }
  • Returns a PDF document, in which annotations may be edited.

    This returns an object even before the PDF and annotation data have been downloaded, so it can be set on a PSPDFInstantViewController immediately, which then shows the download progress. To start a download, use -downloadUsingJWT:error:.

    Some features of PSPDFDocument are not supported in documents managed by Instant:

    • Archiving with NSCoding: instead archive the JWT for the document descriptor’s identifier and layerName, and recreate the document by calling this method again.
    • Undo
    • Bookmarks
    • The document editor
    • Saving: only annotations may be modified, which are persisted automatically by Instant.

    There can only be a single editable document for a document descriptor at any time! Therefore, this method may return the same instance on repeated calls. If you need to display more than one instance of the same document at a time, for example when you want mirroring on an external screen, create secondary read-only instances using -readOnlyDocument.

    Objects returned by this method become invalid if the download fails, is cancelled, or when removing local storage for the document. In these cases the document instance may no longer be used. Since there can only be one editable document, you must release all references to the invalid document so it deallocates, then request a new one from this method.

    Warning

    Instant uses a special annotation provider for its documents! As a result the annotation manager of this document will not have a fileAnnotationProvider.

    Declaration

    Objective-C

    @property (readonly, nonatomic) PSPDFDocument *_Nonnull editableDocument;

    Swift

    var editableDocument: PSPDFDocument { get }
  • Returns a read-only PDF document for this editing context.

    There can only be a single editable Instant-enabled PSPDFDocument for a document descriptor at a time. But since one PSPDFDocument should only be used by one PSPDFViewController, there will be times — like mirroring on an external display — where you need more than just one. For these situations, you can get an arbitrary number of documents that are read-only:
    When changes are made, these are updated as appropriate, but they will not allow you to make any edits — like adding, changing, or removing existing annotations.

    Otherwise this behaves the same as editableDocument.

    Warning

    Instant uses a special annotation provider for its documents! As a result the annotation manager of this document will not have a fileAnnotationProvider.

    Declaration

    Objective-C

    - (nonnull PSPDFDocument *)readOnlyDocument;

    Swift

    func readOnlyDocument() -> PSPDFDocument
  • Removes the annotation store from disk.

    Calling this method will also cancel any in-progress network operations for this document descriptor. Removing the annotation store may fail if the file-system operations fail.

    Warning

    This method must be called before authenticating the document descriptor as a different user. Providing an authentication token for a different user without calling this method first may raise an exception.

    Declaration

    Objective-C

    - (BOOL)removeLocalStorageWithError:(NSError *_Nullable *_Nullable)error;

    Swift

    func removeLocalStorage() throws
  • Attempts to reauthenticate the receiver using the given JWT.

    Instant does not permanently store authentication information but it does cache it in memory. As a result, you will rarely have to call this method repeatedly on the same object during the a single run of your app. In particular, a freshly downloaded document descriptor is already authenticated — as downloading requires authentication.

    As a general rule, it is only necessary to call this method after -[PSPDFInstantClientDelegate instantClient:documentDidFailAuthentication:] has been called:
    This will happen as soon as a sync operation fails due to an authentication error.

    You can, however, pro-actively call this method for every local document descriptor when your app starts. This may be useful to limit the number of requests that have to be made if, for example, you have stored the JWTs for your layers in the keychain, or your server backend provides an endpoint returning the JWTs for all of the layers a user may access in a single call.

    Declaration

    Objective-C

    - (void)reauthenticateWithJWT:(nonnull NSString *)JWT;

    Swift

    func reauthenticate(withJWT JWT: String)
  • Returns the unique identifier for the given annotation of one of the receiver’s documents.

    You can use this method to — for example — associate data from arbitrary sources with annotations managed by Instant. Annotations created interactively by the user working on the editableDocument in a PSPDFViewController always have an identifier. If, however, you create a new annotation programmatically, the identifier will be available as soon as you add the annotation to the receiver’s editableDocument.
    Identifiers returned from this method are guaranteed to be stable over time, and unique in the context of the document descriptor they belong to. Although they are typed as strings for interoperability, you should treat them as opaque objects. Due to deliberate design considerations on our part, they are URL-, XML-, and filesystem-safe.

    This method will fail if the annotation does not belong to any of the receiver’s documents. It may also fail if the receiver is no longer valid.

    Declaration

    Objective-C

    - (nullable NSString *)
    identifierForAnnotation:(nonnull PSPDFAnnotation *)annotation
                      error:(NSError *_Nullable *_Nullable)error;

    Swift

    func identifier(for annotation: PSPDFAnnotation) throws -> String

    Parameters

    annotation

    The annotation to identify.

  • Returns the annotation for the given identifer and document — if any.

    This method allows you to use values once returned from -identifierForAnnotation:error: for looking up annotations in a document managed by the receiver. As useful annotations are always related to a document, you have to specify which document that the annotation — if found — should belong to.
    As such, calling this method will fail if the document you passed is not managed by the receiver, or if there is no annotation with the specified identifier. It will also fail if the document has not been dowloaded yet.

    Declaration

    Objective-C

    - (nullable PSPDFAnnotation *)
    annotationWithIdentifier:(nonnull NSString *)identifier
                 forDocument:(nonnull PSPDFDocument *)document
                       error:(NSError *_Nullable *_Nullable)error;

    Swift

    func annotation(withIdentifier identifier: String, for document: PSPDFDocument) throws -> PSPDFAnnotation

    Parameters

    identifier

    The unique identifier of the annotation to return.

    document

    The document to which the returned annotation — if any — belongs.

  • Syncs annotations with the PSPDFKit Server.

    When the PDF file and annotation data have been downloaded, this method initiates a one-time sync cycle:
    Sync requests will be made until all local changes have been synced, until an error occurs, or until you call -stopSyncing:. If you are using PSPDFInstantViewController in its default configuration to display the document, there is no need to call this method. Instant will push edits to the server as they happen and will listen for changes from the server.

    This method allows you to sync a document descriptor that is not being displayed or for whose document(s) you have disabled automatic syncing. Automatic syncing is controlled by PSPDFInstantViewController.shouldListenForServerChangesWhenVisible and delayForSyncingLocalChanges.

    Note

    This method does nothing if the PDF file or annotations have not been downloaded yet.

    Declaration

    Objective-C

    - (void)sync;

    Swift

    func sync()
  • Stops the current sync cycle, optionally cancelling the current request.

    Calling this method is only necessary if you choose to sync manually. That is:

    If your answer to all of the above is yes, you may call this method to stop the current sync cycle. Passing NO will allow the current request to complete. This gives you the latest server state, but you may still have local changes that have not been synced.
    Passing YES will cancel the current request immediately. Your view of the server’s state will most likely be outdated and if you had local changes, the server has probably not seen them yet.

    Declaration

    Objective-C

    - (void)stopSyncing:(BOOL)cancelCurrentRequest;

    Swift

    func stopSyncing(_ cancelCurrentRequest: Bool)

    Parameters

    cancelCurrentRequest

    Whether the current request should be cancelled — even if it is receiving data.

  • Delay in seconds before kicking off automatic sync after local changes are made to the editableDocument’s annotations.

    If this is a positive value, Instant will automatically sync annotations with the PSPDFKit Server after annotations in the document are modified. Setting this to a higher value will reduce the load on the network and reduce energy use but means other users will not see annotation updates as soon, which also increases the chance of sync conflicts. Setting this to a positive value less than 1 second may strain the network and battery and is not recommended.

    Set this to PSPDFInstantSyncingLocalChangesDisabled to disable automatic syncing, in which case annotations must be synchronized manually by calling sync.

    Setting this to zero will not result in immediate syncing and is not supported. Attempting to sync immediately after every change would stress the network and be unlikely to result in faster syncing.

    Defaults to 1 second.

    Declaration

    Objective-C

    @property (assign, readwrite, atomic) NSTimeInterval delayForSyncingLocalChanges;

    Swift

    var delayForSyncingLocalChanges: TimeInterval { get set }
  • Tells the receiver to start listening for changes from the server as they happen.

    Once a document descriptor’s data has been downloaded, you can use this method to begin observing the server for changes. The most common use case for this is that you are displaying the document in your custom PDF view controller, and you want to make sure that the user sees changes made on other devices in a real-time-like fashion. When you call this method, Instant will begin monitoring the server for changes until syncing fails, or until you call -stopListeningForServerChanges — whichever happens first.

    A word of warning:
    Using the network, especially the cellular network, is one of the most energy intensive tasks. While we do our best to minimize the energy impact this feature has, if your app does not require (near-)real-time sync, consider using explicit user actions to call sync instead.

    Note

    If you use PSPDFInstantViewController you get this behavior for free! This method is provided if you cannot customize that class to suit your needs, but need real-time-like updates.

    Declaration

    Objective-C

    - (void)startListeningForServerChanges;

    Swift

    func startListeningForServerChanges()
  • Tells the receiver to stop listening for changes from the server.

    Once you are no longer interested in real-time updates from the server, use this method to stop listening for changes. A common scenario where you would want to call this, is when you stop displaying an Instant enabled document in your custom PDF view controller.

    Note

    If you use PSPDFInstantViewController you get this behavior for free! This method is provided if you cannot customize that class to suit your needs, but need real-time updates.

    Declaration

    Objective-C

    - (void)stopListeningForServerChanges;

    Swift

    func stopListeningForServerChanges()
  • Deprecated

    Undocumented

    Declaration

    Objective-C

    - (void)updateAuthenticationToken:(NSString *)authenticationToken PSPDF_DEPRECATED_IOS(7.6, "Please use reauthenticateWithJWT: instead.");

    Swift

    func updateAuthenticationToken(_ authenticationToken: String)
  • Deprecated

    Undocumented

    Declaration

    Objective-C

    - (BOOL)downloadDocumentUsingAuthenticationToken:(NSString *)authenticationToken error:(NSError **)error PSPDF_DEPRECATED_IOS(7.6, "Please migrate to downloadUsingJWT:error:");

    Swift

    func downloadDocument(usingAuthenticationToken authenticationToken: String) throws