Reputation: 11598
I'm writing an app that manages documents for a user and (eventually) posts PDF files served out through a web service on the iPhone/iPad. These are almost exclusively scanned PDF files, and they appear to REALLLLLY bog down the iOS device.
The first solution I came up with was to simply host the PDF in a UIWebView. This works really, really well for "generated" PDF files, but NOT for scanned PDF files (I'm guessing the difference here is raster vs. vector?).
My next solution was to implement a UIDocumentInteractionController, which was said to increase snappiness. I can report that it does, indeed, seem to be faster than UIWebView, but it's still unacceptably slow, even on smallish, 2 page PDF files. (On a side note, the "auto-open-in-another-app" feature, along with built-in printing is super slick!)
I've read a post or 2 about the QuickLook framework, and I plan to look into that, but I've also stumbled across a few posts talking about CGPDFDocument classes and such. Those seem to have a finer control over document navigation (a la xPdf), but I have no idea where to start with that. Plus, I'm not even sure if it offers a performance benefit for what I'm doing.
So, first question: what's the fastest way to render scanned PDF files on the iPhone/iPad?
Second question: The scanned PDF files are generated by my company, so I have some control over the PDF generation settings. Does anybody know what settings might improve load speed for image-based PDF files?
Thanks!
(By the way: I've been coding for 19 hours straight today, so if I rambled or didn't make sense, please forgive me! :) )
Upvotes: 3
Views: 5832
Reputation: 4281
Here are my 2 cents about easy and fast pdf rendering in swift.
Still WIP
Upvotes: 0
Reputation: 7641
You may wanna try to reduce image size. Large PDFs are really pushing the iPad/iPhone to its limits. Of course this means that you need to draw/manage the pdf yourself, with Quartz calls.
More speed is possible with proper caching. You can render pages off-screen, and display them without opening the actual pdf - which is much, much faster.
Upvotes: 2
Reputation: 1217
By using UIWebView to render the pdf, we will not get proper control over the pdf. like we cannot go to the desired page directly. and we cannot search a particular word and highlight.
its better to use CGPDF classes like CGPDFDocumentRef and CGPDFPageRef to handle the pdf documents properly.
Using these classes we have two options to handle the pdf's. 1. extracting the pdf pages as images individually and display using UIImageView. 2. extract the content of each page using CGPDFPageRef and create pdf for each page at runtime and display on to the webview.(better control control over pdf and neat display)
below is the sample code to extract individual page as an image.
-(UIImage *)getPage : (NSString*) filePath{
const char *myBuffer = (const char*)filePath; // PDF Path
CFStringRef urlString = (CFStringRef)myBuffer;
CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, urlString, 2, NO);
CGPDFDocumentRef myDocumentRef = CGPDFDocumentCreateWithURL(url);
CGPDFPageRef myPageRef = CGPDFDocumentGetPage(myDocumentRef, 1);
CGRect pdfcropBox = CGPDFPageGetBoxRect(myPageRef,kCGPDFCropBox); //kCGPDFCropBox
UIGraphicsBeginImageContext (pdfcropBox.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM (context,0,pdfcropBox.size.height);// [self pageRect].origin.x,[self pageRect].origin.y+[self pageRect].size.height); //320);
// scale 1:1 100%
CGContextScaleCTM (context, 1.0, -1.0);
CGContextSaveGState (context);
CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(myPageRef, kCGPDFCropBox, CGRectMake(0, 0, pdfcropBox.size.width,pdfcropBox.size.height), 0, true); //
CGContextConcatCTM (context, pdfTransform);
CGContextDrawPDFPage (context, myPageRef);
CGContextRestoreGState (context);
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext ();
CGPDFDocumentRelease (myDocumentRef);
//CGPDFPageRelease(myPageRef);
//myPageRef = nil;
myDocumentRef = nil;
urlString = nil;
url = nil;
return resultingImage;
}
Upvotes: 1
Reputation: 481
The fastest solution will be to write your own custom pdf parser and rendering framework using the CGPDFDocument classes. The secret to superfast pdf rendering is using techniques like:
I used all of the above mentioned techniques in PDFTouch SDK for iOS which is a fast pdf rendering framework developed by me!
Upvotes: 6
Reputation: 11
if you get desperate you could re-process the pdf files on your server to turn them into simple image files (associated with the original pdf files) then load those. that way no "pdf" parsing needs to take place. and then you can host on the server or include as part of the app if the volume is low.
basically you'd need a server script that does all the re-processing and sticks the new files into a special folder. maybe you make a database to reference the new files. or maybe you create a directory name for each new file that mirrors the original pdf file name.
Upvotes: 1