Some test text!

Pre-built Real Time Collaboration

Real Time Document Collaboration on iOS

PDFTron includes full support for pre-built real-time collaboration via GraphQL, making it easy to synchronize annotations and messages from multiple users on a central copy of a document

Please see the PreBuiltRealTimeCollaboration and PreBuiltRealTimeCollaborationObj-C sample apps which demonstrate the PDFTron iOS pre-built real-time collaboration:

1. Integrate

To get started with PDFTron's iOS Pre-built Real-time Collaboration, add the package to your project using Swift Package Manager:

Adding the package will also add its necessary dependencies:

  • PDFTron — the PDFTron SDK for iOS
  • Apollo for iOS — a GraphQL client for iOS which is used by the PDFTron collaboration package

Open your ViewController file. This is either the ViewController.swift or ViewController.m file in the left pane depending on your choice of language. Import the Tools library, as well as the PDFTronCollaboration framework.

#import "ViewController.h"

#import <Tools/Tools.h>
@import PDFTronCollaboration;

2. Setup the client and log in

  • CollabClient: This is the root level class that must be instantiated to enable realtime collaboration. The main purpose of this class is to log in a user. This class conforms to the PTCollaborationServerCommunication protocol.
  • User: A user class returned from the login methods on CollabClient. This class is used to create documents, fetch documents, etc.
  • Document - A class representing a single document. Instances of this class can be used to view a document, invite users, etc.
  • Annotation - A class representing a single annotation belonging to a Document. Instances of this class are used to fetch Mentions and track unread state.

The CollabClient class must be instantiated with an endpoint URL and a subscription URL of the server. This class can then be used to login a user. The login methods return a User object in their completion handlers, this object can then be used to interact with documents on the server.

@interface ViewController ()
@property (nonatomic) PTCollaborationDocumentController *documentController;
@property (nonatomic) CollabClient *client;

@implementation ViewController

- (void)viewDidLoad
    [super viewDidLoad];
    NSURL *subscriptionURL = [NSURL URLWithString:@"wss://"];
    NSURL *endpointURL = [NSURL URLWithString:@""];
    NSString *documentID = @""; // Leave blank to generate a new document
    self.client = [[CollabClient alloc] initWithEndpointURL:endpointURL subscriptionURL:subscriptionURL];
    // Login User
    [self.client loginAnonymouslyWithUsername:@"Guest" completionHandler:^(User * _Nullable user) {
        if (user == nil){
            // User not found
        // Get the document if it exists
        [user getDocumentWithDocumentID:documentID completionHandler:^(Document * _Nullable document) {
            if (document == nil) {
                [user createDocumentWithDocumentID:documentID documentName:@"NewDocument" isPublic:YES annotations:@[] completionHandler:^(Document * _Nullable document) {
                    if (document == nil) {
                    // View the document — this step is to connect the user to the document for real-time annotation syncing
                    [document view];
            // Add the user to the document if the document exists
            [document joinWithCompletion:^(BOOL joined) {
                // View the document — this step is to connect the user to the document for real-time annotation syncing
                [document view];

3. Display the Document in a Viewer

Show the document in a PTCollaborationDocumentController initialized with the CollabClient instance:

- (void)viewDidAppear:(BOOL)animated
    [super viewDidAppear:animated];
    [self showViewer];

    self.documentController = [[PTCollaborationDocumentController alloc] initWithCollaborationService:self.collabClient];
    // The PTDocumentController must be in a navigation controller before a document can be opened
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.documentController];
    navigationController.modalPresentationStyle = UIModalPresentationFullScreen;
    navigationController.navigationBar.translucent = NO;
    navigationController.toolbar.translucent = NO;
    // Open a file from URL.
    NSURL *fileURL = [[NSURL alloc] initWithString:@""];
    [self.documentController openDocumentWithURL:fileURL];
    // Show navigation (and document) controller.
    [self presentViewController:navigationController animated:YES completion:nil];

4. Add a Share Button to the Viewer (Optional)

This code snippet demonstrates how to add a share button to the viewer to copy the document ID or join the session from WebViewer Showcase.

    [] // The rest of this function from step 3.

    NSMutableArray<UIBarButtonItem*>* leftBarItems = [self.documentController.navigationItem.leftBarButtonItems mutableCopy];
    if(leftBarItems == nil) {
        // Initialize the array if it's nil
        leftBarItems = [NSMutableArray array];
    UIBarButtonItem *shareButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(shareDocument)];
    [leftBarItems addObject:shareButton];
    self.documentController.navigationItem.leftBarButtonItems = [leftBarItems copy];

    // Present the viewer at the end
    [self presentViewController:navigationController animated:YES completion:nil];

    NSString *documentID = self.documentController.service.documentID;

    UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Share Link" message:nil preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *copyAction = [UIAlertAction actionWithTitle:@"Copy DocumentID to Clipboard" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [UIPasteboard.generalPasteboard setString:documentID];

    UIAlertAction *webViewerAction = [UIAlertAction actionWithTitle:@"Open in WebViewer Showcase" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSURL *URL = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"", documentID]];
        [UIApplication.sharedApplication openURL:URL options:[NSDictionary dictionary] completionHandler:nil];

    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
    [alertVC addAction:copyAction];
    [alertVC addAction:webViewerAction];
    [alertVC addAction:cancelAction];
    [self.documentController presentViewController:alertVC animated:YES completion:nil];

Get the answers you need: Support

Upcoming Webinar: How Developers Add Office Viewing Without Downloading | June 9th at 11 am PT


The Platform


© 2022 PDFTron Systems Inc. All rights reserved.


Terms of Use