Taskinul Haque
Taskinul Haque

Reputation: 724

iOS Lag While Loading PDFs

So My Application uses, a lot of PDF's These sheet take a long time to load, (10 seconds + on iPad 2, iOS 7) So i figured if I could get the Load the separate sheets into the File directory, at ApplicationDidFinishLaunching() - I could then refers to the files in the user directory and they would load faster - but it made absolutely no difference

Below is my DrawRect() method responsible for displaying the PDF

CGContextRef ctx = UIGraphicsGetCurrentContext();
//PDF might be transparent, assume white paper - set White Background
[[UIColor whiteColor] set];
CGContextFillRect(ctx, rect);

//PDF File Path
//"pdf" refers to the location in the directory where the file is saved"
CGPDFPageRef page1 = CGPDFDocumentGetPage(pdf, 1);

//Flip coordinates
CGContextGetCTM(ctx);
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -rect.size.height);

//Get the rectangle of the cropped inside
CGRect mediaRect = CGPDFPageGetBoxRect(page1, kCGPDFCropBox);

CGContextScaleCTM(ctx, rect.size.width / mediaRect.size.width,
                  rect.size.height / mediaRect.size.height);

//Draw PDF
CGContextDrawPDFPage(ctx, page1);
CGPDFDocumentRelease(pdf);

Location in the directory where the file is as was declared in the idInit() method

NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
    NSString *documentDirectory = [documentDirectories objectAtIndex:0];
    NSString *dataPath = [documentDirectory stringByAppendingPathComponent:
                          [NSString stringWithFormat:@"PDFSource"]];
    NSString *documentDirectoryFilename = [dataPath stringByAppendingPathComponent:
                                           [NSString stringWithFormat:@"BUEvenous.pdf"]];

    CFStringRef path = CFStringCreateWithCString (NULL, [documentDirectoryFilename UTF8String], kCFStringEncodingUTF8);
    CFURLRef url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, 0);
    CFRelease (path);
    pdf = CGPDFDocumentCreateWithURL(url);// 2
    CFRelease(url);

Your help guidance, suggestions, any points as to where I'm going wrong of how I could make this load faster is very much appreciated

EDIT

@DavidvanDriessche thank you for the suggestion, it turnes out that the PDF files I am using are actually quite large (about 1 MB), what I learnt from testing is that if i further compress the PDF files so they're =< 500kbs then i don't have an issue with loading time - but compressing the files, lead to loss of image quality on some of the embedded images within the PDF : also it could be the iPad 2 - I'll try running it on a newer device and add to this post

Any other suggestions ?

Task

Upvotes: 1

Views: 512

Answers (1)

EsbenB
EsbenB

Reputation: 3406

You could consider creating images from pdf pages instead, and do so in a background thread, via NSOperation or using dispatch_async

To create an image from a pdf page:

+(UIImage *)getPDFPage:(CGPDFPageRef) page rect:(CGRect) rect
{

    CGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);


    UIGraphicsBeginImageContext(pageRect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextTranslateCTM(context, 0.0, pageRect.size.height);

    CGContextScaleCTM(context, 1.0, -1.0);

    CGContextDrawPDFPage(context, page);

    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();
    return img;
}

EDIT:

This code will give you an image in a size decided by the PDF file (the pageRect in code above). Zoom level will therefore be decided by the media available. Take a look at the different values for CGPDFPageGetBoxRect here.

Keep in mind that the images might take up a lot of memory. You could save the images to disk using:

NSData *imageData = UIImagePNGRepresentation(pdfImage);

And then load the relevant page when needed. Loading an image from the iUnit disk is pretty fast.

Upvotes: 2

Related Questions