Import and Export Annotations from a Database in iOS

PSPDFKit enables you to serialize and save annotation changes in external files and save those files in a database. You can later import annotations from the database when you open the document again to restore the changes. The benefit of this approach is that you don’t need to transfer the whole modified document over the network to save it in your database. Rather, you only send the annotations, which saves bandwidth.

You can import and export annotations from a database using the Instant JSON or XFDF formats. The benefit of using Instant JSON over the XFDF format is that Instant JSON represents the changes made to annotations, whereas XFDF is a complete snapshot of all the annotations in a document. For documents that originally contained a lot of annotations, Instant JSON might greatly reduce the required bandwidth.

Exporting Annotations to a Database

If you’re using the Instant Document JSON format, you don’t need to save the document before exporting the payload. That’s because the Instant Document JSON format is a serializable representation of the current changes to a document, i.e. a diff between the Document’s saved and unsaved changes. However, if you’re using the Instant Annotation JSON or XFDF formats, you need to save the document before exporting the payload. Here’s how you can save your Document:

let document = ...
try? document.save()

Then, you need to serialize the annotations and save them to an external file or your database. The examples below show how to export annotations to external files:

Using Instant Document JSON

let data = try! document.generateInstantJSON(from: documentProvider)

// Optionally convert the data to a JSON `String`.
let jsonString = String(data: data, encoding: .utf8)!

// Write the JSON file.
try! jsonString.write(to: externalAnnotationsFile, atomically: false, encoding: .utf8)

Using XFDF

// Collect all existing annotations from the document.
let annotations = document.allAnnotations(of: .all).values.flatMap { $0 }

// Write the file.
let dataSink = try! FileDataSink(fileURL: externalAnnotationsFile)
try! XFDFWriter().write(annotations, to: dataSink, documentProvider: document.documentProviders.first!)

Importing Annotations from a Database

You’ll need to instantiate your Document before you can import annotations from a database or external file to a document. The examples below show how to import annotations from external files.

Using Instant Document JSON

// Load the document.
let document = ...

// Load Instant JSON data from an external JSON file.
let loadedInstantJSONString = try! String(contentsOf: externalAnnotationsFile)

// Convert the JSON string payload to data.
let loadedInstantJSONData = loadedInstantJSONString.data(using: .utf8)

// Create the data container provider using the loaded Instant JSON data payload.
let jsonContainer = DataContainerProvider(data:loadedInstantJSONData!)

// Apply the Instant JSON payload to import the annotations.
try! document.applyInstantJSON(fromDataProvider: jsonContainer, to: document.documentProviders[0], lenient: false)

Using XFDF

// Load the document.
let document = ...

// The XFDF file can be loaded from an external file or from the database.
let externalAnnotationsFile = ...

let documentProvider = (document.documentProviders.first)!
let dataProvider = FileDataProvider(fileURL: externalAnnotationsFile)

// Create the XFDF parser and parse all annotations.
let parser = XFDFParser(dataProvider: dataProvider, documentProvider: documentProvider)
let annotations = try! parser.parse()

// Add the parsed annotations to the document.
document.add(annotations: annotations)