For a recent project, we had to split a PDF document with any number of pages into single PDF files that contained exactly one page of the source file each. The splitting had to be done by the app itself, and the text in the resulting documents had to be select- and copyable.
The function I created to that purpose takes a NSURL pointing to the source file, the base name for the generated output-files and a directory (which is relative to the application’s Documents folder) where the output-files are being saved.
So without further ado, here’s what I came up with:
-(void)splitPDF:(NSURL *)sourcePDFUrl withOutputName:(NSString *)outputBaseName intoDirectory:(NSString *)directory
{
// Reference to the Document
CGPDFDocumentRef SourcePDFDocument = CGPDFDocumentCreateWithURL((__bridge CFURLRef)sourcePDFUrl);
// Get the number of pages in the Document
size_t numberOfPages = CGPDFDocumentGetNumberOfPages(SourcePDFDocument);
// Check the directory and create if not existent
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePathAndDirectory = [documentsDirectory stringByAppendingPathComponent:directory];
NSError *error;
if (![[NSFileManager defaultManager] createDirectoryAtPath:filePathAndDirectory
withIntermediateDirectories:NO
attributes:nil
error:&error])
{
NSLog(@"Create directory error: %@", error);
}
// PDFPageReferences start to count the page numbers from 1 rather than 0
for(int currentPage = 1; currentPage <= numberOfPages; currentPage ++ )
{
// Iterate over all PDF-Pages in the Source-Document
// Reference to Page current Page
CGPDFPageRef SourcePDFPage = CGPDFDocumentGetPage(SourcePDFDocument, currentPage);
// CoreGraphics: MUST retain the Page-Refernce manually
CGPDFPageRetain(SourcePDFPage);
// Build Path for the Output-File based on the directory, outputBaseName and current Page
NSString *relativeOutputFilePath = [NSString stringWithFormat:@"%@/%@%d.pdf", directory, outputBaseName, currentPage];
NSString *pdfFileName = [documentsDirectory stringByAppendingPathComponent:relativeOutputFilePath];
// Get the Size of the Page in the Source-PDF
CGRect sourceRect = CGPDFPageGetBoxRect(SourcePDFPage, kCGPDFMediaBox);
// Start PDF-Context for the File --> if not existent, the file will be created
UIGraphicsBeginPDFContextToFile(pdfFileName, sourceRect, nil);
// Start a ne PDF-Page --> MUST be done!!!
UIGraphicsBeginPDFPage();
// Get the current Context
CGContextRef context = UIGraphicsGetCurrentContext();
// Flip the context so that the PDF page is rendered right side up.
CGContextTranslateCTM(context, 0.0, sourceRect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// Draw the PDF Page into the new Page
CGContextDrawPDFPage(context, SourcePDFPage);
// Close the PDF-Context which also writes the PDF to disk
UIGraphicsEndPDFContext();
// Manually release the Source PDFPage Referene
CGPDFPageRelease(SourcePDFPage);
}
}
Markus is a technical mastermind and one of the founders of Innovaptor. He studied Computer Engineering at Vienna University of Technology and contributes a valuable diversification to Innovaptor's qualifications. Markus is eager to find innovative solutions to complex problems in order to provide products that are tailored directly to the customers' needs