HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

What can I improve on my iOS PDF class?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
canwhatiosimproveclasspdf

Problem

This is the first PDF class I have made for the iOS using code from Apple's samples. There could easily be stuff here wrong that I am missing.

I intend this to get images out of for a layer, for example:

image.contents = (id)[self.test imageForPage: 3 size: CGSizeMake(4*dpc, 2*dpc)].CGImage;


Here is this hopefully decent code. Any suggestions are welcome.

```
@interface PDFDocument : NSObject {
CGPDFDocumentRef pdfFile;
}

  • (id) initWithURL: (NSURL*) url;
  • (UIImage*) imageForPage: (size_t) pageno size: (CGSize) size;
  • (CGSize) sizeOfPage: (size_t) pageno;



@end

@implementation PDFDocument

  • (id) initWithURL: (NSURL*) url {


if ([super init])
{
// Open PDF
CGPDFDocumentRef doc = CGPDFDocumentCreateWithURL((CFURLRef)url);

if (doc == NULL)
@throw @"PDF File does not exist.";

pdfFile = doc;

}
return self;
}

  • (UIImage*) imageForPage: (size_t) pageno size: (CGSize) size {


if (pdfFile) {
// Get First Page
CGPDFPageRef page = CGPDFDocumentGetPage(pdfFile, pageno);

if (page == NULL)
@throw @"Page does not exist.";

// Get Page Size
CGRect cropBox = CGPDFPageGetBoxRect(page, kCGPDFCropBox);

// Start Drawing Context to Render PDF
UIGraphicsBeginImageContext(size);

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);

CGRect u = { {0, 0}, size};

CGContextFillRect(context, u);
CGContextSetAllowsAntialiasing(context, NO);

CGContextSaveGState(context);

// Scale PDF
CGContextScaleCTM(context, size.width / cropBox.size.width, size.height / cropBox.size.height);

// Flip Context to render PDF correctly
CGContextTranslateCTM(context, 0.0, cropBox.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);

Solution

One immediate change I'd make is how you're handling errors. While try-catch blocks are extremely common in other programming languages, I actually don't see them all that very often in Objective-C.

That doesn't mean we won't have errors. It just means error handling is typically handled differently in my experience with Objective-C. Just take a look at some of the Foundation methods as example:

stringWithContentsOfFile:encoding:error:


You can send nil as the argument for the error, but otherwise, you send the method an NSError object, and when the method returns, if there was an error, you can check the object to find out what it was. In the case of an init method, if an error occurred, you'd also want to return nil as well as loading the error description in the passed error object.

For completeness, it seems like it might be a good idea to create a corresponding PDFPage class. And instead of imageForPage:size: being called over and over to create pages, the end user would create instances of PDFPage. The PDFDocument in turn isn't much more than an array of PDFPages with some logic for adding a single page, array of pages, remove pages, from front, back, specific index, etc.

Code Snippets

stringWithContentsOfFile:encoding:error:

Context

StackExchange Code Review Q#2722, answer score: 7

Revisions (0)

No revisions yet.