Usage


API Overview

The entry class into Instant is PSPDFInstantClient: this represents a connection to your PSPDFKit Server. An app would typically create one PSPDFInstantClient, although could create several to connect to several different PSPDFKit Server instances.

Instant manages downloading and storing the PDF files when your app requests this. The API to each document managed by Instant is PSPDFInstantDocumentDescriptor. A document descriptor may be used to request downloading the associated PDF file, and once that has finished a PSPDFDocument may be created. Set this document on a PSPDFInstantViewController then show it to the user and changes to annotations will be synchronized with all users viewing the same document.

PSPDFInstantViewController is a subclass of PSPDFViewController and may be used to show any PSPDFDocument, not only ones created by Instant, although there will be no annotation synchronization in that case. This means it is possible to create a PSPDFTabbedViewController whose internal pdfController is a PSPDFInstantViewController and mixing documents managed by Instant with other documents will work. Showing a PSPDFDocument created by Instant in any PSPDFViewController except a PSPDFInstantViewController is not supported.

Document Lifecycle

When using a document managed by Instant, you might go through these typical stages:

  • Obtain a document identifier from your server
  • Obtain a document descriptor
  • Download the document
  • Show the document and synchronize annotations
  • Update the authentication token to keep synchronizing annotations
  • Lose access to the document
  • Clear local storage

Usage in Detail

After signing in to your server and finding out the identifier of the document you want to show to the user for it, obtain a document descriptor from Instant:

Copy
1
2
3
4
5
6
7
8
9
let instantClient = PSPDFInstantClient(serverURL: URL(string: "location of your PSPDFKit Server here")!)
let documentIdentifier = "some document identifier from your server"

do {
    let documentDescriptor = try instantClient.documentDescriptor(withIdentifier: documentIdentifier)
} catch {
    print("This document identifier is invalid: \(error)")
    return
}
Copy
1
2
3
4
5
6
7
8
9
PSPDFInstantClient *client = [[PSPDFInstantClient alloc] initWithServerURL:[NSURL URLWithString:@"location of your PSPDFKit Server here"]];
NSString *documentIdentifier = @"some document identifier from your server";

NSError *error;
id<PSPDFInstantDocumentDescriptor> documentDescriptor = [client documentDescriptorWithIdentifier:documentIdentifier error:&error];
if (documentDescriptor == nil) {
    NSLog(@"This document identifier is invalid: %@", error);
    return;
}

Check if the document has been downloaded:

Copy
1
2
3
4
5
6
7
8
let documentDescriptor: PSPDFInstantDocumentDescriptor = ...
if documentDescriptor.isDownloaded {
    if let pdfDocument = documentDescriptor.editableDocument {
         // We now have a PSPDFDocument
    }
} else {
    // The document has not been downloaded yet.
}
Copy
1
2
3
4
5
6
7
8
PSPDFInstantDocumentDescriptor *documentDescriptor = ...
if (documentDescriptor.isDownloaded) {
    PSPDFDocument *pdfDocument = documentDescriptor.editableDocument;
    // We now have a PSPDFDocument

} else {
    // The document has not been downloaded yet.
}

If the document has not been downloaded, obtain a JSON Web Token (JWT) for this document from your server then use this to start the download:

Copy
1
2
3
4
5
6
let JWT = "token from your server"
do {
    try documentDescriptor.downloadDocument(usingAuthenticationToken: JWT)
} catch {
    print("Could not start downloading document with identifier \(documentDescriptor.identifier): \(error)")
}
Copy
1
2
3
4
5
6
NSString *JWT = @"token from your server";

NSError *error;
if (![documentDescriptor downloadDocumentUsingAuthenticationToken:JWT error:&error]) {
    NSLog(@"Could not start downloading document with identifier %@: %@", documentDescriptor.identifier, error);
}

Once a download finishes, the Instant client’s delegate will notified by a call to instantClient:didFinishDownloadForDocument: and PSPDFInstantDidFinishDownloadNotification will be posted with the document descriptor as the object. A PSPDFDocument can be obtained by calling editableDocument on the document descriptor.

Showing a document and synchronizing annotations:

Simply create a PSPDFInstantViewController, set its document to a PSPDFDocument created by Instant, and show the view controller to the user. That’s all.

Copy
1
2
3
4
5
let document: PSPDFDocument = ...
let pdfViewController = PSPDFInstantViewController(document: document)
self.navigationController?.pushViewController(pdfViewController, animated: true)
// or
self.present(pdfViewController, animated: true)
Copy
1
2
3
4
5
PSPDFDocument *document = ...
PSPDFInstantViewController *pdfViewController = [[PSPDFInstantViewController alloc] initWithDocument:document];
[self.navigationController pushViewController:pdfViewController animated:YES];
// or
[self presentViewController:pdfViewController animated:YES completion:NULL];

Instant does not persist authentication tokens, and the tokens have an expiry date. When a new token is needed for a document, the instantClient:didFailAuthenticationForDocument: delegate method will be called and PSPDFInstantDidFailAuthenticationNotification will be posted with PSPDFInstantDocumentDescriptor as the object. This will always be called the first time syncing a document after app launch because tokens are not persisted.

When your app receives this callback, it should request a new token from your server then pass this token to Instant to keep synchronizing annotations:

Copy
1
2
3
let documentDescriptor: PSPDFInstantDocumentDescriptor = ...
let JWT = "token from your server"
documentDescriptor.updateAuthenticationToken(JWT)
Copy
1
2
3
PSPDFInstantDocumentDescriptor *documentDescriptor = ...
NSString *JWT = "token from your server";
[documentDescriptor updateAuthenticationToken:JWT];

You app might find out that user no longer has access to a document from your server, or from the PSPDFKit Server.

If your app finds the user has lost access to the document then you probably want to stop showing the document and clear the local storage:

Copy
1
2
3
4
5
6
let documentDescriptor: PSPDFInstantDocumentDescriptor = ...
do {
    try documentDescriptor.removeLocalStorage()
} catch {
    // Errors are unlikely, but it is possible the delete from the file system fails.
}
Copy
1
2
3
4
5
6
PSPDFInstantDocumentDescriptor *documentDescriptor = ...

NSError *error;
if (![documentDescriptor removeLocalStorageWithError:&error]) {
    // Errors are unlikely, but it is possible the delete from the file system fails.
}
Was this page helpful? We're happy to answer any questions.