Instant JSON

Instant JSON is our approach to bring annotations into a sane format while keeping all important properties to make it work with PDF. It is fully documented and supports long-term storage. The PSPDFJSONSerialization protocol has been deprecated in favor of the new API.

Instant JSON stores PDF changes such as annotations into a separate JSON file. This means that a PDF document will only need to be transferred once and all changes are added as an overlay to the existing PDF. This approach significantly reduces the bandwidth since you only need to transfer this JSON instead of the complete PDF.

Conceptually, Instant JSON defines a list of skippedPdfObjectIds. These point to the PDF's internal object IDs for annotations. Whenever an object ID is marked as skipped, it will no longer be loaded from the original PDF. Instead, it could be defined inside the annotations array with the same pdfObjectId. If this is the case, the PDF viewer will display the new annotation, which signalizes an update to the original one. If an object ID is marked as skipped, but the annotations array does not contain an annotation with the same pdfObjectId, it will be interpreted as a deleted annotation. An annotation that is inside the annotations array without the pdfObjectId property is interpreted as a newly created annotation.

All annotations in the annotations array have an unique id field. For updated annotations which already where in the original PDF, this field will be the stringified pdfObjectId. Newly created annotations will get a newly generated ULID.

An "empty" Instant JSON contains no skippedPdfObjectIds, and annotations which means that the original PDF is untouched. All annotations in the initial PDF are still shown.

The format

We use Flow Type Declarations to specify the format of Instant JSON.

Copy
1
2
3
4
5
6
7
8
9
10
declare type InstantJSON = {
  format: 'https://pspdfkit.com/instant-json/v1',
  pdfId?: {
    permanent: string,
    changing: string,
  },
  skippedPdfObjectIds?: number[],
  annotations?: Object[],
  formFieldValues?: Object[],
}
  • format

    This is a literal string that includes the version information.

  • pdfId

    This optional key contains an object of a permanent and a changing PDF ID. According to the PDF spec, a PDF document must contain those IDs. We use the permanent ID to verify that the PDF you've opened together with this Instant JSON is indeed the right one. The changing PDF ID will be updated whenever the PDF file is updated (for example saved with different annotations). Since Instant JSON only works with an immutable PDF. The state would be invalid when used with a changed PDF.

    Not very PDF might have a valid permanent or changing ID, and thus this field might not be set. We recommend you take care of always using the same PDF.

  • skippedPdfObjectIds

    An array of PDF object IDs that will be ignored when importing annotations from the original PDF document. If this array is empty, the key should not be set.

  • annotations

    A list of new or updated annotations. Annotations follow the Instant Annotation JSON format. When an annotation contains a pdfObjectId, it is considered to be an update to one of the annotations of the original PDF. For newly created annotation, this key will not be set.

  • formFieldValues

    A list of modified form field values. Objects follow the Instant Form Field Value JSON format. This list will not be preset, when no form field values were modified.

Instant Annotation JSON API

Annotation JSON is Instant's representation of a single annotation. This can be generated by using the methods available in PSPDFAnnotation. For generation, use -[PSPDFAnnotation generateInstantJSONWithError:], and for creating an annotation from the JSON, use -[PSPDFAnnotation annotationFromInstantJSON:documentProvider:error:].

If you have JSON generated by PSPDFJSONAdapter, convert it to Instant JSON via the following steps:

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
NSDictionary *jsonDictionary = ...; // Deserialized JSON data in the old JSON format generated by PSPDFJSONAdapter.
NSError *annotationCreationError;
PSPDFAnnotation *annotation = [PSPDFAnnotation annotationFromJSONDictionary:jsonDictionary documentProvider:<#document provider from document> error:&annotationCreationError];
if (!annotation || annotationCreationError) {
    // Handle failure to create annotation from JSON.
} else {
    NSError *instantJSONGenerationError;
    NSData *instantJSONData = [annotation generateInstantJSONWithError:&instantJSONGenerationError];
    if (!instantJSON || instantJSONGenerationError) {
        // handle error
    } else {
        // instantJSONData now contains the JSON for the annotation in the Instant format.
    }
}

There are some limitations with Instant JSON in that not all annotation types are currently supported, and only the properties that can be handled correctly across all of PSPDFKit's supported platforms (iOS, Android, and is) are serialized. For more information, check out the detailed Instant Annotation JSON format specification.

Instant Document JSON API

Document JSON is a serializable representation of the current changes to a document: a diff between the PSPDFDocument's saved and unsaved changes. This can be used to transfer a set of changes across devices without having to send the entire PDF, which could potentially be very large. PSPDFKit for Web uses this in standalone deployment to reduce bandwidth usage. Currently the generated JSON only contains changes to annotations.

To generate Instant Document JSON, simply call -[PSPDFDocument generateInstantJSONFromDocumentProvider:error:] on the document from which you wish to retrieve currently unsaved changes in JSON form. Note that this method will return nil if there are no unsaved changes in the document.

This generated JSON can then be applied to a document using -[PSPDFDocument applyInstantJSONFromDataProvider:toDocumentProvider:error:]. If you have an NSData object containing the Document JSON data, create a PSPDFDataContainerProvider and pass that as the dataProvider argument to the method.