Kevin Ferrell

National Archives

A Simple Solution for Archiving iPad PDF Annotations

I’m currently working on an enterprise iPad app that delivers information (briefings, reports, etc.) to users in PDF format. Our team is hoping to move towards a more flexible delivery format in the future but that’s a topic for another post!

In order to display the PDF files we’re using the excellent PSPDFKit library developed by Peter Steinberg. The library has a huge feature set and enables users to make annotations directly on PDF files in an Adobe compliant format. Annotation support was a frequently requested feature from a previous app that our team developed so we’re anticipating a lot of use of this feature. However, because this app is being developed for use in a government agency, we had to track all annotations made by our users in order to comply with the National Archives and Records Act (NARA). Any annotations or notes made by our users must be sent to our agency’s archival system in order to store them for future reference.

The easy way out would have been to store the modified PDF files on each user’s iPad, and then send the entire file back to the server where they could then be sent to the archives. The problem with this approach is that we’d be sending the entire PDF file back to the server when we really only needed a small piece of annotation data. This would have ate away at our data plans and while it wouldn’t have affected the user experience it would have been inefficient.

In order to solve this problem, we stored the annotation data separately from the main PDF file within a SQLite DB. Then during our data sync process we send only the annotation data back to the server where it is appended to a copy of the full PDF file and sent to an archival system.

You can capture the annotation data by sub-classing the PSPDFDocument object and then modifying the didAppendData; method:


-(void) documentProvider:(PSPDFDocumentProvider *)documentProvider didAppendData:(NSData *)data
{

// Save the annotation data to a local database for later syncing
[self.myCustomDocumentClass saveFileAnnotationData:data];

// Debugging output

//NSLog(@"Annotation Trailer Attached: %@",[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);

}

This method will get called each time the user makes an annotation. In our app we save the NSData sequentially into a SQLite DB and then send them to the server. You can display the annotations to the user the next time the PDF document is loaded by appending the annotation data to the end of the PDF file like so:

// Create a NSMutableData object that contains the file content for the core PDF
NSMutableData *combinedFile = [[NSMutableData alloc] initWithData:fileContent];

// Loop over annotations for the file and append them
// (Note: I'm using the FMDB library here)
FMResultSet *annotations = [appDB executeQuery:@"SELECT CONTENT FROM DOCUMENTFILEANNOTATION WHERE DOCUMENTFILEID = ? ORDER BY LASTMODDATE",self.documentFileID];
while ([annotations next]) {
    [combinedFile appendData:[annotations dataForColumnIndex:0]];
}

This is a simple solution for handling document annotations that efficiently manages data and meets NARA compliance requirements. Mobile apps are new to most government agencies and as a mobile developer I often encounter hurdles and challenges that are unique to the government. Some of the people I encounter are resistant to change but I usually find that if you take the time to work with them and understand the root of the requirement you can often find a workable solution.

Discussion Closed

New comments are not allowed on this post.