#iOS PDF programming is still not that difficult. Now we dive into #PDF itself ;)
In the last post I described how to "draw" on iOS, which served me well in getting me started on iOS PDF programming.
As with "drawing", writing PDF isn't that complicated if you sit down and decipher it. And Apple's print tutorial for iOS does a good job explaining it. But sadly, the tutorial has a bug in this call. The tutorial wrongly writes:
currentRange = [self renderPageWithTextRange:currentRange andFramesetter:framesetter];
instead of the correct:
currentRange = [self renderPage:currentPage withTextRange:currentRange andFramesetter:framesetter];
So I got this part running pretty well with the following code:
- (IBAction)savePDFFile:(id)sender
{
NSString* path = [[NSBundle mainBundle] pathForResource:@"sampleData" ofType:@"plist"];
// get a temprorary filename for this PDF
path = NSTemporaryDirectory();
self.pdfFilePath = [path stringByAppendingPathComponent:
[NSString stringWithFormat:@"%d.pdf",
[[NSDate date]
timeIntervalSince1970] ]];
// Prepare the text using a Core Text Framesetter
CFAttributedStringRef currentText = CFAttributedStringCreate(NULL,
(CFStringRef)textView.text, NULL);
if (currentText) {
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);
if (framesetter) {
NSString* pdfFileName = self.pdfFilePath; //[NSString stringWithString:@"test.pdf"];
// Create the PDF context using the default page: currently constants at the size
// of 612 x 792.
UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil);
CFRange currentRange = CFRangeMake(0, 0);
NSInteger currentPage = 0;
BOOL done = NO;
do {
// Mark the beginning of a new page.
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, kDefaultPageWidth,
kDefaultPageHeight), nil);
// Draw a page number at the bottom of each page
currentPage++;
[self drawPageNumber:currentPage];
// Render the current page and update the current range to
// point to the beginning of the next page.
currentRange = [self renderPage:currentPage withTextRange:
currentRange andFramesetter:framesetter];
// If we're at the end of the text, exit the loop.
if (currentRange.location == CFAttributedStringGetLength
((CFAttributedStringRef)currentText))
done = YES;
} while (!done);
// Close the PDF context and write the contents out.
UIGraphicsEndPDFContext();
// Release the framewetter.
CFRelease(framesetter);
} else {
NSLog(@"Could not create the framesetter needed to lay out the atrributed string.");
}
// Release the attributed string.
CFRelease(currentText);
} else {
NSLog(@"Could not create the attributed string for the framesetter");
}
}
The problem was that I couldn't verify if the PDF was written to the iPhone or not. In the next post I will describe how I combined it with code from Spitzkoff.